Merge remote-tracking branch 'upstream/master' into feature/ich2

This commit is contained in:
Jasmine Iwanek
2023-07-16 13:36:20 -04:00
77 changed files with 10283 additions and 1890 deletions

View File

@@ -288,7 +288,6 @@ then
echo [-] Using MSYSTEM [$MSYSTEM]
# Install dependencies only if we're in a new build and/or architecture.
freetype_dll="$cache_dir/freetype.$MSYSTEM.dll"
if check_buildtag "$MSYSTEM"
then
# Update databases and keyring only if we're in a new build.
@@ -333,9 +332,6 @@ then
# Clean pacman cache when running under Jenkins to save disk space.
[ "$CI" = "true" ] && rm -rf /var/cache/pacman/pkg
# Generate a new freetype DLL for this architecture.
rm -f "$freetype_dll"
# Save build tag to skip this later. Doing it here (once everything is
# in place) is important to avoid potential issues with retried builds.
save_buildtag "$MSYSTEM"
@@ -796,10 +792,6 @@ then
sevenzip="$pf/7-Zip/7z.exe"
[ "$arch" = "32" -a -d "/c/Program Files (x86)" ] && pf="/c/Program Files (x86)"
# Archive freetype from cache or generate it from local MSYS installation.
[ ! -e "$freetype_dll" ] && .ci/static2dll.sh -p freetype2 /$MSYSTEM/lib/libfreetype.a "$freetype_dll"
cp -p "$freetype_dll" archive_tmp/freetype.dll
# Archive Ghostscript DLL from local official distribution installation.
for gs in "$pf"/gs/gs*.*.*
do
@@ -1003,6 +995,11 @@ else
ln -s "$relroot/usr/lib/libvulkan.so.1" "archive_tmp/usr/lib/libvulkan.so"
ln -s "$relroot/usr/lib/$libdir/libvulkan.so.1" "archive_tmp/usr/lib/$libdir/libvulkan.so"
# The FluidSynth packaged by Debian bullseye is ABI incompatible with
# the newer version we compile, despite sharing a major version. Since we
# don't run into the one breaking ABI change they made, just symlink it.
ln -s "$(readlink "archive_tmp/usr/lib/libfluidsynth.so.3")" "archive_tmp/usr/lib/libfluidsynth.so.2"
# Archive Discord Game SDK library.
7z e -y -o"archive_tmp/usr/lib" "$discord_zip" "lib/$arch_discord/discord_game_sdk.so"
[ ! -e "archive_tmp/usr/lib/discord_game_sdk.so" ] && echo [!] No Discord Game SDK for architecture [$arch_discord]

View File

@@ -1,160 +0,0 @@
#!/bin/sh
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running 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.
#
# Script for converting MinGW static libraries into a DLL.
#
#
# Authors: RichardG, <richardg867@gmail.com>
#
# Copyright 2021 RichardG.
#
def_file="static2dll.def"
seen_file="static2dll.seen"
libs_file="static2dll.libs"
find_lib() {
# Try to find a static library's file.
local msystem_lib="/$(echo $MSYSTEM | tr '[:upper:]' '[:lower:]')/lib/lib"
if [ -e "$msystem_lib$1.a" ]
then
echo "$msystem_lib$1.a"
elif [ -e "$msystem_lib$1.dll.a" ]
then
echo "$msystem_lib$1.dll.a"
else
# Return dynamic reference to the library.
echo "-l$1"
return 1
fi
}
add_lib() {
# Always make sure this lib is listed after the last lib that depends on it.
old_libs=$(cat "$libs_file")
rm -f "$libs_file"
for lib in $old_libs
do
[ "$lib" != "$*" ] && echo "$lib" >> "$libs_file"
done
echo "$*" >> "$libs_file"
# Add libstdc++ in the end if required.
if echo "$*" | grep -q "/"
then
grep -Eq -- "__cxa_|__gxx_" "$1" 2> /dev/null && add_lib -static -lstdc++
fi
# Add libiconv for libintl.
if echo "$*" | grep -q "libintl"
then
add_lib $(find_lib iconv)
fi
# Add libuuid for glib.
if echo "$*" | grep -q "libglib"
then
add_lib $(find_lib uuid)
fi
}
run_pkgconfig() {
local cache_file="static2dll.$1.cache"
if [ -e "$cache_file" ]
then
cat "$cache_file"
else
pkg-config --static --libs "$1" 2> /dev/null | tee "$cache_file"
fi
}
parse_pkgconfig() {
# Parse arguments.
local layers=$1
shift
local input_lib_name=$1
shift
# Don't process the same file again.
grep -q '^'$input_lib_name'$' "$seen_file" && return
echo $input_lib_name >> "$seen_file"
echo "$layers" parse_pkgconfig $input_lib_name
# Parse pkg-config arguments.
for arg in $*
do
local arg_base="$(echo $arg | cut -c1-2)"
if [ "x$arg_base" = "x-l" ]
then
# Don't process the same lib again.
local lib_name="$(echo $arg | cut -c3-)"
[ "x$lib_name" == "x$input_lib_name" ] && continue
# Add lib path.
add_lib "$(find_lib $lib_name)"
# Get this lib's dependencies through pkg-config.
local pkgconfig="$(run_pkgconfig "$lib_name")"
[ $? -eq 0 ] && parse_pkgconfig "$layers"'>' "$lib_name" $pkgconfig || echo $lib_name >> "$seen_file"
elif [ "x$(echo $arg_base | cut -c1)" = "x-" ]
then
# Ignore other arguments.
continue
else
# Add lib path.
add_lib "$arg"
fi
done
}
# Parse arguments.
case $1 in
-p) # -p pkg_config_name static_lib_path out_dll
shift
base_pkgconfig=$(run_pkgconfig "$1")
base_path="$2"
base_name="$1"
;;
*) # pc_path static_lib_path out_dll
base_pkgconfig="$(grep ^Libs.private: $1 | cut -d: -f2-)"
base_path="$2"
base_name="$2"
;;
esac
# Check arguments.
if [ -z "$base_pkgconfig" -o -z "$base_path" -o -z "$base_name" ]
then
echo Usage:
echo static2dll.sh -p {pkgconfig_package_name} {static_lib_path} {out_dll_name}
echo static2dll.sh {pc_file_path} {static_lib_path} {out_dll_name}
exit 1
fi
# Produce .def file.
echo LIBRARY $(basename "$3") > "$def_file"
echo EXPORTS >> "$def_file"
nm "$base_path" | grep " [TC] " | sed "/ _/s// /" | awk '{ print $3 }' >> "$def_file"
# Parse dependencies recursively.
rm -f "$seen_file" "$libs_file" "$libs_file.tmp"
touch "$seen_file" "$libs_file"
parse_pkgconfig '>' $base_name $base_pkgconfig
# Produce final DLL.
dllwrap --def "$def_file" -o "$3" -Wl,--allow-multiple-definition "$base_path" $(cat "$libs_file")
status=$?
[ $status -eq 0 ] && rm -f "$def_file" "$seen_file" "$libs_file" "static2dll.*.cache"
# Update final DLL timestamp.
touch -r "$base_path" "$3"
exit $status

View File

@@ -90,6 +90,8 @@ jobs:
libpng:p
openal:p
rtmidi:p
libslirp:p
fluidsynth:p
libvncserver:p
- name: Checkout repository

View File

@@ -105,6 +105,7 @@ jobs:
openal:p
rtmidi:p
libslirp:p
fluidsynth:p
libvncserver:p
${{ matrix.ui.packages }}
@@ -329,8 +330,9 @@ jobs:
libc6-dev
librtmidi-dev
libopenal-dev
libvncserver-dev
libslirp-dev
libfluidsynth-dev
libvncserver-dev
${{ matrix.ui.packages }}
- name: Checkout repository
@@ -415,6 +417,7 @@ jobs:
libpng
rtmidi
openal-soft
fluidsynth
libvncserver
${{ matrix.ui.packages }}

View File

@@ -108,6 +108,7 @@ jobs:
openal:p
rtmidi:p
libslirp:p
fluidsynth:p
libvncserver:p
${{ matrix.ui.packages }}
@@ -193,6 +194,7 @@ jobs:
librtmidi-dev
libopenal-dev
libslirp-dev
libfluidsynth-dev
libvncserver-dev
${{ matrix.ui.packages }}
@@ -268,6 +270,7 @@ jobs:
libpng
rtmidi
openal-soft
fluidsynth
libvncserver
${{ matrix.ui.packages }}

View File

@@ -41,6 +41,9 @@
#include <86box/machine.h>
#include <86box/chipset.h>
#include <86box/spd.h>
#ifndef USE_DRB_HACK
#include <86box/row.h>
#endif
#define MEM_STATE_SHADOW_R 0x01
#define MEM_STATE_SHADOW_W 0x02
@@ -158,6 +161,26 @@ i420ex_smram_handler_phase1(i420ex_t *dev)
(regs[0x70] & 0x70) == 0x40, !(regs[0x70] & 0x20));
}
#ifndef USE_DRB_HACK
static void
i420ex_drb_recalc(i420ex_t *dev)
{
int i;
uint32_t boundary;
for (i = 4; i >= 0; i--)
row_disable(i);
for (i = 0; i <= 4; i++) {
boundary = ((uint32_t) dev->regs[0x60 + i]) & 0xff;
row_set_boundary(i, boundary);
}
flushmmucache();
}
#endif
static void
i420ex_write(int func, int addr, uint8_t val, void *priv)
{
@@ -289,7 +312,12 @@ i420ex_write(int func, int addr, uint8_t val, void *priv)
case 0x62:
case 0x63:
case 0x64:
#ifdef USE_DRB_HACK
spd_write_drbs(dev->regs, 0x60, 0x64, 1);
#else
dev->regs[addr] = val;
i420ex_drb_recalc(dev);
#endif
break;
case 0x66:
case 0x67:
@@ -452,7 +480,7 @@ i420ex_reset(void *priv)
i420ex_write(0, 0x59 + i, 0x00, priv);
for (uint8_t i = 0; i <= 4; i++)
i420ex_write(0, 0x60 + i, 0x01, priv);
dev->regs[0x60 + i] = 0x01;
dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */
dev->smram_locked = 0;
@@ -530,6 +558,11 @@ i420ex_init(const device_t *info)
device_add(&ide_pci_2ch_device);
#ifndef USE_DRB_HACK
row_device.local = 4 | (1 << 8) | (0x01 << 16) | (8 << 24);
device_add((const device_t *) &row_device);
#endif
i420ex_reset_hard(dev);
return dev;

View File

@@ -1537,7 +1537,12 @@ i4x0_reset(void *priv)
i4x0_write(0, 0x5a + i, 0x00, priv);
for (uint8_t i = 0; i <= dev->max_drb; i++)
i4x0_write(0, 0x60 + i, dev->drb_default, priv);
dev->regs[0x60 + i] = dev->drb_default;
if (dev->type >= INTEL_430NX) {
for (uint8_t i = 0; i < 4; i++)
dev->regs[0x68 + i] = 0x00;
}
if (dev->type >= INTEL_430FX) {
dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */
@@ -1621,7 +1626,7 @@ i4x0_init(const device_t *info)
regs[0x59] = 0x0f;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = 0x02;
dev->max_drb = 3;
dev->drb_unit = 4;
dev->drb_unit = 1;
dev->drb_default = 0x02;
break;
case INTEL_430LX:

View File

@@ -326,13 +326,6 @@ pb_write(int func, int addr, uint8_t val, void *priv)
dev->pb_pci_conf[addr] = val & /*0x1a*/ 0x1f;
break;
case 0xb4:
dev->pb_pci_conf[addr] = val & 0xe0;
break;
case 0xb5:
dev->pb_pci_conf[addr] = val & 0x1f;
break;
case 0xb8:
case 0xb9:
dev->pb_pci_conf[addr] = val;
@@ -689,7 +682,7 @@ i450kx_reset(void *priv)
dev->pb_pci_conf[0xb0] = 0x00;
dev->pb_pci_conf[0xb1] = 0x00;
#endif
dev->pb_pci_conf[0xb4] = 0x00;
dev->pb_pci_conf[0xb4] = 0xff;
dev->pb_pci_conf[0xb5] = 0x00;
dev->pb_pci_conf[0xb8] = 0x05;
dev->pb_pci_conf[0xb9] = 0x00;

View File

@@ -38,10 +38,17 @@
#include <86box/machine.h>
#include <86box/chipset.h>
#include <86box/spd.h>
#ifndef USE_DRB_HACK
#include <86box/row.h>
#endif
typedef struct sis_85c496_t {
uint8_t cur_reg;
uint8_t rmsmiblk_count;
#ifndef USE_DRB_HACK
uint8_t drb_default;
uint8_t drb_bits;
#endif
uint8_t regs[127];
uint8_t pci_conf[256];
smram_t *smram;
@@ -184,6 +191,26 @@ sis_85c496_ide_handler(sis_85c496_t *dev)
}
}
#ifndef USE_DRB_HACK
static void
sis_85c496_drb_recalc(sis_85c496_t *dev)
{
int i;
uint32_t boundary;
for (i = 7; i >= 0; i--)
row_disable(i);
for (i = 0; i <= 7; i++) {
boundary = ((uint32_t) dev->pci_conf[0x48 + i]);
row_set_boundary(i, boundary);
}
flushmmucache();
}
#endif
/* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */
static void
sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
@@ -259,10 +286,12 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
case 0x4d:
case 0x4e:
case 0x4f:
#if 0
dev->pci_conf[addr] = val;
#endif
#ifdef USE_DRB_HACK
spd_write_drbs(dev->pci_conf, 0x48, 0x4f, 1);
#else
dev->pci_conf[addr] = val;
sis_85c496_drb_recalc(dev);
#endif
break;
case 0x50:
case 0x51: /* Exclusive Area 0 Setup */
@@ -552,7 +581,7 @@ sis_85c496_reset(void *priv)
// sis_85c49x_pci_write(0, 0x5a, 0x06, dev);
for (uint8_t i = 0; i < 8; i++)
sis_85c49x_pci_write(0, 0x48 + i, 0x00, dev);
dev->pci_conf[0x48 + i] = 0x02;
sis_85c49x_pci_write(0, 0x80, 0x00, dev);
sis_85c49x_pci_write(0, 0x81, 0x00, dev);
@@ -643,6 +672,11 @@ static void
timer_add(&dev->rmsmiblk_timer, sis_85c496_rmsmiblk_count, dev, 0);
#ifndef USE_DRB_HACK
row_device.local = 7 | (1 << 8) | (0x02 << 16) | (7 << 24);
device_add((const device_t *) &row_device);
#endif
sis_85c496_reset(dev);
return dev;

View File

@@ -128,6 +128,54 @@ RecompOpFn recomp_opcodes_0f[512] = {
// clang-format on
};
RecompOpFn recomp_opcodes_0f_no_mmx[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,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ ropJO_w, ropJNO_w, ropJB_w, ropJNB_w, ropJE_w, ropJNE_w, ropJBE_w, ropJNBE_w, ropJS_w, ropJNS_w, ropJP_w, ropJNP_w, ropJL_w, ropJNL_w, ropJLE_w, ropJNLE_w,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_w_b, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_w_b, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*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,
/*32-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,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ ropJO_l, ropJNO_l, ropJB_l, ropJNB_l, ropJE_l, ropJNE_l, ropJBE_l, ropJNBE_l, ropJS_l, ropJNS_l, ropJP_l, ropJNP_l, ropJL_l, ropJNL_l, ropJLE_l, ropJNLE_l,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_l_b, ropMOVZX_l_w, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_l_b, ropMOVSX_l_w,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*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_d8[512] = {
// clang-format off
/*16-bit data*/

View File

@@ -7,6 +7,7 @@ typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
extern RecompOpFn recomp_opcodes[512];
extern RecompOpFn recomp_opcodes_0f[512];
extern RecompOpFn recomp_opcodes_0f_no_mmx[512];
extern RecompOpFn recomp_opcodes_d8[512];
extern RecompOpFn recomp_opcodes_d9[512];
extern RecompOpFn recomp_opcodes_da[512];

View File

@@ -845,7 +845,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
switch (opcode) {
case 0x0f:
op_table = x86_dynarec_opcodes_0f;
recomp_op_table = recomp_opcodes_0f;
recomp_op_table = fpu_softfloat ? recomp_opcodes_0f_no_mmx : recomp_opcodes_0f;
over = 1;
break;

View File

@@ -1884,7 +1884,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
switch (opcode) {
case 0x0f:
op_table = x86_dynarec_opcodes_0f;
recomp_op_table = recomp_opcodes_0f;
recomp_op_table = fpu_softfloat ? recomp_opcodes_0f_no_mmx : recomp_opcodes_0f;
over = 1;
break;

View File

@@ -399,7 +399,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
last_prefix = 0x0f;
#endif
op_table = x86_dynarec_opcodes_0f;
recomp_op_table = recomp_opcodes_0f;
recomp_op_table = fpu_softfloat ? recomp_opcodes_0f_no_mmx : recomp_opcodes_0f;
over = 1;
break;
@@ -634,11 +634,11 @@ generate_call:
}
opcode_3dnow = fastreadb(cs + opcode_pc);
if (recomp_opcodes_3DNOW[opcode_3dnow]) {
if (!fpu_softfloat && recomp_opcodes_3DNOW[opcode_3dnow]) {
next_pc = opcode_pc + 1;
op_table = (OpFn *) x86_dynarec_opcodes_3DNOW;
recomp_op_table = recomp_opcodes_3DNOW;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_3DNOW;
opcode = opcode_3dnow;
recomp_opcode_mask = 0xff;
opcode_mask = 0xff;

View File

@@ -144,6 +144,54 @@ RecompOpFn recomp_opcodes_0f[512] = {
// clang-format on
};
RecompOpFn recomp_opcodes_0f_no_mmx[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,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, ropSHLD_16_imm, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, ropSHRD_16_imm, NULL, NULL, NULL,
/*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*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,
/*32-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,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, ropSHLD_32_imm, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, ropSHRD_32_imm, NULL, NULL, NULL,
/*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*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_3DNOW[256] = {
// clang-format off
#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64

View File

@@ -9,6 +9,7 @@ typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t
extern RecompOpFn recomp_opcodes[512];
extern RecompOpFn recomp_opcodes_0f[512];
extern RecompOpFn recomp_opcodes_0f_no_mmx[512];
extern RecompOpFn recomp_opcodes_3DNOW[256];
extern RecompOpFn recomp_opcodes_d8[512];
extern RecompOpFn recomp_opcodes_d9[512];

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box distribution.
#
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
#
# Copyright 2020-2021 David Hrdlička.
#
add_library(808x OBJECT queue.c)

190
src/cpu/808x/queue.c Normal file
View File

@@ -0,0 +1,190 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running 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.
*
* 808x CPU emulation, mostly ported from reenigne's XTCE, which
* is cycle-accurate.
*
* Authors: gloriouscow, <https://github.com/dbalsom>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2023 gloriouscow.
* Copyright 2023 Miran Grca.
*/
#include <math.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include "x86.h"
#include <86box/machine.h>
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/nmi.h>
#include <86box/pic.h>
#include <86box/ppi.h>
#include <86box/timer.h>
#include <86box/gdbstub.h>
// #include "808x.h"
#include "queue.h"
/* TODO: Move to cpu.h so this can eventually be reused for 286+ as well. */
#define QUEUE_MAX 6
typedef struct queue_t
{
size_t size;
size_t len;
size_t back;
size_t front;
uint8_t q[QUEUE_MAX];
uint16_t preload;
queue_delay_t delay;
} queue_t;
static queue_t queue;
#ifdef ENABLE_QUEUE_LOG
int queue_do_log = ENABLE_QUEUE_LOG;
static void
queue_log(const char *fmt, ...)
{
va_list ap;
if (queue_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define queue_log(fmt, ...)
#endif
void
queue_set_size(size_t size)
{
if (size > QUEUE_MAX)
fatal("Requested prefetch queue of %i bytes is too big\n", size);
queue.size = size;
}
size_t
queue_get_len(void)
{
return queue.len;
}
int
queue_is_full(void)
{
return (queue.len != queue.size);
}
uint16_t
queue_get_preload(void)
{
uint16_t ret = queue.preload;
queue.preload = 0x0000;
return ret;
}
int
queue_has_preload(void)
{
return (queue.preload & FLAG_PRELOADED) ? 1 : 0;
}
void
queue_set_preload(void)
{
uint8_t byte;
if (queue.len > 0) {
byte = queue_pop();
queue.preload = ((uint16_t) byte) | FLAG_PRELOADED;
} else
fatal("Tried to preload with empty queue\n");
}
void
queue_push8(uint8_t byte)
{
if (queue.len < queue.size) {
queue.q[queue.front] = byte;
queue.front = (queue.front + 1) % queue.size;
queue.len++;
if (queue.len == 3)
queue.delay = DELAY_WRITE;
else
queue.delay = DELAY_NONE;
} else
fatal("Queue overrun\n");
}
void
queue_push16(uint16_t word)
{
queue_push8((uint8_t) (word & 0xff));
queue_push8((uint8_t) ((word >> 8) & 0xff));
}
uint8_t
queue_pop(void)
{
uint8_t byte = 0xff;
if (queue.len > 0) {
byte = queue.q[queue.back];
queue.back = (queue.back + 1) % queue.size;
queue.len--;
if (queue.len >= 3)
queue.delay = DELAY_READ;
else
queue.delay = DELAY_NONE;
} else
fatal("Queue underrun\n");
return byte;
}
queue_delay_t
queue_get_delay(void)
{
return queue.delay;
}
void
queue_flush(void)
{
memset(&queue, 0x00, sizeof(queue_t));
queue.delay = DELAY_NONE;
}
void
queue_init(void)
{
queue_flush();
if (is8086)
queue_set_size(6);
else
queue_set_size(4);
}

43
src/cpu/808x/queue.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running 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.
*
* Prefetch queue implementation header.
*
* Authors: gloriouscow, <https://github.com/dbalsom>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2023 gloriouscow.
* Copyright 2023 Miran Grca.
*/
#ifndef EMU_QUEUE_H
#define EMU_QUEUE_H
typedef enum queue_delay_t
{
DELAY_READ,
DELAY_WRITE,
DELAY_NONE
} queue_delay_t;
#define FLAG_PRELOADED 0x8000
extern void queue_set_size(size_t size);
extern size_t queue_get_len(void);
extern int queue_is_full(void);
extern uint16_t queue_get_preload(void);
extern int queue_has_preload(void);
extern void queue_set_preload(void);
extern void queue_push8(uint8_t byte);
extern void queue_push16(uint16_t word);
extern uint8_t queue_pop(void);
extern queue_delay_t queue_get_delay(void);
extern void queue_flush(void);
extern void queue_init(void);
#endif /*EMU_QUEUE_H*/

View File

@@ -14,7 +14,7 @@
#
add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c
386_dynarec.c x86seg.c x87.c x87_timings.c 8080.c)
386_dynarec.c x86_ops_mmx.c x86seg.c x87.c x87_timings.c 8080.c)
if(AMD_K5)
target_compile_definitions(cpu PRIVATE USE_AMD_K5)
@@ -35,3 +35,6 @@ endif()
add_subdirectory(softfloat)
target_link_libraries(86Box softfloat)
add_subdirectory(808x)
target_link_libraries(86Box 808x)

View File

@@ -1646,6 +1646,7 @@ cpu_set(void)
cpu_exec = exec386;
else
cpu_exec = execx86;
mmx_init();
gdbstub_cpu_init();
}

View File

@@ -856,4 +856,9 @@ extern void cpu_fast_off_reset(void);
extern void smi_raise(void);
extern void nmi_raise(void);
extern MMX_REG *MMP[8];
extern uint16_t *MMEP[8];
extern void mmx_init(void);
#endif /*EMU_CPU_H*/

View File

@@ -36,17 +36,20 @@ static int
opPAVGUSB(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1;
dst->b[0] = (dst->b[0] + src.b[0] + 1) >> 1;
dst->b[1] = (dst->b[1] + src.b[1] + 1) >> 1;
dst->b[2] = (dst->b[2] + src.b[2] + 1) >> 1;
dst->b[3] = (dst->b[3] + src.b[3] + 1) >> 1;
dst->b[4] = (dst->b[4] + src.b[4] + 1) >> 1;
dst->b[5] = (dst->b[5] + src.b[5] + 1) >> 1;
dst->b[6] = (dst->b[6] + src.b[6] + 1) >> 1;
dst->b[7] = (dst->b[7] + src.b[7] + 1) >> 1;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -54,11 +57,14 @@ static int
opPF2ID(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].sl[0] = (int32_t) src.f[0];
cpu_state.MM[cpu_reg].sl[1] = (int32_t) src.f[1];
dst->sl[0] = (int32_t) src.f[0];
dst->sl[1] = (int32_t) src.f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -66,11 +72,14 @@ static int
opPF2IW(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].sw[0] = (int32_t) src.f[0];
cpu_state.MM[cpu_reg].sw[1] = (int32_t) src.f[1];
dst->sw[0] = (int32_t) src.f[0];
dst->sw[1] = (int32_t) src.f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -78,13 +87,16 @@ static int
opPFACC(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
float tempf;
MMX_GETSRC();
tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1];
cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1];
cpu_state.MM[cpu_reg].f[0] = tempf;
tempf = dst->f[0] + dst->f[1];
dst->f[1] = src.f[0] + src.f[1];
dst->f[0] = tempf;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -92,13 +104,16 @@ static int
opPFNACC(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
float tempf;
MMX_GETSRC();
tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1];
cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1];
cpu_state.MM[cpu_reg].f[0] = tempf;
tempf = dst->f[0] - dst->f[1];
dst->f[1] = src.f[0] - src.f[1];
dst->f[0] = tempf;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -106,13 +121,16 @@ static int
opPFPNACC(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
float tempf;
MMX_GETSRC();
tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1];
cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1];
cpu_state.MM[cpu_reg].f[0] = tempf;
tempf = dst->f[0] - dst->f[1];
dst->f[1] = src.f[0] + src.f[1];
dst->f[0] = tempf;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -120,15 +138,18 @@ static int
opPSWAPD(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
float tempf, tempf2;
MMX_GETSRC();
/* We have to do this in case source and destination overlap. */
tempf = src.f[0];
tempf2 = src.f[1];
cpu_state.MM[cpu_reg].f[1] = tempf;
cpu_state.MM[cpu_reg].f[0] = tempf2;
tempf = src.f[0];
tempf2 = src.f[1];
dst->f[1] = tempf;
dst->f[0] = tempf2;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -136,11 +157,14 @@ static int
opPFADD(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] += src.f[0];
cpu_state.MM[cpu_reg].f[1] += src.f[1];
dst->f[0] += src.f[0];
dst->f[1] += src.f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -148,11 +172,14 @@ static int
opPFCMPEQ(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0;
dst->l[0] = (dst->f[0] == src.f[0]) ? 0xffffffff : 0;
dst->l[1] = (dst->f[1] == src.f[1]) ? 0xffffffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -160,11 +187,14 @@ static int
opPFCMPGE(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0;
dst->l[0] = (dst->f[0] >= src.f[0]) ? 0xffffffff : 0;
dst->l[1] = (dst->f[1] >= src.f[1]) ? 0xffffffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -172,11 +202,14 @@ static int
opPFCMPGT(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0;
dst->l[0] = (dst->f[0] > src.f[0]) ? 0xffffffff : 0;
dst->l[1] = (dst->f[1] > src.f[1]) ? 0xffffffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -184,13 +217,16 @@ static int
opPFMAX(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
if (src.f[0] > cpu_state.MM[cpu_reg].f[0])
cpu_state.MM[cpu_reg].f[0] = src.f[0];
if (src.f[1] > cpu_state.MM[cpu_reg].f[1])
cpu_state.MM[cpu_reg].f[1] = src.f[1];
if (src.f[0] > dst->f[0])
dst->f[0] = src.f[0];
if (src.f[1] > dst->f[1])
dst->f[1] = src.f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -198,13 +234,16 @@ static int
opPFMIN(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
if (src.f[0] < cpu_state.MM[cpu_reg].f[0])
cpu_state.MM[cpu_reg].f[0] = src.f[0];
if (src.f[1] < cpu_state.MM[cpu_reg].f[1])
cpu_state.MM[cpu_reg].f[1] = src.f[1];
if (src.f[0] < dst->f[0])
dst->f[0] = src.f[0];
if (src.f[1] < dst->f[1])
dst->f[1] = src.f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -212,24 +251,29 @@ static int
opPFMUL(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] *= src.f[0];
cpu_state.MM[cpu_reg].f[1] *= src.f[1];
dst->f[0] *= src.f[0];
dst->f[1] *= src.f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPFRCP(uint32_t fetchdat)
{
MMX_REG *dst = MMX_GETREGP(cpu_reg);
union {
uint32_t i;
float f;
} src;
if (cpu_mod == 3) {
src.f = cpu_state.MM[cpu_rm].f[0];
src.f = (MMX_GETREG(cpu_rm)).f[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_READ(cpu_state.ea_seg);
@@ -239,8 +283,10 @@ opPFRCP(uint32_t fetchdat)
CLOCK_CYCLES(2);
}
cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f;
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
dst->f[0] = 1.0 / src.f;
dst->f[1] = dst->f[0];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -249,11 +295,14 @@ static int
opPFRCPIT1(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] = src.f[0];
cpu_state.MM[cpu_reg].f[1] = src.f[1];
dst->f[0] = src.f[0];
dst->f[1] = src.f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -261,24 +310,29 @@ static int
opPFRCPIT2(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] = src.f[0];
cpu_state.MM[cpu_reg].f[1] = src.f[1];
dst->f[0] = src.f[0];
dst->f[1] = src.f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPFRSQRT(uint32_t fetchdat)
{
MMX_REG *dst = MMX_GETREGP(cpu_reg);
union {
uint32_t i;
float f;
} src;
if (cpu_mod == 3) {
src.f = cpu_state.MM[cpu_rm].f[0];
src.f = (MMX_GETREG(cpu_rm)).f[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_READ(cpu_state.ea_seg);
@@ -288,8 +342,10 @@ opPFRSQRT(uint32_t fetchdat)
CLOCK_CYCLES(2);
}
cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f);
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
dst->f[0] = 1.0 / sqrt(src.f);
dst->f[1] = dst->f[0];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -308,11 +364,14 @@ static int
opPFSUB(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] -= src.f[0];
cpu_state.MM[cpu_reg].f[1] -= src.f[1];
dst->f[0] -= src.f[0];
dst->f[1] -= src.f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -320,11 +379,14 @@ static int
opPFSUBR(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0];
cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1];
dst->f[0] = src.f[0] - dst->f[0];
dst->f[1] = src.f[1] - dst->f[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -332,11 +394,14 @@ static int
opPI2FD(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] = (float) src.sl[0];
cpu_state.MM[cpu_reg].f[1] = (float) src.sl[1];
dst->f[0] = (float) src.sl[0];
dst->f[1] = (float) src.sl[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -344,37 +409,46 @@ static int
opPI2FW(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].f[0] = (float) src.sw[0];
cpu_state.MM[cpu_reg].f[1] = (float) src.sw[1];
dst->f[0] = (float) src.sw[0];
dst->f[1] = (float) src.sw[1];
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPMULHRW(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].w[0] = (((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[1] = (((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[2] = (((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[3] = (((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16;
src = MMX_GETREG(cpu_rm);
dst->w[0] = (((int32_t) dst->sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16;
dst->w[1] = (((int32_t) dst->sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16;
dst->w[2] = (((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16;
dst->w[3] = (((int32_t) dst->sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16;
CLOCK_CYCLES(1);
} else {
MMX_REG src;
SEG_CHECK_READ(cpu_state.ea_seg);
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4);
if (cpu_state.abrt)
return 0;
cpu_state.MM[cpu_reg].w[0] = ((int32_t) (cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[1] = ((int32_t) (cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[2] = ((int32_t) (cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16;
cpu_state.MM[cpu_reg].w[3] = ((int32_t) (cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16;
dst->w[0] = ((int32_t) (dst->sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16;
dst->w[1] = ((int32_t) (dst->sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16;
dst->w[2] = ((int32_t) (dst->sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16;
dst->w[3] = ((int32_t) (dst->sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16;
CLOCK_CYCLES(2);
}
MMX_SETEXP(cpu_reg);
return 0;
}

View File

@@ -43,6 +43,132 @@ opSYSEXIT(uint32_t fetchdat)
return ret;
}
static int
sf_fx_save_stor_common(uint32_t fetchdat, int bits)
{
uint8_t fxinst = 0;
uint32_t tag_byte;
unsigned index;
floatx80 reg;
if (CPUID < 0x650)
return ILLEGAL(fetchdat);
FP_ENTER();
if (bits == 32) {
fetch_ea_32(fetchdat);
} else {
fetch_ea_16(fetchdat);
}
if (cpu_state.eaaddr & 0xf) {
x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr);
x86gpf(NULL, 0);
return cpu_state.abrt;
}
fxinst = (rmdat >> 3) & 7;
if ((fxinst > 1) || (cpu_mod == 3)) {
x86illegal();
return cpu_state.abrt;
}
FP_ENTER();
if (fxinst == 1) {
/* FXRSTOR */
fpu_state.cwd = readmemw(easeg, cpu_state.eaaddr);
fpu_state.swd = readmemw(easeg, cpu_state.eaaddr + 2);
fpu_state.tos = (fpu_state.swd >> 11) & 7;
/* always set bit 6 as '1 */
fpu_state.cwd = (fpu_state.cwd & ~FPU_CW_Reserved_Bits) | 0x0040;
/* Restore x87 FPU Opcode */
/* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */
fpu_state.foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF;
fpu_state.fip = readmeml(easeg, cpu_state.eaaddr + 8);
fpu_state.fcs = readmemw(easeg, cpu_state.eaaddr + 12);
tag_byte = readmemb(easeg, cpu_state.eaaddr + 4);
fpu_state.fdp = readmeml(easeg, cpu_state.eaaddr + 16);
fpu_state.fds = readmemw(easeg, cpu_state.eaaddr + 20);
/* load i387 register file */
for (index = 0; index < 8; index++) {
reg.fraction = readmemq(easeg, cpu_state.eaaddr + (index * 16) + 32);
reg.exp = readmemw(easeg, cpu_state.eaaddr + (index * 16) + 40);
// update tag only if it is not empty
FPU_save_regi_tag(reg, IS_TAG_EMPTY(index) ? X87_TAG_EMPTY : FPU_tagof(reg), index);
}
fpu_state.tag = unpack_FPU_TW(tag_byte);
/* check for unmasked exceptions */
if (fpu_state.swd & ~fpu_state.cwd & FPU_CW_Exceptions_Mask) {
/* set the B and ES bits in the status-word */
fpu_state.swd |= (FPU_SW_Summary | FPU_SW_Backward);
} else {
/* clear the B and ES bits in the status-word */
fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward);
}
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
} else {
/* FXSAVE */
writememw(easeg, cpu_state.eaaddr, i387_get_control_word());
writememw(easeg, cpu_state.eaaddr + 2, i387_get_status_word());
writememw(easeg, cpu_state.eaaddr + 4, pack_FPU_TW(fpu_state.tag));
/* x87 FPU Opcode (16 bits) */
/* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */
writememw(easeg, cpu_state.eaaddr + 6, fpu_state.foo);
/*
* x87 FPU IP Offset (32/64 bits)
* The contents of this field differ depending on the current
* addressing mode (16/32/64 bit) when the FXSAVE instruction was executed:
* + 64-bit mode - 64-bit IP offset
* + 32-bit mode - 32-bit IP offset
* + 16-bit mode - low 16 bits are IP offset; high 16 bits are reserved.
* x87 CS FPU IP Selector
* + 16 bit, in 16/32 bit mode only
*/
writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip);
writememl(easeg, cpu_state.eaaddr + 12, fpu_state.fcs);
/*
* x87 FPU Instruction Operand (Data) Pointer Offset (32/64 bits)
* The contents of this field differ depending on the current
* addressing mode (16/32 bit) when the FXSAVE instruction was executed:
* + 64-bit mode - 64-bit offset
* + 32-bit mode - 32-bit offset
* + 16-bit mode - low 16 bits are offset; high 16 bits are reserved.
* x87 DS FPU Instruction Operand (Data) Pointer Selector
* + 16 bit, in 16/32 bit mode only
*/
writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp);
writememl(easeg, cpu_state.eaaddr + 20, fpu_state.fds);
/* store i387 register file */
for (index = 0; index < 8; index++) {
const floatx80 fp = FPU_read_regi(index);
writememq(easeg, cpu_state.eaaddr + (index * 16) + 32, fp.fraction);
writememw(easeg, cpu_state.eaaddr + (index * 16) + 40, fp.exp);
}
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
}
return cpu_state.abrt;
}
static int
fx_save_stor_common(uint32_t fetchdat, int bits)
{
@@ -253,12 +379,18 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
static int
opFXSAVESTOR_a16(uint32_t fetchdat)
{
if (fpu_softfloat)
return sf_fx_save_stor_common(fetchdat, 16);
return fx_save_stor_common(fetchdat, 16);
}
static int
opFXSAVESTOR_a32(uint32_t fetchdat)
{
if (fpu_softfloat)
return sf_fx_save_stor_common(fetchdat, 32);
return fx_save_stor_common(fetchdat, 32);
}

50
src/cpu/x86_ops_mmx.c Normal file
View File

@@ -0,0 +1,50 @@
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <math.h>
#ifndef INFINITY
# define INFINITY (__builtin_inff())
#endif
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include "x86.h"
#include "x87.h"
#include <86box/nmi.h>
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/keyboard.h>
#include <86box/timer.h>
#include "386_common.h"
#include "x86_flags.h"
#include "x86seg.h"
MMX_REG *MMP[8];
uint16_t *MMEP[8];
static uint16_t MME[8];
#define MMX_GETREGP(r) fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[r].fraction) : &(cpu_state.MM[r])
void
mmx_init(void)
{
memset(MME, 0xff, sizeof(MME));
for (uint8_t i = 0; i < 8; i++) {
if (fpu_softfloat) {
MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction;
MMEP[i] = (uint16_t *) &fpu_state.st_space[i].exp;
} else {
MMP[i] = &(cpu_state.MM[i]);
MMEP[i] = &(MME[i]);
}
}
}

View File

@@ -3,9 +3,15 @@
#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val)))
#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val)))
#define MMX_GETREGP(r) MMP[r]
#define MMX_GETREG(r) *(MMP[r])
#define MMX_SETEXP(r) \
*(MMEP[r]) = 0xffff
#define MMX_GETSRC() \
if (cpu_mod == 3) { \
src = cpu_state.MM[cpu_rm]; \
src = MMX_GETREG(cpu_rm); \
CLOCK_CYCLES(1); \
} else { \
SEG_CHECK_READ(cpu_state.ea_seg); \

File diff suppressed because it is too large Load Diff

View File

@@ -2,20 +2,25 @@ static int
opPCMPEQB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
dst->b[0] = (dst->b[0] == src.b[0]) ? 0xff : 0;
dst->b[1] = (dst->b[1] == src.b[1]) ? 0xff : 0;
dst->b[2] = (dst->b[2] == src.b[2]) ? 0xff : 0;
dst->b[3] = (dst->b[3] == src.b[3]) ? 0xff : 0;
dst->b[4] = (dst->b[4] == src.b[4]) ? 0xff : 0;
dst->b[5] = (dst->b[5] == src.b[5]) ? 0xff : 0;
dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0;
dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -23,20 +28,25 @@ static int
opPCMPEQB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
dst->b[0] = (dst->b[0] == src.b[0]) ? 0xff : 0;
dst->b[1] = (dst->b[1] == src.b[1]) ? 0xff : 0;
dst->b[2] = (dst->b[2] == src.b[2]) ? 0xff : 0;
dst->b[3] = (dst->b[3] == src.b[3]) ? 0xff : 0;
dst->b[4] = (dst->b[4] == src.b[4]) ? 0xff : 0;
dst->b[5] = (dst->b[5] == src.b[5]) ? 0xff : 0;
dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0;
dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -45,20 +55,25 @@ static int
opPCMPGTB_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
dst->b[0] = (dst->sb[0] > src.sb[0]) ? 0xff : 0;
dst->b[1] = (dst->sb[1] > src.sb[1]) ? 0xff : 0;
dst->b[2] = (dst->sb[2] > src.sb[2]) ? 0xff : 0;
dst->b[3] = (dst->sb[3] > src.sb[3]) ? 0xff : 0;
dst->b[4] = (dst->sb[4] > src.sb[4]) ? 0xff : 0;
dst->b[5] = (dst->sb[5] > src.sb[5]) ? 0xff : 0;
dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0;
dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -66,20 +81,25 @@ static int
opPCMPGTB_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
dst->b[0] = (dst->sb[0] > src.sb[0]) ? 0xff : 0;
dst->b[1] = (dst->sb[1] > src.sb[1]) ? 0xff : 0;
dst->b[2] = (dst->sb[2] > src.sb[2]) ? 0xff : 0;
dst->b[3] = (dst->sb[3] > src.sb[3]) ? 0xff : 0;
dst->b[4] = (dst->sb[4] > src.sb[4]) ? 0xff : 0;
dst->b[5] = (dst->sb[5] > src.sb[5]) ? 0xff : 0;
dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0;
dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -88,16 +108,21 @@ static int
opPCMPEQW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
dst->w[0] = (dst->w[0] == src.w[0]) ? 0xffff : 0;
dst->w[1] = (dst->w[1] == src.w[1]) ? 0xffff : 0;
dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0;
dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -105,16 +130,21 @@ static int
opPCMPEQW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
dst->w[0] = (dst->w[0] == src.w[0]) ? 0xffff : 0;
dst->w[1] = (dst->w[1] == src.w[1]) ? 0xffff : 0;
dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0;
dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -123,16 +153,21 @@ static int
opPCMPGTW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
dst->w[0] = (dst->sw[0] > src.sw[0]) ? 0xffff : 0;
dst->w[1] = (dst->sw[1] > src.sw[1]) ? 0xffff : 0;
dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0;
dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -140,16 +175,21 @@ static int
opPCMPGTW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
dst->w[0] = (dst->sw[0] > src.sw[0]) ? 0xffff : 0;
dst->w[1] = (dst->sw[1] > src.sw[1]) ? 0xffff : 0;
dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0;
dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -158,14 +198,19 @@ static int
opPCMPEQD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0;
dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -173,14 +218,19 @@ static int
opPCMPEQD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0;
dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -189,14 +239,19 @@ static int
opPCMPGTD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0;
dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -204,14 +259,19 @@ static int
opPCMPGTD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0;
dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0;
MMX_SETEXP(cpu_reg);
return 0;
}

View File

@@ -2,24 +2,38 @@ static int
opPAND_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q &= src.q;
dst->q &= src.q;
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPAND_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q &= src.q;
dst->q &= src.q;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -27,24 +41,38 @@ static int
opPANDN_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
dst->q = ~dst->q & src.q;
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPANDN_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
dst->q = ~dst->q & src.q;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -52,24 +80,38 @@ static int
opPOR_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q |= src.q;
dst->q |= src.q;
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPOR_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q |= src.q;
dst->q |= src.q;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -77,23 +119,37 @@ static int
opPXOR_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q ^= src.q;
dst->q ^= src.q;
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPXOR_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].q ^= src.q;
dst->q ^= src.q;
MMX_SETEXP(cpu_reg);
return 0;
}

View File

@@ -1,88 +1,112 @@
static int
opMOVD_l_mm_a16(uint32_t fetchdat)
{
uint32_t dst;
MMX_REG *op;
MMX_ENTER();
fetch_ea_16(fetchdat);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
cpu_state.MM[cpu_reg].l[1] = 0;
op->l[0] = cpu_state.regs[cpu_rm].l;
op->l[1] = 0;
CLOCK_CYCLES(1);
} else {
uint32_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].l[0] = dst;
cpu_state.MM[cpu_reg].l[1] = 0;
op->l[0] = dst;
op->l[1] = 0;
CLOCK_CYCLES(2);
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opMOVD_l_mm_a32(uint32_t fetchdat)
{
uint32_t dst;
MMX_REG *op;
MMX_ENTER();
fetch_ea_32(fetchdat);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
cpu_state.MM[cpu_reg].l[1] = 0;
op->l[0] = cpu_state.regs[cpu_rm].l;
op->l[1] = 0;
CLOCK_CYCLES(1);
} else {
uint32_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].l[0] = dst;
cpu_state.MM[cpu_reg].l[1] = 0;
op->l[0] = dst;
op->l[1] = 0;
CLOCK_CYCLES(2);
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opMOVD_mm_l_a16(uint32_t fetchdat)
{
MMX_REG *op;
MMX_ENTER();
fetch_ea_16(fetchdat);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
cpu_state.regs[cpu_rm].l = op->l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
writememl(easeg, cpu_state.eaaddr, op->l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
static int
opMOVD_mm_l_a32(uint32_t fetchdat)
{
MMX_REG *op;
MMX_ENTER();
fetch_ea_32(fetchdat);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
cpu_state.regs[cpu_rm].l = op->l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
writememl(easeg, cpu_state.eaaddr, op->l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
@@ -91,45 +115,59 @@ opMOVD_mm_l_a32(uint32_t fetchdat)
static int
opMOVD_mm_l_a16_cx(uint32_t fetchdat)
{
MMX_REG *op;
if (in_smm)
return opSMINT(fetchdat);
MMX_ENTER();
fetch_ea_16(fetchdat);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
cpu_state.regs[cpu_rm].l = op->l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
writememl(easeg, cpu_state.eaaddr, op->l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
static int
opMOVD_mm_l_a32_cx(uint32_t fetchdat)
{
MMX_REG *op;
if (in_smm)
return opSMINT(fetchdat);
MMX_ENTER();
fetch_ea_32(fetchdat);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
cpu_state.regs[cpu_rm].l = op->l[0];
CLOCK_CYCLES(1);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
writememl(easeg, cpu_state.eaaddr, op->l[0]);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
#endif
@@ -137,81 +175,121 @@ opMOVD_mm_l_a32_cx(uint32_t fetchdat)
static int
opMOVQ_q_mm_a16(uint32_t fetchdat)
{
uint64_t dst;
MMX_REG src;
MMX_REG *op;
MMX_ENTER();
fetch_ea_16(fetchdat);
src = MMX_GETREG(cpu_rm);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
op->q = src.q;
CLOCK_CYCLES(1);
} else {
uint64_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmemq(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].q = dst;
op->q = dst;
CLOCK_CYCLES(2);
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opMOVQ_q_mm_a32(uint32_t fetchdat)
{
uint64_t dst;
MMX_REG src;
MMX_REG *op;
MMX_ENTER();
fetch_ea_32(fetchdat);
src = MMX_GETREG(cpu_rm);
op = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
op->q = src.q;
CLOCK_CYCLES(1);
} else {
uint64_t dst;
SEG_CHECK_READ(cpu_state.ea_seg);
dst = readmemq(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 1;
cpu_state.MM[cpu_reg].q = dst;
op->q = dst;
CLOCK_CYCLES(2);
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opMOVQ_mm_q_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
src = MMX_GETREG(cpu_reg);
dst = MMX_GETREGP(cpu_rm);
if (cpu_mod == 3) {
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
dst->q = src.q;
CLOCK_CYCLES(1);
MMX_SETEXP(cpu_rm);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q);
writememq(easeg, cpu_state.eaaddr, src.q);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}
static int
opMOVQ_mm_q_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
src = MMX_GETREG(cpu_reg);
dst = MMX_GETREGP(cpu_rm);
if (cpu_mod == 3) {
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
dst->q = src.q;
CLOCK_CYCLES(1);
MMX_SETEXP(cpu_rm);
} else {
SEG_CHECK_WRITE(cpu_state.ea_seg);
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q);
writememq(easeg, cpu_state.eaaddr, src.q);
if (cpu_state.abrt)
return 1;
CLOCK_CYCLES(2);
}
return 0;
}

View File

@@ -1,45 +1,61 @@
static int
opPUNPCKLDQ_a16(uint32_t fetchdat)
{
uint32_t usrc;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
src = MMX_GETREG(cpu_rm);
dst = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
dst->l[1] = src.l[0];
CLOCK_CYCLES(1);
} else {
uint32_t src;
SEG_CHECK_READ(cpu_state.ea_seg);
src = readmeml(easeg, cpu_state.eaaddr);
usrc = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 0;
cpu_state.MM[cpu_reg].l[1] = src;
dst->l[1] = usrc;
CLOCK_CYCLES(2);
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPUNPCKLDQ_a32(uint32_t fetchdat)
{
uint32_t usrc;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
src = MMX_GETREG(cpu_rm);
dst = MMX_GETREGP(cpu_reg);
if (cpu_mod == 3) {
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
dst->l[1] = src.l[0];
CLOCK_CYCLES(1);
} else {
uint32_t src;
SEG_CHECK_READ(cpu_state.ea_seg);
src = readmeml(easeg, cpu_state.eaaddr);
usrc = readmeml(easeg, cpu_state.eaaddr);
if (cpu_state.abrt)
return 0;
cpu_state.MM[cpu_reg].l[1] = src;
dst->l[1] = usrc;
CLOCK_CYCLES(2);
}
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -47,13 +63,19 @@ static int
opPUNPCKHDQ_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
cpu_state.MM[cpu_reg].l[1] = src.l[1];
dst->l[0] = dst->l[1];
dst->l[1] = src.l[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -61,13 +83,19 @@ static int
opPUNPCKHDQ_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
cpu_state.MM[cpu_reg].l[1] = src.l[1];
dst->l[0] = dst->l[1];
dst->l[1] = src.l[1];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -76,19 +104,25 @@ static int
opPUNPCKLBW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[7] = src.b[3];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
cpu_state.MM[cpu_reg].b[5] = src.b[2];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
cpu_state.MM[cpu_reg].b[3] = src.b[1];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
cpu_state.MM[cpu_reg].b[1] = src.b[0];
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
dst->b[7] = src.b[3];
dst->b[6] = dst->b[3];
dst->b[5] = src.b[2];
dst->b[4] = dst->b[2];
dst->b[3] = src.b[1];
dst->b[2] = dst->b[1];
dst->b[1] = src.b[0];
dst->b[0] = dst->b[0];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -96,19 +130,25 @@ static int
opPUNPCKLBW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[7] = src.b[3];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
cpu_state.MM[cpu_reg].b[5] = src.b[2];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
cpu_state.MM[cpu_reg].b[3] = src.b[1];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
cpu_state.MM[cpu_reg].b[1] = src.b[0];
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
dst->b[7] = src.b[3];
dst->b[6] = dst->b[3];
dst->b[5] = src.b[2];
dst->b[4] = dst->b[2];
dst->b[3] = src.b[1];
dst->b[2] = dst->b[1];
dst->b[1] = src.b[0];
dst->b[0] = dst->b[0];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -117,19 +157,25 @@ static int
opPUNPCKHBW_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
cpu_state.MM[cpu_reg].b[1] = src.b[4];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
cpu_state.MM[cpu_reg].b[3] = src.b[5];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
cpu_state.MM[cpu_reg].b[5] = src.b[6];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
cpu_state.MM[cpu_reg].b[7] = src.b[7];
dst->b[0] = dst->b[4];
dst->b[1] = src.b[4];
dst->b[2] = dst->b[5];
dst->b[3] = src.b[5];
dst->b[4] = dst->b[6];
dst->b[5] = src.b[6];
dst->b[6] = dst->b[7];
dst->b[7] = src.b[7];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -137,19 +183,25 @@ static int
opPUNPCKHBW_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
cpu_state.MM[cpu_reg].b[1] = src.b[4];
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
cpu_state.MM[cpu_reg].b[3] = src.b[5];
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
cpu_state.MM[cpu_reg].b[5] = src.b[6];
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
cpu_state.MM[cpu_reg].b[7] = src.b[7];
dst->b[0] = dst->b[4];
dst->b[1] = src.b[4];
dst->b[2] = dst->b[5];
dst->b[3] = src.b[5];
dst->b[4] = dst->b[6];
dst->b[5] = src.b[6];
dst->b[6] = dst->b[7];
dst->b[7] = src.b[7];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -158,15 +210,21 @@ static int
opPUNPCKLWD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[3] = src.w[1];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
cpu_state.MM[cpu_reg].w[1] = src.w[0];
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
dst->w[3] = src.w[1];
dst->w[2] = dst->w[1];
dst->w[1] = src.w[0];
dst->w[0] = dst->w[0];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -174,15 +232,21 @@ static int
opPUNPCKLWD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[3] = src.w[1];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
cpu_state.MM[cpu_reg].w[1] = src.w[0];
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
dst->w[3] = src.w[1];
dst->w[2] = dst->w[1];
dst->w[1] = src.w[0];
dst->w[0] = dst->w[0];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -191,15 +255,21 @@ static int
opPUNPCKHWD_a16(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
cpu_state.MM[cpu_reg].w[1] = src.w[2];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
cpu_state.MM[cpu_reg].w[3] = src.w[3];
dst->w[0] = dst->w[2];
dst->w[1] = src.w[2];
dst->w[2] = dst->w[3];
dst->w[3] = src.w[3];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -207,15 +277,21 @@ static int
opPUNPCKHWD_a32(uint32_t fetchdat)
{
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
cpu_state.MM[cpu_reg].w[1] = src.w[2];
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
cpu_state.MM[cpu_reg].w[3] = src.w[3];
dst->w[0] = dst->w[2];
dst->w[1] = src.w[2];
dst->w[2] = dst->w[3];
dst->w[3] = src.w[3];
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -223,42 +299,52 @@ opPUNPCKHWD_a32(uint32_t fetchdat)
static int
opPACKSSWB_a16(uint32_t fetchdat)
{
MMX_REG src, dst;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
dst->sb[0] = SSATB(dst->sw[0]);
dst->sb[1] = SSATB(dst->sw[1]);
dst->sb[2] = SSATB(dst->sw[2]);
dst->sb[3] = SSATB(dst->sw[3]);
dst->sb[4] = SSATB(src.sw[0]);
dst->sb[5] = SSATB(src.sw[1]);
dst->sb[6] = SSATB(src.sw[2]);
dst->sb[7] = SSATB(src.sw[3]);
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPACKSSWB_a32(uint32_t fetchdat)
{
MMX_REG src, dst;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
dst->sb[0] = SSATB(dst->sw[0]);
dst->sb[1] = SSATB(dst->sw[1]);
dst->sb[2] = SSATB(dst->sw[2]);
dst->sb[3] = SSATB(dst->sw[3]);
dst->sb[4] = SSATB(src.sw[0]);
dst->sb[5] = SSATB(src.sw[1]);
dst->sb[6] = SSATB(src.sw[2]);
dst->sb[7] = SSATB(src.sw[3]);
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -266,42 +352,52 @@ opPACKSSWB_a32(uint32_t fetchdat)
static int
opPACKUSWB_a16(uint32_t fetchdat)
{
MMX_REG src, dst;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
dst->b[0] = USATB(dst->sw[0]);
dst->b[1] = USATB(dst->sw[1]);
dst->b[2] = USATB(dst->sw[2]);
dst->b[3] = USATB(dst->sw[3]);
dst->b[4] = USATB(src.sw[0]);
dst->b[5] = USATB(src.sw[1]);
dst->b[6] = USATB(src.sw[2]);
dst->b[7] = USATB(src.sw[3]);
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPACKUSWB_a32(uint32_t fetchdat)
{
MMX_REG src, dst;
MMX_REG src;
MMX_REG *dst;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSRC();
dst->b[0] = USATB(dst->sw[0]);
dst->b[1] = USATB(dst->sw[1]);
dst->b[2] = USATB(dst->sw[2]);
dst->b[3] = USATB(dst->sw[3]);
dst->b[4] = USATB(src.sw[0]);
dst->b[5] = USATB(src.sw[1]);
dst->b[6] = USATB(src.sw[2]);
dst->b[7] = USATB(src.sw[3]);
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -309,34 +405,48 @@ opPACKUSWB_a32(uint32_t fetchdat)
static int
opPACKSSDW_a16(uint32_t fetchdat)
{
MMX_REG src, dst;
MMX_REG src;
MMX_REG *dst;
MMX_REG dst2;
MMX_ENTER();
fetch_ea_16(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
dst = MMX_GETREGP(cpu_reg);
dst2 = *dst;
MMX_GETSRC();
dst->sw[0] = SSATW(dst2.sl[0]);
dst->sw[1] = SSATW(dst2.sl[1]);
dst->sw[2] = SSATW(src.sl[0]);
dst->sw[3] = SSATW(src.sl[1]);
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPACKSSDW_a32(uint32_t fetchdat)
{
MMX_REG src, dst;
MMX_REG src;
MMX_REG *dst;
MMX_REG dst2;
MMX_ENTER();
fetch_ea_32(fetchdat);
MMX_GETSRC();
dst = cpu_state.MM[cpu_reg];
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
dst = MMX_GETREGP(cpu_reg);
dst2 = *dst;
MMX_GETSRC();
dst->sw[0] = SSATW(dst2.sl[0]);
dst->sw[1] = SSATW(dst2.sl[1]);
dst->sw[2] = SSATW(src.sl[0]);
dst->sw[3] = SSATW(src.sl[1]);
MMX_SETEXP(cpu_reg);
return 0;
}

View File

@@ -1,6 +1,6 @@
#define MMX_GETSHIFT() \
if (cpu_mod == 3) { \
shift = cpu_state.MM[cpu_rm].b[0]; \
shift = (MMX_GETREG(cpu_rm)).b[0]; \
CLOCK_CYCLES(1); \
} else { \
SEG_CHECK_READ(cpu_state.ea_seg); \
@@ -16,37 +16,39 @@ opPSxxW_imm(uint32_t fetchdat)
int reg = fetchdat & 7;
int op = fetchdat & 0x38;
int shift = (fetchdat >> 8) & 0xff;
MMX_REG *dst;
cpu_state.pc += 2;
MMX_ENTER();
dst = MMX_GETREGP(reg);
switch (op) {
case 0x10: /*PSRLW*/
if (shift > 15)
cpu_state.MM[reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[reg].w[0] >>= shift;
cpu_state.MM[reg].w[1] >>= shift;
cpu_state.MM[reg].w[2] >>= shift;
cpu_state.MM[reg].w[3] >>= shift;
dst->w[0] >>= shift;
dst->w[1] >>= shift;
dst->w[2] >>= shift;
dst->w[3] >>= shift;
}
break;
case 0x20: /*PSRAW*/
if (shift > 15)
shift = 15;
cpu_state.MM[reg].sw[0] >>= shift;
cpu_state.MM[reg].sw[1] >>= shift;
cpu_state.MM[reg].sw[2] >>= shift;
cpu_state.MM[reg].sw[3] >>= shift;
dst->sw[0] >>= shift;
dst->sw[1] >>= shift;
dst->sw[2] >>= shift;
dst->sw[3] >>= shift;
break;
case 0x30: /*PSLLW*/
if (shift > 15)
cpu_state.MM[reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[reg].w[0] <<= shift;
cpu_state.MM[reg].w[1] <<= shift;
cpu_state.MM[reg].w[2] <<= shift;
cpu_state.MM[reg].w[3] <<= shift;
dst->w[0] <<= shift;
dst->w[1] <<= shift;
dst->w[2] <<= shift;
dst->w[3] <<= shift;
}
break;
default:
@@ -55,6 +57,8 @@ opPSxxW_imm(uint32_t fetchdat)
return 0;
}
MMX_SETEXP(reg);
CLOCK_CYCLES(1);
return 0;
}
@@ -62,126 +66,162 @@ opPSxxW_imm(uint32_t fetchdat)
static int
opPSLLW_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[cpu_reg].w[0] <<= shift;
cpu_state.MM[cpu_reg].w[1] <<= shift;
cpu_state.MM[cpu_reg].w[2] <<= shift;
cpu_state.MM[cpu_reg].w[3] <<= shift;
dst->w[0] <<= shift;
dst->w[1] <<= shift;
dst->w[2] <<= shift;
dst->w[3] <<= shift;
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSLLW_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[cpu_reg].w[0] <<= shift;
cpu_state.MM[cpu_reg].w[1] <<= shift;
cpu_state.MM[cpu_reg].w[2] <<= shift;
cpu_state.MM[cpu_reg].w[3] <<= shift;
dst->w[0] <<= shift;
dst->w[1] <<= shift;
dst->w[2] <<= shift;
dst->w[3] <<= shift;
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSRLW_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[cpu_reg].w[0] >>= shift;
cpu_state.MM[cpu_reg].w[1] >>= shift;
cpu_state.MM[cpu_reg].w[2] >>= shift;
cpu_state.MM[cpu_reg].w[3] >>= shift;
dst->w[0] >>= shift;
dst->w[1] >>= shift;
dst->w[2] >>= shift;
dst->w[3] >>= shift;
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSRLW_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 15)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[cpu_reg].w[0] >>= shift;
cpu_state.MM[cpu_reg].w[1] >>= shift;
cpu_state.MM[cpu_reg].w[2] >>= shift;
cpu_state.MM[cpu_reg].w[3] >>= shift;
dst->w[0] >>= shift;
dst->w[1] >>= shift;
dst->w[2] >>= shift;
dst->w[3] >>= shift;
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSRAW_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 15)
shift = 15;
cpu_state.MM[cpu_reg].sw[0] >>= shift;
cpu_state.MM[cpu_reg].sw[1] >>= shift;
cpu_state.MM[cpu_reg].sw[2] >>= shift;
cpu_state.MM[cpu_reg].sw[3] >>= shift;
dst->sw[0] >>= shift;
dst->sw[1] >>= shift;
dst->sw[2] >>= shift;
dst->sw[3] >>= shift;
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSRAW_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 15)
shift = 15;
cpu_state.MM[cpu_reg].sw[0] >>= shift;
cpu_state.MM[cpu_reg].sw[1] >>= shift;
cpu_state.MM[cpu_reg].sw[2] >>= shift;
cpu_state.MM[cpu_reg].sw[3] >>= shift;
dst->sw[0] >>= shift;
dst->sw[1] >>= shift;
dst->sw[2] >>= shift;
dst->sw[3] >>= shift;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -192,31 +232,34 @@ opPSxxD_imm(uint32_t fetchdat)
int reg = fetchdat & 7;
int op = fetchdat & 0x38;
int shift = (fetchdat >> 8) & 0xff;
MMX_REG *dst;
cpu_state.pc += 2;
MMX_ENTER();
dst = MMX_GETREGP(reg);
switch (op) {
case 0x10: /*PSRLD*/
if (shift > 31)
cpu_state.MM[reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[reg].l[0] >>= shift;
cpu_state.MM[reg].l[1] >>= shift;
dst->l[0] >>= shift;
dst->l[1] >>= shift;
}
break;
case 0x20: /*PSRAD*/
if (shift > 31)
shift = 31;
cpu_state.MM[reg].sl[0] >>= shift;
cpu_state.MM[reg].sl[1] >>= shift;
dst->sl[0] >>= shift;
dst->sl[1] >>= shift;
break;
case 0x30: /*PSLLD*/
if (shift > 31)
cpu_state.MM[reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[reg].l[0] <<= shift;
cpu_state.MM[reg].l[1] <<= shift;
dst->l[0] <<= shift;
dst->l[1] <<= shift;
}
break;
default:
@@ -225,6 +268,8 @@ opPSxxD_imm(uint32_t fetchdat)
return 0;
}
MMX_SETEXP(reg);
CLOCK_CYCLES(1);
return 0;
}
@@ -232,114 +277,150 @@ opPSxxD_imm(uint32_t fetchdat)
static int
opPSLLD_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[cpu_reg].l[0] <<= shift;
cpu_state.MM[cpu_reg].l[1] <<= shift;
dst->l[0] <<= shift;
dst->l[1] <<= shift;
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSLLD_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[cpu_reg].l[0] <<= shift;
cpu_state.MM[cpu_reg].l[1] <<= shift;
dst->l[0] <<= shift;
dst->l[1] <<= shift;
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSRLD_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[cpu_reg].l[0] >>= shift;
cpu_state.MM[cpu_reg].l[1] >>= shift;
dst->l[0] >>= shift;
dst->l[1] >>= shift;
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSRLD_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 31)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else {
cpu_state.MM[cpu_reg].l[0] >>= shift;
cpu_state.MM[cpu_reg].l[1] >>= shift;
dst->l[0] >>= shift;
dst->l[1] >>= shift;
}
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSRAD_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 31)
shift = 31;
cpu_state.MM[cpu_reg].sl[0] >>= shift;
cpu_state.MM[cpu_reg].sl[1] >>= shift;
dst->sl[0] >>= shift;
dst->sl[1] >>= shift;
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSRAD_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 31)
shift = 31;
cpu_state.MM[cpu_reg].sl[0] >>= shift;
cpu_state.MM[cpu_reg].sl[1] >>= shift;
dst->sl[0] >>= shift;
dst->sl[1] >>= shift;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -350,27 +431,32 @@ opPSxxQ_imm(uint32_t fetchdat)
int reg = fetchdat & 7;
int op = fetchdat & 0x38;
int shift = (fetchdat >> 8) & 0xff;
MMX_REG *dst;
cpu_state.pc += 2;
MMX_ENTER();
dst = MMX_GETREGP(reg);
switch (op) {
case 0x10: /*PSRLW*/
if (shift > 63)
cpu_state.MM[reg].q = 0;
dst->q = 0;
else
cpu_state.MM[reg].q >>= shift;
dst->q >>= shift;
break;
case 0x20: /*PSRAW*/
if (shift > 63)
shift = 63;
cpu_state.MM[reg].sq >>= shift;
dst->sq >>= shift;
break;
case 0x30: /*PSLLW*/
if (shift > 63)
cpu_state.MM[reg].q = 0;
dst->q = 0;
else
cpu_state.MM[reg].q <<= shift;
dst->q <<= shift;
break;
default:
cpu_state.pc = cpu_state.oldpc;
@@ -378,6 +464,8 @@ opPSxxQ_imm(uint32_t fetchdat)
return 0;
}
MMX_SETEXP(reg);
CLOCK_CYCLES(1);
return 0;
}
@@ -385,34 +473,46 @@ opPSxxQ_imm(uint32_t fetchdat)
static int
opPSLLQ_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else
cpu_state.MM[cpu_reg].q <<= shift;
dst->q <<= shift;
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSLLQ_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else
cpu_state.MM[cpu_reg].q <<= shift;
dst->q <<= shift;
MMX_SETEXP(cpu_reg);
return 0;
}
@@ -420,34 +520,46 @@ opPSLLQ_a32(uint32_t fetchdat)
static int
opPSRLQ_a16(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_16(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else
cpu_state.MM[cpu_reg].q >>= shift;
dst->q >>= shift;
MMX_SETEXP(cpu_reg);
return 0;
}
static int
opPSRLQ_a32(uint32_t fetchdat)
{
MMX_REG *dst;
int shift;
MMX_ENTER();
fetch_ea_32(fetchdat);
dst = MMX_GETREGP(cpu_reg);
MMX_GETSHIFT();
if (shift > 63)
cpu_state.MM[cpu_reg].q = 0;
dst->q = 0;
else
cpu_state.MM[cpu_reg].q >>= shift;
dst->q >>= shift;
MMX_SETEXP(cpu_reg);
return 0;
}

View File

@@ -439,6 +439,79 @@ FPU_tagof(const floatx80 reg)
return X87_TAG_VALID;
}
uint8_t
pack_FPU_TW(uint16_t twd)
{
uint8_t tag_byte = 0;
if ((twd & 0x0003) != 0x0003) tag_byte |= 0x01;
if ((twd & 0x000c) != 0x000c) tag_byte |= 0x02;
if ((twd & 0x0030) != 0x0030) tag_byte |= 0x04;
if ((twd & 0x00c0) != 0x00c0) tag_byte |= 0x08;
if ((twd & 0x0300) != 0x0300) tag_byte |= 0x10;
if ((twd & 0x0c00) != 0x0c00) tag_byte |= 0x20;
if ((twd & 0x3000) != 0x3000) tag_byte |= 0x40;
if ((twd & 0xc000) != 0xc000) tag_byte |= 0x80;
return tag_byte;
}
uint16_t
unpack_FPU_TW(uint16_t tag_byte)
{
uint32_t twd = 0;
/* FTW
*
* Note that the original format for FTW can be recreated from the stored
* FTW valid bits and the stored 80-bit FP data (assuming the stored data
* was not the contents of MMX registers) using the following table:
| Exponent | Exponent | Fraction | J,M bits | FTW valid | x87 FTW |
| all 1s | all 0s | all 0s | | | |
-------------------------------------------------------------------
| 0 | 0 | 0 | 0x | 1 | S 10 |
| 0 | 0 | 0 | 1x | 1 | V 00 |
-------------------------------------------------------------------
| 0 | 0 | 1 | 00 | 1 | S 10 |
| 0 | 0 | 1 | 10 | 1 | V 00 |
-------------------------------------------------------------------
| 0 | 1 | 0 | 0x | 1 | S 10 |
| 0 | 1 | 0 | 1x | 1 | S 10 |
-------------------------------------------------------------------
| 0 | 1 | 1 | 00 | 1 | Z 01 |
| 0 | 1 | 1 | 10 | 1 | S 10 |
-------------------------------------------------------------------
| 1 | 0 | 0 | 1x | 1 | S 10 |
| 1 | 0 | 0 | 1x | 1 | S 10 |
-------------------------------------------------------------------
| 1 | 0 | 1 | 00 | 1 | S 10 |
| 1 | 0 | 1 | 10 | 1 | S 10 |
-------------------------------------------------------------------
| all combinations above | 0 | E 11 |
*
* The J-bit is defined to be the 1-bit binary integer to the left of
* the decimal place in the significand.
*
* The M-bit is defined to be the most significant bit of the fractional
* portion of the significand (i.e., the bit immediately to the right of
* the decimal place). When the M-bit is the most significant bit of the
* fractional portion of the significand, it must be 0 if the fraction
* is all 0's.
*/
for (int index = 7; index >= 0; index--, twd <<= 2, tag_byte <<= 1) {
if (tag_byte & 0x80) {
const floatx80 *fpu_reg = &fpu_state.st_space[index & 7];
twd |= FPU_tagof(*fpu_reg);
} else {
twd |= X87_TAG_EMPTY;
}
}
return (twd >> 2);
}
#ifdef ENABLE_808X_LOG
void

View File

@@ -10,9 +10,14 @@ static __inline void
x87_set_mmx(void)
{
uint64_t *p;
cpu_state.TOP = 0;
p = (uint64_t *) cpu_state.tag;
*p = 0x0101010101010101ull;
if (fpu_softfloat) {
fpu_state.tag = 0;
fpu_state.tos = 0; /* reset FPU Top-Of-Stack */
} else {
cpu_state.TOP = 0;
p = (uint64_t *) cpu_state.tag;
*p = 0x0101010101010101ull;
}
cpu_state.ismmx = 1;
}
@@ -20,8 +25,13 @@ static __inline void
x87_emms(void)
{
uint64_t *p;
p = (uint64_t *) cpu_state.tag;
*p = 0;
if (fpu_softfloat) {
fpu_state.tag = 0xffff;
fpu_state.tos = 0; /* reset FPU Top-Of-Stack */
} else {
p = (uint64_t *) cpu_state.tag;
*p = 0;
}
cpu_state.ismmx = 0;
}
@@ -141,6 +151,8 @@ void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack);
int FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status);
int FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status);
int FPU_tagof(const floatx80 reg);
uint8_t pack_FPU_TW(uint16_t twd);
uint16_t unpack_FPU_TW(uint16_t tag_byte);
static __inline uint16_t
i387_get_control_word(void)

View File

@@ -82,7 +82,8 @@
#define KBC_VEN_NCR 0x24
#define KBC_VEN_ALI 0x28
#define KBC_VEN_SIEMENS 0x2c
#define KBC_VEN_MASK 0x3c
#define KBC_VEN_COMPAQ 0x30
#define KBC_VEN_MASK 0x7c
#define FLAG_CLOCK 0x01
#define FLAG_CACHE 0x02
@@ -981,6 +982,8 @@ write64_generic(void *priv, uint8_t val)
} else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_GREEN))
/* (B0 or F0) | (0x08 or 0x0c) */
kbc_delay_to_ob(dev, ((dev->p1 | fixed_bits) & 0xf0) | (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c), 0, 0x00);
else if (kbc_ven == KBC_VEN_COMPAQ)
kbc_delay_to_ob(dev, dev->p1 | (hasfpu ? 0x00 : 0x04), 0, 0x00);
else
/* (B0 or F0) | (0x04 or 0x44) */
kbc_delay_to_ob(dev, dev->p1 | fixed_bits, 0, 0x00);
@@ -1968,6 +1971,7 @@ kbc_at_init(const device_t *info)
case KBC_VEN_GENERIC:
case KBC_VEN_NCR:
case KBC_VEN_IBM_PS1:
case KBC_VEN_COMPAQ:
dev->write64_ven = write64_generic;
break;
@@ -2141,6 +2145,20 @@ const device_t keyboard_at_ncr_device = {
.config = NULL
};
const device_t keyboard_at_compaq_device = {
.name = "PC/AT Keyboard (Compaq)",
.internal_name = "keyboard_at_compaq",
.flags = DEVICE_KBC,
.local = KBC_TYPE_ISA | KBC_VEN_COMPAQ,
.init = kbc_at_init,
.close = kbc_at_close,
.reset = kbc_at_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_ps2_device = {
.name = "PS/2 Keyboard",
.internal_name = "keyboard_ps2",

View File

@@ -119,6 +119,8 @@ static void
serial_passthrough_speed_changed(void *priv)
{
serial_passthrough_t *dev = (serial_passthrough_t *) priv;
if (!dev)
return;
timer_stop(&dev->host_to_serial_timer);
/* FIXME: do something to dev->baudrate */
@@ -132,9 +134,11 @@ static void
serial_passthrough_dev_close(void *priv)
{
serial_passthrough_t *dev = (serial_passthrough_t *) priv;
if (!dev)
return;
/* Detach passthrough device from COM port */
if (dev && dev->serial && dev->serial->sd)
if (dev->serial && dev->serial->sd)
memset(dev->serial->sd, 0, sizeof(serial_device_t));
plat_serpt_close(dev);
@@ -184,6 +188,10 @@ serial_passthrough_dev_init(const device_t *info)
/* Attach passthrough device to a COM port */
dev->serial = serial_attach_ex(dev->port, serial_passthrough_rcr_cb,
serial_passthrough_write, serial_passthrough_transmit_period, serial_passthrough_lcr_callback, dev);
if (!dev->serial) {
free(dev);
return NULL;
}
strncpy(dev->host_serial_path, device_get_config_string("host_serial_path"), 1023);
#ifdef _WIN32

View File

@@ -234,6 +234,7 @@ extern const device_t keyboard_at_tg_ami_device;
extern const device_t keyboard_at_toshiba_device;
extern const device_t keyboard_at_olivetti_device;
extern const device_t keyboard_at_ncr_device;
extern const device_t keyboard_at_compaq_device;
extern const device_t keyboard_ps2_device;
extern const device_t keyboard_ps2_ps1_device;
extern const device_t keyboard_ps2_ps1_pci_device;

View File

@@ -545,9 +545,8 @@ extern int machine_at_cmdpc_init(const machine_t *);
extern int machine_at_portableii_init(const machine_t *);
extern int machine_at_portableiii_init(const machine_t *);
extern int machine_at_portableiii386_init(const machine_t *);
#if defined(DEV_BRANCH) && defined(USE_DESKPRO386)
extern int machine_at_deskpro386_init(const machine_t *);
#endif
extern int machine_at_deskpro386_01_1988_init(const machine_t *);
/* m_at_socket4.c */
extern void machine_at_premiere_common_init(const machine_t *, int);

46
src/include/86box/row.h Normal file
View File

@@ -0,0 +1,46 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the SMRAM interface.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2020 Miran Grca.
*/
#ifndef EMU_ROW_H
# define EMU_ROW_H
typedef struct _row_
{
struct _smram_ *prev;
struct _smram_ *next;
uint8_t *buf;
mem_mapping_t mapping;
uint32_t host_base;
uint32_t host_size;
uint32_t ram_base;
uint32_t ram_size;
uint32_t ram_mask;
uint32_t boundary;
} row_t;
extern void row_disable(uint8_t row_id);
extern void row_set_boundary(uint8_t row_id, uint32_t boundary);
extern device_t row_device;
#endif /*EMU_ROW_H*/

View File

@@ -24,6 +24,8 @@ typedef struct ibm8514_t {
int force_old_addr;
int type;
int local;
int bpp;
uint32_t vram_size;
uint32_t vram_mask;
@@ -32,6 +34,7 @@ typedef struct ibm8514_t {
uint8_t dac_mask, dac_status;
uint32_t *map8;
int dac_addr, dac_pos, dac_r, dac_g;
int internal_pitch;
struct {
uint16_t subsys_cntl;
@@ -58,7 +61,7 @@ typedef struct ibm8514_t {
uint8_t pix_trans[2];
int poly_draw;
int ssv_state;
int x1, x2, y1, y2;
int16_t x1, x2, x3, y1, y2;
int sys_cnt, sys_cnt2;
int temp_cnt;
int16_t cx, cy, oldcy;
@@ -80,6 +83,7 @@ typedef struct ibm8514_t {
uint16_t scratch;
int fill_state, xdir, ydir;
uint32_t ge_offset;
} accel;
uint16_t test;
@@ -90,7 +94,7 @@ typedef struct ibm8514_t {
dispon, hdisp_on, linecountff,
vc, linepos, oddeven, cursoron, blink, scrollcache,
firstline, lastline, firstline_draw, lastline_draw,
displine, fullchange, x_add, y_add;
displine, fullchange;
uint32_t ma, maback;
uint8_t *vram, *changedvram, linedbl;
@@ -103,11 +107,13 @@ typedef struct ibm8514_t {
int disp_cntl, interlace;
uint8_t subsys_cntl, subsys_stat;
volatile int force_busy, force_busy2;
atomic_int force_busy, force_busy2;
int blitter_busy;
uint64_t blitter_time;
uint64_t status_time;
int pitch;
int ext_pitch;
int ext_crt_pitch;
} ibm8514_t;
#endif /*VIDEO_8514A_H*/

View File

@@ -43,6 +43,7 @@ typedef struct ati_eeprom_t {
} ati_eeprom_t;
void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type);
void ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn);
void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat);
int ati_eeprom_read(ati_eeprom_t *eeprom);

View File

@@ -31,8 +31,9 @@
# define FLAG_NOSKEW 16
# define FLAG_ADDR_BY16 32
# define FLAG_RAMDAC_SHIFT 64
# define FLAG_128K_MASK 128
# define FLAG_ATI 128
# define FLAG_S3_911_16BIT 256
# define FLAG_512K_MASK 512
struct monitor_t;
typedef struct {

View File

@@ -36,6 +36,7 @@ typedef struct xga_t {
mem_mapping_t linear_mapping;
mem_mapping_t video_mapping;
rom_t bios_rom;
rom_t vga_bios_rom;
xga_hwcursor_t hwcursor, hwcursor_latch;
PALETTE extpal;
@@ -57,7 +58,7 @@ typedef struct xga_t {
uint8_t clk_sel_1, clk_sel_2;
uint8_t hwc_control;
uint8_t bus_arb;
uint8_t select_pos_isa;
uint8_t isa_pos_enable;
uint8_t hwcursor_oddeven;
uint8_t cfg_reg_instance;
uint8_t rowcount;
@@ -70,6 +71,8 @@ typedef struct xga_t {
uint8_t sprite_data[1024];
uint8_t scrollcache;
uint8_t direct_color;
uint8_t dma_channel;
uint8_t instance_isa, instance_num, ext_mem_addr;
uint8_t *vram, *changedvram;
int16_t hwc_pos_x;

View File

@@ -17,6 +17,11 @@
#ifndef VIDEO_XGA_DEVICE_H
#define VIDEO_XGA_DEVICE_H
extern int xga_has_vga;
#ifdef EMU_DEVICE_H
extern const device_t xga_device;
extern const device_t xga_isa_device;
extern const device_t inmos_isa_device;
#endif
#endif /*VIDEO_XGA_DEVICE_H*/

View File

@@ -60,8 +60,10 @@ enum {
#define VIDEO_FLAG_TYPE_CGA 0
#define VIDEO_FLAG_TYPE_MDA 1
#define VIDEO_FLAG_TYPE_SPECIAL 2
#define VIDEO_FLAG_TYPE_NONE 3
#define VIDEO_FLAG_TYPE_MASK 3
#define VIDEO_FLAG_TYPE_8514 3
#define VIDEO_FLAG_TYPE_XGA 4
#define VIDEO_FLAG_TYPE_NONE 5
#define VIDEO_FLAG_TYPE_MASK 7
typedef struct video_timings_t {
int type;
@@ -206,6 +208,7 @@ extern double cpuclock;
extern int emu_fps;
extern int frames;
extern int readflash;
extern int ibm8514_has_vga;
/* Function handler pointers. */
extern void (*video_recalctimings)(void);
@@ -232,6 +235,8 @@ extern int video_card_get_flags(int card);
extern int video_is_mda(void);
extern int video_is_cga(void);
extern int video_is_ega_vga(void);
extern int video_is_8514(void);
extern int video_is_xga(void);
extern void video_inform_monitor(int type, const video_timings_t *ptr, int monitor_index);
extern int video_get_type_monitor(int monitor_index);
@@ -290,8 +295,12 @@ extern uint32_t video_color_transform(uint32_t color);
/* IBM XGA */
extern void xga_device_add(void);
/* IBM 8514/A and generic clones*/
/* IBM 8514/A and clones*/
extern void ibm8514_device_add(void);
extern const device_t mach8_isa_device;
extern const device_t mach32_isa_device;
extern const device_t mach32_vlb_device;
extern const device_t mach32_pci_device;
/* ATi Mach64 */
extern const device_t mach64gx_isa_device;

View File

@@ -31,6 +31,7 @@
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
@@ -41,22 +42,28 @@
#include <86box/vid_cga.h>
#include <86box/vid_cga_comp.h>
static video_timings_t timing_compaq_plasma = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
enum {
COMPAQ_PORTABLEII = 0,
COMPAQ_PORTABLEIII,
COMPAQ_PORTABLEIII386,
COMPAQ_DESKPRO386
COMPAQ_DESKPRO386,
COMPAQ_DESKPRO386_01_1988
};
#define CGA_RGB 0
#define CGA_COMPOSITE 1
#define COMPOSITE_OLD 0
#define COMPOSITE_NEW 1
/*Very rough estimate*/
#define VID_CLOCK (double) (651 * 416 * 60)
static uint8_t cga_crtcmask[32] = {
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* Mapping of attributes to colours */
static uint32_t amber;
static uint32_t black;
@@ -72,6 +79,8 @@ static uint32_t normcols[256][2];
*/
static int8_t cpq_st_display_internal = -1;
static uint8_t mdaattr[256][2][2];
static void
compaq_plasma_display_set(uint8_t internal)
{
@@ -85,21 +94,13 @@ compaq_plasma_display_get(void)
}
typedef struct compaq_plasma_t {
mem_mapping_t plasma_mapping;
cga_t cga;
uint8_t port_23c6;
uint8_t internal_monitor;
uint8_t attrmap; /* Attribute mapping register */
int linepos, displine;
uint8_t *vram;
uint64_t dispontime, dispofftime;
int dispon, fullchange;
uint8_t attrmap;
} compaq_plasma_t;
static uint8_t cga_crtcmask[32] = {
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static int compaq_machine_type = 0;
/* Compaq Deskpro 386 remaps RAM from 0xA0000-0xFFFFF to 0xFA0000-0xFFFFFF */
static mem_mapping_t ram_mapping;
@@ -121,8 +122,18 @@ compaq_plasma_recalctimings(compaq_plasma_t *self)
disptime = 651;
_dispontime = 640;
_dispofftime = disptime - _dispontime;
self->dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
self->dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
}
static void
compaq_plasma_waitstates(void *p)
{
int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 };
int ws;
ws = ws_array[cycles & 0xf];
sub_cycles(ws);
}
static void
@@ -130,7 +141,8 @@ compaq_plasma_write(uint32_t addr, uint8_t val, void *priv)
{
compaq_plasma_t *self = (compaq_plasma_t *) priv;
self->vram[addr & 0x7fff] = val;
self->cga.vram[addr & 0x7fff] = val;
compaq_plasma_waitstates(&self->cga);
}
static uint8_t
@@ -139,206 +151,12 @@ compaq_plasma_read(uint32_t addr, void *priv)
compaq_plasma_t *self = (compaq_plasma_t *) priv;
uint8_t ret;
ret = (self->vram[addr & 0x7fff]);
compaq_plasma_waitstates(&self->cga);
ret = (self->cga.vram[addr & 0x7fff]);
return ret;
}
/* Draw a row of text in 80-column mode */
static void
compaq_plasma_text80(compaq_plasma_t *self)
{
uint32_t cols[2];
int c;
uint8_t chr;
uint8_t attr;
int drawcursor;
int cursorline;
int blink;
uint16_t addr;
uint8_t sc;
uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff;
uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff;
sc = (self->displine) & 15;
addr = ((ma & ~1) + (self->displine >> 4) * 80) * 2;
ma += (self->displine >> 4) * 80;
if ((self->cga.crtc[10] & 0x60) == 0x20)
cursorline = 0;
else
cursorline = ((self->cga.crtc[10] & 0x0F) * 2 <= sc) && ((self->cga.crtc[11] & 0x0F) * 2 >= sc);
for (uint8_t x = 0; x < 80; x++) {
chr = self->vram[(addr + 2 * x) & 0x7FFF];
attr = self->vram[(addr + 2 * x + 1) & 0x7FFF];
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16));
blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
if (self->cga.cgamode & 0x20) { /* Blink */
cols[1] = blinkcols[attr][1];
cols[0] = blinkcols[attr][0];
if (blink)
cols[1] = cols[0];
} else {
cols[1] = normcols[attr][1];
cols[0] = normcols[attr][0];
}
if (drawcursor) {
for (c = 0; c < 8; c++)
((uint32_t *) buffer32->line[self->displine])[(x << 3) + c] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
} else {
for (c = 0; c < 8; c++)
((uint32_t *) buffer32->line[self->displine])[(x << 3) + c] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
++ma;
}
}
/* Draw a row of text in 40-column mode */
static void
compaq_plasma_text40(compaq_plasma_t *self)
{
uint32_t cols[2];
int c;
uint8_t chr;
uint8_t attr;
int drawcursor;
int cursorline;
int blink;
uint16_t addr;
uint8_t sc;
uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff;
uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff;
sc = (self->displine) & 15;
addr = ((ma & ~1) + (self->displine >> 4) * 40) * 2;
ma += (self->displine >> 4) * 40;
if ((self->cga.crtc[10] & 0x60) == 0x20)
cursorline = 0;
else
cursorline = ((self->cga.crtc[10] & 0x0F) * 2 <= sc) && ((self->cga.crtc[11] & 0x0F) * 2 >= sc);
for (uint8_t x = 0; x < 40; x++) {
chr = self->vram[(addr + 2 * x) & 0x7FFF];
attr = self->vram[(addr + 2 * x + 1) & 0x7FFF];
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16));
blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
if (self->cga.cgamode & 0x20) { /* Blink */
cols[1] = blinkcols[attr][1];
cols[0] = blinkcols[attr][0];
if (blink)
cols[1] = cols[0];
} else {
cols[1] = normcols[attr][1];
cols[0] = normcols[attr][0];
}
if (drawcursor) {
for (c = 0; c < 8; c++) {
((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
}
} else {
for (c = 0; c < 8; c++) {
((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
}
++ma;
}
}
/* Draw a line in CGA 640x200 or Compaq Plasma 640x400 mode */
static void
compaq_plasma_cgaline6(compaq_plasma_t *self)
{
uint8_t dat;
uint32_t ink = 0;
uint16_t addr;
uint32_t fg = (self->cga.cgacol & 0x0F) ? amber : black;
uint32_t bg = black;
uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff;
if ((self->cga.crtc[9] == 3) || (self->port_23c6 & 1)) /* 640*400 */ {
addr = ((self->displine) & 1) * 0x2000 + ((self->displine >> 1) & 1) * 0x4000 + (self->displine >> 2) * 80 + ((ma & ~1) << 1);
} else {
addr = ((self->displine >> 1) & 1) * 0x2000 + (self->displine >> 2) * 80 + ((ma & ~1) << 1);
}
for (uint8_t x = 0; x < 80; x++) {
dat = self->vram[addr & 0x7FFF];
addr++;
for (uint8_t c = 0; c < 8; c++) {
ink = (dat & 0x80) ? fg : bg;
if (!(self->cga.cgamode & 8))
ink = black;
((uint32_t *) buffer32->line[self->displine])[x * 8 + c] = ink;
dat <<= 1;
}
}
}
/* Draw a line in CGA 320x200 mode. Here the CGA colours are converted to
* dither patterns: colour 1 to 25% grey, colour 2 to 50% grey */
static void
compaq_plasma_cgaline4(compaq_plasma_t *self)
{
uint8_t dat;
uint8_t pattern;
uint32_t ink0 = 0;
uint32_t ink1 = 0;
uint16_t addr;
uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff;
/* 320*200 */
addr = ((self->displine >> 1) & 1) * 0x2000 + (self->displine >> 2) * 80 + ((ma & ~1) << 1);
for (uint8_t x = 0; x < 80; x++) {
dat = self->vram[addr & 0x7FFF];
addr++;
for (uint8_t c = 0; c < 4; c++) {
pattern = (dat & 0xC0) >> 6;
if (!(self->cga.cgamode & 8))
pattern = 0;
switch (pattern & 3) {
case 0:
ink0 = ink1 = black;
break;
case 1:
if (self->displine & 1) {
ink0 = black;
ink1 = black;
} else {
ink0 = amber;
ink1 = black;
}
break;
case 2:
if (self->displine & 1) {
ink0 = black;
ink1 = amber;
} else {
ink0 = amber;
ink1 = black;
}
break;
case 3:
ink0 = ink1 = amber;
break;
}
((uint32_t *) buffer32->line[self->displine])[x * 8 + 2 * c] = ink0;
((uint32_t *) buffer32->line[self->displine])[x * 8 + 2 * c + 1] = ink1;
dat <<= 2;
}
}
}
static void
compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
{
@@ -348,7 +166,7 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
switch (addr) {
/* Emulated CRTC, register select */
case 0x3d4:
self->cga.crtcreg = val & 31;
cga_out(addr, val, &self->cga);
break;
/* Emulated CRTC, value */
@@ -366,33 +184,26 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
if (old != val) {
if (self->cga.crtcreg < 0xe || self->cga.crtcreg > 0x10) {
self->fullchange = changeframecount;
self->cga.fullchange = changeframecount;
compaq_plasma_recalctimings(self);
}
}
break;
case 0x3d8:
self->cga.cgamode = val;
break;
case 0x3d9:
self->cga.cgacol = val;
cga_out(addr, val, &self->cga);
break;
case 0x13c6:
if (val & 8)
compaq_plasma_display_set(1);
else
compaq_plasma_display_set(0);
compaq_plasma_display_set((val & 8) ? 1 : 0);
break;
case 0x23c6:
self->port_23c6 = val;
if (val & 8) /* Disable internal CGA */
mem_mapping_disable(&self->plasma_mapping);
mem_mapping_disable(&self->cga.mapping);
else
mem_mapping_enable(&self->plasma_mapping);
mem_mapping_enable(&self->cga.mapping);
break;
}
}
@@ -405,31 +216,38 @@ compaq_plasma_in(uint16_t addr, void *priv)
switch (addr) {
case 0x3d4:
ret = self->cga.crtcreg;
case 0x3da:
ret = cga_in(addr, &self->cga);
break;
case 0x3d5:
if (self->cga.crtcreg == 0x12) {
ret = self->attrmap & 0x0F;
ret = self->attrmap & 0x0f;
if (self->internal_monitor)
ret |= 0x30; /* Plasma / CRT */
} else
ret = self->cga.crtc[self->cga.crtcreg];
break;
case 0x3da:
ret = self->cga.cgastat;
ret = cga_in(addr, &self->cga);
break;
case 0x13c6:
if (compaq_plasma_display_get())
ret = 8;
else
ret = 0;
ret = compaq_plasma_display_get() ? 8 : 0;
ret |= 4;
break;
case 0x1bc6:
ret = 0;
if (compaq_plasma_display_get()) {
if ((self->cga.cgamode & 0x12) == 0x12) {
if (self->port_23c6 & 8)
ret |= 0x40;
else
ret |= 0x20;
}
}
break;
case 0x23c6:
ret = self->port_23c6;
ret = 0;
break;
}
@@ -440,56 +258,242 @@ static void
compaq_plasma_poll(void *p)
{
compaq_plasma_t *self = (compaq_plasma_t *) p;
uint8_t chr, attr;
uint8_t sc;
uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff;
uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff;
uint16_t addr;
int drawcursor;
int x, c;
int cursorline;
int blink = 0;
int underline = 0;
uint32_t ink = 0;
uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black;
uint32_t bg = black;
uint32_t cols[2];
uint8_t dat2, pattern;
uint32_t ink0 = 0, ink1 = 0;
/* Switch between internal plasma and external CRT display. */
if (cpq_st_display_internal != -1 && cpq_st_display_internal != self->internal_monitor) {
if ((cpq_st_display_internal != -1) && (cpq_st_display_internal != self->internal_monitor)) {
self->internal_monitor = cpq_st_display_internal;
compaq_plasma_recalctimings(self);
}
/* graphic mode and not mode 40h */
if (!self->internal_monitor && !(self->port_23c6 & 1)) {
cga_poll(&self->cga);
return;
}
if (!self->linepos) {
timer_advance_u64(&self->cga.timer, self->dispofftime);
/* mode 40h or text mode */
if (!self->cga.linepos) {
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
self->cga.cgastat |= 1;
self->linepos = 1;
if (self->dispon) {
if (self->displine == 0)
self->cga.linepos = 1;
if (self->cga.cgadispon) {
if (self->cga.displine == 0) {
video_wait_for_buffer();
}
if (self->cga.cgamode & 2) {
if (self->cga.cgamode & 0x10) {
/* 640x400 mode */
if (self->port_23c6 & 1) /* 640*400 */ {
addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
} else {
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
}
for (x = 0; x < 80; x++) {
dat2 = self->cga.vram[(addr & 0x7FFF)];
addr++;
/* Graphics */
if (self->cga.cgamode & 0x02) {
if (self->cga.cgamode & 0x10)
compaq_plasma_cgaline6(self);
for (c = 0; c < 8; c++) {
ink = (dat2 & 0x80) ? fg : bg;
if (!(self->cga.cgamode & 8))
ink = black;
((uint32_t *) buffer32->line[self->cga.displine])[x * 8 + c] = ink;
dat2 <<= 1;
}
}
} else {
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
for (x = 0; x < 80; x++) {
dat2 = self->cga.vram[(addr & 0x7fff)];
addr++;
for (c = 0; c < 4; c++) {
pattern = (dat2 & 0xC0) >> 6;
if (!(self->cga.cgamode & 8))
pattern = 0;
switch (pattern & 3) {
case 0:
ink0 = ink1 = black;
break;
case 1:
if (self->cga.displine & 1) {
ink0 = black;
ink1 = black;
} else {
ink0 = amber;
ink1 = black;
}
break;
case 2:
if (self->cga.displine & 1) {
ink0 = black;
ink1 = amber;
} else {
ink0 = amber;
ink1 = black;
}
break;
case 3:
ink0 = ink1 = amber;
break;
}
buffer32->line[self->cga.displine][x * 8 + 2 * c] = ink0;
buffer32->line[self->cga.displine][x * 8 + 2 * c + 1] = ink1;
dat2 <<= 2;
}
}
}
} else if (self->cga.cgamode & 1) {
/* 80-col */
sc = self->cga.displine & 0x0f;
addr = ((ma & ~1) + (self->cga.displine >> 4) * 80) * 2;
ma += (self->cga.displine >> 4) * 80;
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
cursorline = 0;
else
compaq_plasma_cgaline4(self);
} else if (self->cga.cgamode & 0x01) /* High-res text */
compaq_plasma_text80(self);
else
compaq_plasma_text40(self);
cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc);
/* for each text column */
for (x = 0; x < 80; x++) {
/* video output enabled */
if (self->cga.cgamode & 8) {
chr = self->cga.vram[(addr + 2 * x) & 0x7fff];
attr = self->cga.vram[(addr + 2 * x + 1) & 0x7fff];
} else
chr = attr = 0;
/* check if cursor has to be drawn */
drawcursor = ((ma == ca) && cursorline && self->cga.cursoron);
underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6));
if (underline) {
/* set forecolor to white */
attr |= 7;
}
blink = 0;
/* blink active */
if (self->cga.cgamode & 0x20) {
cols[1] = blinkcols[attr][1];
cols[0] = blinkcols[attr][0];
/* attribute 7 active and not cursor */
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) {
/* set blinking */
cols[1] = cols[0];
blink = 1;
}
} else {
/* Set intensity bit */
cols[1] = normcols[attr][1];
cols[0] = normcols[attr][0];
blink = (attr & 0x80) * 8 + 7 + 16;
}
/* character underline active and 7th row of pixels in character height being drawn */
if (underline && (sc == 7)) {
/* for each pixel in character width */
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1];
} else if (drawcursor) {
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
} else {
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
++ma;
}
} else { /* 40-col */
sc = self->cga.displine & 0x0f;
addr = ((ma & ~1) + (self->cga.displine >> 4) * 40) * 2;
ma += (self->cga.displine >> 4) * 40;
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
cursorline = 0;
else
cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc);
for (x = 0; x < 40; x++) {
if (self->cga.cgamode & 8) {
chr = self->cga.vram[(addr + 2 * x) & 0x7fff];
attr = self->cga.vram[(addr + 2 * x + 1) & 0x7fff];
} else {
chr = attr = 0;
}
drawcursor = ((ma == ca) && cursorline && self->cga.cursoron);
underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6));
if (underline) {
/* set forecolor to white */
attr |= 7;
}
blink = 0;
/* blink active */
if (self->cga.cgamode & 0x20) {
cols[1] = blinkcols[attr][1];
cols[0] = blinkcols[attr][0];
/* attribute 7 active and not cursor */
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) {
/* set blinking */
cols[1] = cols[0];
blink = 1;
}
} else {
/* Set intensity bit */
cols[1] = normcols[attr][1];
cols[0] = normcols[attr][0];
blink = (attr & 0x80) * 8 + 7 + 16;
}
/* character underline active and 7th row of pixels in character height being drawn */
if (underline && (sc == 7)) {
/* for each pixel in character width */
for (c = 0; c < 8; c++)
buffer32->line[self->cga.displine][(x << 4) + (c * 2)] = buffer32->line[self->cga.displine][(x << 4) + (c * 2) + 1] = mdaattr[attr][blink][1];
} else if (drawcursor) {
for (c = 0; c < 8; c++) {
buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
}
} else {
for (c = 0; c < 8; c++) {
buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
}
++ma;
}
}
}
self->displine++;
self->cga.displine++;
/* Hardcode a fixed refresh rate and VSYNC timing */
if (self->displine == 400) { /* Start of VSYNC */
if (self->cga.displine == 400) { /* Start of VSYNC */
self->cga.cgastat |= 8;
self->dispon = 0;
self->cga.cgadispon = 0;
}
if (self->displine == 416) { /* End of VSYNC */
self->displine = 0;
if (self->cga.displine == 416) { /* End of VSYNC */
self->cga.displine = 0;
self->cga.cgastat &= ~8;
self->dispon = 1;
self->cga.cgadispon = 1;
}
} else {
if (self->dispon)
if (self->cga.cgadispon)
self->cga.cgastat &= ~1;
timer_advance_u64(&self->cga.timer, self->dispontime);
self->linepos = 0;
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
self->cga.linepos = 0;
if (self->displine == 400) {
if (self->cga.displine == 400) {
/* Hardcode 640x400 window size */
if ((640 != xsize) || (400 != ysize) || video_force_resize_get()) {
xsize = 640;
@@ -515,14 +519,41 @@ compaq_plasma_poll(void *p)
video_bpp = 1;
else
video_bpp = 2;
} else
video_bpp = 0;
self->cga.cgablink++;
}
}
}
static void
compaq_plasma_mdaattr_rebuild(void)
{
int c;
for (c = 0; c < 256; c++) {
mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16;
if (c & 8)
mdaattr[c][0][1] = 15 + 16;
else
mdaattr[c][0][1] = 7 + 16;
}
mdaattr[0x70][0][1] = 16;
mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15;
mdaattr[0xF0][0][1] = 16;
mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15;
mdaattr[0x78][0][1] = 16 + 7;
mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15;
mdaattr[0xF8][0][1] = 16 + 7;
mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15;
mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16;
mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16;
mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16;
mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16;
}
static void
compaq_plasma_recalcattrs(compaq_plasma_t *self)
{
@@ -537,10 +568,10 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self)
* are bold */
/* Set up colours */
amber = makecol(0xff, 0x7D, 0x00);
black = makecol(0x64, 0x19, 0x00);
amber = makecol(0xff, 0x7d, 0x00);
black = makecol(0x64, 0x0c, 0x00);
/* Initialise the attribute mapping. Start by defaulting everything
/* Initialize the attribute mapping. Start by defaulting everything
* to black on amber, and with bold set by bit 3 */
for (n = 0; n < 256; n++) {
blinkcols[n][0] = normcols[n][0] = amber;
@@ -607,36 +638,37 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self)
static void *
compaq_plasma_init(const device_t *info)
{
int display_type;
compaq_plasma_t *self = malloc(sizeof(compaq_plasma_t));
memset(self, 0, sizeof(compaq_plasma_t));
display_type = device_get_config_int("display_type");
self->cga.composite = (display_type != CGA_RGB);
self->cga.revision = device_get_config_int("composite_type");
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma);
loadfont_ex("roms/machines/portableiii/K Combined.bin", 1, 0x4bb2);
self->vram = malloc(0x8000);
self->cga.composite = 0;
self->cga.revision = 0;
self->cga.vram = malloc(0x8000);
self->internal_monitor = 1;
cga_comp_init(self->cga.revision);
timer_add(&self->cga.timer, compaq_plasma_poll, self, 1);
mem_mapping_add(&self->plasma_mapping, 0xb8000, 0x08000, compaq_plasma_read, NULL, NULL, compaq_plasma_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self);
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, compaq_plasma_read, NULL, NULL, compaq_plasma_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self);
io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
io_sethandler(0x13c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
io_sethandler(0x1bc6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
io_sethandler(0x23c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
/* Default attribute mapping is 4 */
self->attrmap = 4;
compaq_plasma_recalcattrs(self);
self->cga.cgastat = 0xF4;
self->cga.vram = self->vram;
self->cga.cgastat = 0xf4;
overscan_x = overscan_y = 16;
self->cga.rgb_type = device_get_config_int("rgb_type");
cga_palette = (self->cga.rgb_type << 1);
cgapal_rebuild();
compaq_plasma_mdaattr_rebuild();
return self;
}
@@ -646,8 +678,7 @@ compaq_plasma_close(void *p)
{
compaq_plasma_t *self = (compaq_plasma_t *) p;
free(self->vram);
free(self->cga.vram);
free(self);
}
@@ -661,38 +692,10 @@ compaq_plasma_speed_changed(void *p)
const device_config_t compaq_plasma_config[] = {
// clang-format off
{
.name = "display_type",
.description = "Display type",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = CGA_RGB,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "RGB", .value = CGA_RGB },
{ .description = "Composite", .value = CGA_COMPOSITE },
{ .description = "" }
}
},
{
.name = "composite_type",
.description = "Composite type",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = COMPOSITE_OLD,
.file_filter = "",
.spinner = { 0 },
{
{ .description = "Old", .value = COMPOSITE_OLD },
{ .description = "New", .value = COMPOSITE_NEW },
{ .description = "" }
}
},
{
.name = "rgb_type",
.description = "RGB type",
.type = CONFIG_SELECTION,
.description = "RGB type",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = "",
@@ -702,7 +705,6 @@ const device_config_t compaq_plasma_config[] = {
{ .description = "Green Monochrome", .value = 1 },
{ .description = "Amber Monochrome", .value = 2 },
{ .description = "Gray Monochrome", .value = 3 },
{ .description = "Color (no brown)", .value = 4 },
{ .description = "" }
}
},
@@ -781,26 +783,36 @@ write_raml(uint32_t addr, uint32_t val, void *priv)
static void
machine_at_compaq_init(const machine_t *model, int type)
{
if (type != COMPAQ_DESKPRO386)
compaq_machine_type = type;
if ((type != COMPAQ_DESKPRO386) && (type != COMPAQ_DESKPRO386_01_1988))
mem_remap_top(384);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000,
read_ram, read_ramw, read_raml,
write_ram, write_ramw, write_raml,
0xa0000 + ram, MEM_MAPPING_INTERNAL, NULL);
if ((type == COMPAQ_DESKPRO386) || (type == COMPAQ_DESKPRO386_01_1988) || (type == COMPAQ_PORTABLEIII386))
mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000,
read_ram, read_ramw, read_raml,
write_ram, write_ramw, write_raml,
0xa0000 + ram, MEM_MAPPING_EXTERNAL, NULL);
else
mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000,
read_ram, read_ramw, read_raml,
write_ram, write_ramw, write_raml,
0xa0000 + ram, MEM_MAPPING_INTERNAL, NULL);
video_reset(gfxcard[0]);
switch (type) {
case COMPAQ_PORTABLEII:
machine_at_init(model);
break;
case COMPAQ_PORTABLEIII:
if (gfxcard[0] == VID_INTERNAL)
device_add(&compaq_plasma_device);
machine_at_init(model);
break;
case COMPAQ_PORTABLEIII386:
@@ -808,15 +820,17 @@ machine_at_compaq_init(const machine_t *model, int type)
device_add(&ide_isa_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&compaq_plasma_device);
machine_at_init(model);
break;
case COMPAQ_DESKPRO386:
case COMPAQ_DESKPRO386_01_1988:
if (hdc_current == 1)
device_add(&ide_isa_device);
machine_at_common_init(model);
device_add(&keyboard_at_compaq_device);
break;
}
machine_at_init(model);
}
int
@@ -841,9 +855,9 @@ machine_at_portableiii_init(const machine_t *model)
{
int ret;
ret = bios_load_interleavedr("roms/machines/portableiii/Compaq Portable III - BIOS - 106779-002 - Even.bin",
"roms/machines/portableiii/Compaq Portable III - BIOS - 106778-002 - Odd.bin",
0x000f8000, 65536, 0);
ret = bios_load_linearr("roms/machines/portableiii/K Combined.bin",
0x000f8000, 65536, 0);
if (bios_only || !ret)
return ret;
@@ -858,9 +872,8 @@ machine_at_portableiii386_init(const machine_t *model)
{
int ret;
ret = bios_load_interleavedr("roms/machines/portableiii/Compaq Portable III - BIOS - 106779-002 - Even.bin",
"roms/machines/portableiii/Compaq Portable III - BIOS - 106778-002 - Odd.bin",
0x000f8000, 65536, 0);
ret = bios_load_linearr("roms/machines/portableiii/K Combined.bin",
0x000f8000, 65536, 0);
if (bios_only || !ret)
return ret;
@@ -870,14 +883,13 @@ machine_at_portableiii386_init(const machine_t *model)
return ret;
}
#if defined(DEV_BRANCH) && defined(USE_DESKPRO386)
int
machine_at_deskpro386_init(const machine_t *model)
{
int ret;
ret = bios_load_linearr("roms/machines/deskpro386/1986-09-04-HI.json.bin",
0x000fc000, 65536, 0);
0x000f8000, 65536, 0);
if (bios_only || !ret)
return ret;
@@ -886,4 +898,19 @@ machine_at_deskpro386_init(const machine_t *model)
return ret;
}
#endif
int
machine_at_deskpro386_01_1988_init(const machine_t *model)
{
int ret;
ret = bios_load_linearr("roms/machines/deskpro386/1988-01-28.json.bin",
0x000f8000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_compaq_init(model, COMPAQ_DESKPRO386_01_1988);
return ret;
}

View File

@@ -2588,8 +2588,8 @@ const machine_t machines[] = {
.cpu = {
.package = CPU_PKG_286,
.block = CPU_BLOCK_NONE,
.min_bus = 6000000,
.max_bus = 8000000,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -2905,8 +2905,8 @@ const machine_t machines[] = {
.cpu = {
.package = CPU_PKG_286,
.block = CPU_BLOCK_NONE,
.min_bus = 6000000,
.max_bus = 8000000,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -2944,8 +2944,8 @@ const machine_t machines[] = {
.cpu = {
.package = CPU_PKG_286,
.block = CPU_BLOCK_NONE,
.min_bus = 6000000,
.max_bus = 8000000,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
@@ -4671,9 +4671,8 @@ const machine_t machines[] = {
.net_device = NULL
},
/* Uses Compaq KBC firmware. */
#if defined(DEV_BRANCH) && defined(USE_DESKPRO386)
{
.name = "[ISA] Compaq Deskpro 386",
.name = "[ISA] Compaq Deskpro 386 (September 1986)",
.internal_name = "deskpro386",
.type = MACHINE_TYPE_386DX,
.chipset = MACHINE_CHIPSET_DISCRETE,
@@ -4693,13 +4692,51 @@ const machine_t machines[] = {
.max_multi = 0
},
.bus_flags = MACHINE_AT,
.flags = MACHINE_IDE | MACHINE_APM,
.flags = MACHINE_IDE,
.ram = {
.min = 1024,
.max = 14336,
.step = 1024
.min = 640,
.max = 16384,
.step = 128
},
.nvrmask = 127,
.nvrmask = 63,
.kbc_device = NULL,
.kbc_p1 = 0,
.gpio = 0,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[ISA] Compaq Deskpro 386 (January 1988)",
.internal_name = "deskpro386_01_1988",
.type = MACHINE_TYPE_386DX,
.chipset = MACHINE_CHIPSET_DISCRETE,
.init = machine_at_deskpro386_01_1988_init,
.pad = 0,
.pad0 = 0,
.pad1 = MACHINE_AVAILABLE,
.pad2 = 0,
.cpu = {
.package = CPU_PKG_386DX,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_AT,
.flags = MACHINE_IDE,
.ram = {
.min = 640,
.max = 16384,
.step = 128
},
.nvrmask = 63,
.kbc_device = NULL,
.kbc_p1 = 0,
.gpio = 0,
@@ -4710,7 +4747,6 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
#endif /* defined(DEV_BRANCH) && defined(USE_DESKPRO386) */
{
.name = "[ISA] Compaq Portable III (386)",
.internal_name = "portableiii386",
@@ -4732,7 +4768,7 @@ const machine_t machines[] = {
.max_multi = 0
},
.bus_flags = MACHINE_AT,
.flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM,
.flags = MACHINE_IDE | MACHINE_VIDEO,
.ram = {
.min = 1024,
.max = 14336,

View File

@@ -14,4 +14,4 @@
#
add_library(mem OBJECT 815ep_spd_hack.c catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c rom.c
smram.c spd.c sst_flash.c)
row.c smram.c spd.c sst_flash.c)

343
src/mem/row.c Normal file
View File

@@ -0,0 +1,343 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running 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.
*
* DRAM row handling.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2020 Miran Grca.
*/
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include "x86_ops.h"
#include "x86.h"
#include <86box/config.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/spd.h>
#include <86box/row.h>
/* 0 1 2 3 4 5 6 7 */
static uint8_t rows_num, rows_default,
rows_bits;
static uint32_t row_unit;
static uint8_t drb_defaults[16];
static row_t *rows;
static uint8_t
row_read(uint32_t addr, void *priv)
{
row_t *dev = (row_t *) priv;
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
addreadlookup(mem_logical_addr, new_addr);
return dev->buf[new_addr];
}
static uint16_t
row_readw(uint32_t addr, void *priv)
{
row_t *dev = (row_t *) priv;
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
addreadlookup(mem_logical_addr, new_addr);
return *(uint16_t *) &(dev->buf[new_addr]);
}
static uint32_t
row_readl(uint32_t addr, void *priv)
{
row_t *dev = (row_t *) priv;
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
addreadlookup(mem_logical_addr, new_addr);
return *(uint32_t *) &(dev->buf[new_addr]);
}
static void
row_write(uint32_t addr, uint8_t val, void *priv)
{
row_t *dev = (row_t *) priv;
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
addwritelookup(mem_logical_addr, new_addr);
mem_write_ramb_page(new_addr, val, &pages[addr >> 12]);
}
static void
row_writew(uint32_t addr, uint16_t val, void *priv)
{
row_t *dev = (row_t *) priv;
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
addwritelookup(mem_logical_addr, new_addr);
mem_write_ramw_page(new_addr, val, &pages[addr >> 12]);
}
static void
row_writel(uint32_t addr, uint32_t val, void *priv)
{
row_t *dev = (row_t *) priv;
uint32_t new_addr = ((addr - dev->host_base) & dev->ram_mask) + dev->ram_base;
addwritelookup(mem_logical_addr, new_addr);
mem_write_raml_page(new_addr, val, &pages[addr >> 12]);
}
void
row_allocate(uint8_t row_id, uint8_t set)
{
uint32_t c, offset;
/* Do nothing if size is either zero or invalid. */
if ((rows[row_id].host_size == 0x00000000) || (rows[row_id].host_size == 0xffffffff))
return;
if (rows[row_id].ram_size == 0x00000000)
return;
for (c = (rows[row_id].host_base >> 12); c < ((rows[row_id].host_base + rows[row_id].host_size) >> 12); c++) {
offset = c - (rows[row_id].host_base >> 12);
pages[c].mem = set ? (rows[row_id].buf + rows[row_id].ram_base + ((offset << 12) & rows[row_id].ram_mask)) : page_ff;
pages[c].write_b = set ? mem_write_ramb_page : NULL;
pages[c].write_w = set ? mem_write_ramw_page : NULL;
pages[c].write_l = set ? mem_write_raml_page : NULL;
#ifdef USE_NEW_DYNAREC
pages[c].evict_prev = EVICT_NOT_IN_LIST;
pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64];
pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64];
#endif
}
if (rows[row_id].host_base >= 0x00100000) {
mem_set_mem_state_both(rows[row_id].host_base, rows[row_id].host_base + rows[row_id].host_size,
set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
} else {
if (0x000a0000 > rows[row_id].host_base) {
mem_set_mem_state_both(rows[row_id].host_base, 0x000a0000 - rows[row_id].host_base,
set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
}
if ((rows[row_id].host_base + rows[row_id].host_size) > 0x00100000) {
mem_set_mem_state_both(0x00100000, (rows[row_id].host_base + rows[row_id].host_size) - 0x00100000,
set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
}
}
if (set) {
mem_mapping_set_addr(&rows[row_id].mapping, rows[row_id].host_base, rows[row_id].host_size);
mem_mapping_set_exec(&rows[row_id].mapping, rows[row_id].buf + rows[row_id].ram_base);
mem_mapping_set_mask(&rows[row_id].mapping, rows[row_id].ram_mask);
if ((rows[row_id].host_base == rows[row_id].ram_base) && (rows[row_id].host_size == rows[row_id].ram_size)) {
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram,mem_read_ramw,mem_read_raml,
mem_write_ram,mem_write_ramw,mem_write_raml);
#else
if (rows[row_id].buf == ram2) {
mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram_2gb,mem_read_ram_2gbw,mem_read_ram_2gbl,
mem_write_ram,mem_write_ramw,mem_write_raml);
} else {
mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram,mem_read_ramw,mem_read_raml,
mem_write_ram,mem_write_ramw,mem_write_raml);
}
#endif
} else {
mem_mapping_set_handler(&rows[row_id].mapping, row_read, row_readw, row_readl,
row_write, row_writew, row_writel);
}
} else
mem_mapping_disable(&rows[row_id].mapping);
}
void
row_disable(uint8_t row_id)
{
row_allocate(row_id, 0);
}
void
row_set_boundary(uint8_t row_id, uint32_t boundary)
{
if (row_id >= rows_num)
return;
boundary &= ((1 << rows_bits) - 1);
rows[row_id].host_size = boundary * row_unit;
if (row_id == 0)
rows[row_id].host_base = 0x00000000;
else {
rows[row_id].host_base = rows[row_id - 1].boundary * row_unit;
if (rows[row_id - 1].boundary > boundary)
rows[row_id].host_size = 0x00000000;
else
rows[row_id].host_size -= rows[row_id].host_base;
}
rows[row_id].boundary = boundary;
row_allocate(row_id, 1);
}
void
row_reset(void *priv)
{
int i;
uint32_t boundary, shift;
for (i = (rows_num - 1); i >= 0; i--)
row_disable(i);
for (i = 0; i < rows_num; i++) {
shift = (i & 1) << 2;
boundary = ((uint32_t) drb_defaults[i]) + (((((uint32_t) drb_defaults[(i >> 1) + 8]) >> shift) & 0xf) << 8);
row_set_boundary(i, boundary);
}
}
void
row_close(void *priv)
{
free(rows);
rows = NULL;
}
void *
row_init(const device_t *info)
{
uint32_t cur_drb = 0, cur_drbe = 0;
uint32_t last_drb = 0, last_drbe = 0;
uint8_t phys_drbs[16];
int i, max = info->local & 0xff;
int c;
uint32_t shift, drb;
uint32_t boundary, mask;
row_t *new_rows = NULL;
rows_bits = ((info->local >> 24) & 0xff);
mask = (1 << rows_bits) - 1;
row_unit = ((info->local >> 8) & 0xff);
memset(phys_drbs, 0x00, 16);
spd_write_drbs(phys_drbs, 0x00, max, row_unit);
row_unit <<= 20;
rows_default = (info->local >> 16) & 0xff;
memset(drb_defaults, 0x00, 16);
for (i = 0; i < 8; i++)
drb_defaults[i] = rows_default;
new_rows = calloc(max + 1, sizeof(row_t));
rows_num = max + 1;
rows = new_rows;
mem_mapping_disable(&ram_low_mapping);
mem_mapping_disable(&ram_mid_mapping);
mem_mapping_disable(&ram_high_mapping);
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
if (mem_size > 1048576)
mem_mapping_disable(&ram_2gb_mapping);
#endif
for (c = 0; c < pages_sz; c++) {
pages[c].mem = page_ff;
pages[c].write_b = NULL;
pages[c].write_w = NULL;
pages[c].write_l = NULL;
#ifdef USE_NEW_DYNAREC
pages[c].evict_prev = EVICT_NOT_IN_LIST;
pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64];
pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64];
#endif
}
/* Set all memory space above the default allocated area to external. */
boundary = ((uint32_t) rows_default) * row_unit;
mem_set_mem_state_both(boundary, (mem_size << 10) - boundary, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
for (i = 0; i <= max; i++) {
cur_drb = phys_drbs[i];
cur_drbe = phys_drbs[(i >> 1) + 8];
shift = (i & 1) << 2;
drb = (cur_drb & mask) + (((cur_drbe >> shift) & 0x03) << 8);
rows[i].ram_size = drb * row_unit;
shift = ((i - 1) & 1) << 2;
drb = (last_drb & mask) + (((last_drbe >> shift) & 0x03) << 8);
rows[i].ram_base = drb * row_unit;
rows[i].ram_size -= rows[i].ram_base;
rows[i].buf = ram;
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
if (rows[i].ram_base >= (1 << 30)) {
rows[i].ram_base -= (1 << 30);
rows[i].buf = ram2;
}
#endif
rows[i].ram_mask = rows[i].ram_size - 1;
mem_mapping_add(&rows[i].mapping, rows[i].ram_base, rows[i].ram_size,
row_read, row_readw, row_readl,
row_write, row_writew, row_writel,
rows[i].buf + rows[i].ram_base, MEM_MAPPING_INTERNAL, &(rows[i]));
mem_mapping_disable(&rows[i].mapping);
shift = (i & 1) << 2;
boundary = ((uint32_t) drb_defaults[i]) + ((((uint32_t) drb_defaults[(i >> 1) + 8]) >> shift) << 8);
row_set_boundary(i, boundary);
last_drb = cur_drb;
last_drbe = cur_drbe;
}
flushmmucache();
return new_rows;
}
/* NOTE: NOT const, so that we can patch it at init. */
device_t row_device = {
.name = "DRAM Rows",
.internal_name = "dram_rows",
.flags = DEVICE_AT,
.local = 0x0000,
.init = row_init,
.close = row_close,
.reset = row_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -401,7 +401,7 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit
}
}
/* Needed for 430LX. */
/* Needed for 430NX. */
void
spd_write_drbs_with_ext(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
{
@@ -447,8 +447,9 @@ spd_write_drbs_with_ext(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t
row_val += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
regs[drb] = row_val & 0xff;
drb = reg_min + 8 + (row >> 1);
shift = (row & 0x01) << 3;
regs[drb] = (((row_val & 0xfff) >> 8) << shift);
shift = (row & 0x01) << 2;
/* Limit to 1 GB space, per the 430NX datasheet. */
regs[drb] = (regs[drb] & ~(0xf << shift)) | (((row_val >> 8) & 3) << shift);
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
}
}

View File

@@ -20,4 +20,15 @@ if(APPLE)
if (NOT GHOSTSCRIPT_LIB)
message(WARNING "Could not find ghostscript. The library will not be bundled and any related features will not work.")
endif()
endif ()
endif()
find_package(PkgConfig REQUIRED)
pkg_check_modules(FREETYPE REQUIRED IMPORTED_TARGET freetype2)
target_link_libraries(86Box PkgConfig::FREETYPE)
if(STATIC_BUILD)
if(QT)
# Qt provides its own version of harfbuzz which leads to duplicated symbols.
target_link_options(86Box PRIVATE "LINKER:--allow-multiple-definition")
endif()
target_link_libraries(86Box -static ${FREETYPE_STATIC_LIBRARIES})
endif()

View File

@@ -65,7 +65,6 @@
#include <86box/pit.h>
#include <86box/path.h>
#include <86box/plat.h>
#include <86box/plat_dynld.h>
#include <86box/ui.h>
#include <86box/lpt.h>
#include <86box/video.h>
@@ -85,45 +84,8 @@
#define PAGE_CPI 10.0 /* standard 10 cpi */
#define PAGE_LPI 6.0 /* standard 6 lpi */
#ifdef _WIN32
# define PATH_FREETYPE_DLL "freetype.dll"
#elif defined __APPLE__
# define PATH_FREETYPE_DLL "libfreetype.6.dylib"
#else
# define PATH_FREETYPE_DLL "libfreetype.so.6"
#endif
/* FreeType library handles - global so they can be shared. */
FT_Library ft_lib = NULL;
void *ft_handle = NULL;
static int (*ft_Init_FreeType)(FT_Library *alibrary);
static int (*ft_Done_Face)(FT_Face face);
static int (*ft_New_Face)(FT_Library library, const char *filepathname,
FT_Long face_index, FT_Face *aface);
static int (*ft_Set_Char_Size)(FT_Face face, FT_F26Dot6 char_width,
FT_F26Dot6 char_height,
FT_UInt horz_resolution,
FT_UInt vert_resolution);
static int (*ft_Set_Transform)(FT_Face face, FT_Matrix *matrix,
FT_Vector *delta);
static int (*ft_Get_Char_Index)(FT_Face face, FT_ULong charcode);
static int (*ft_Load_Glyph)(FT_Face face, FT_UInt glyph_index,
FT_Int32 load_flags);
static int (*ft_Render_Glyph)(FT_GlyphSlot slot,
FT_Render_Mode render_mode);
static dllimp_t ft_imports[] = {
{"FT_Init_FreeType", &ft_Init_FreeType },
{ "FT_New_Face", &ft_New_Face },
{ "FT_Done_Face", &ft_Done_Face },
{ "FT_Set_Char_Size", &ft_Set_Char_Size },
{ "FT_Set_Transform", &ft_Set_Transform },
{ "FT_Get_Char_Index", &ft_Get_Char_Index},
{ "FT_Load_Glyph", &ft_Load_Glyph },
{ "FT_Render_Glyph", &ft_Render_Glyph },
{ NULL, NULL }
};
FT_Library ft_lib = NULL;
/* The fonts. */
#define FONT_DEFAULT 0
@@ -544,7 +506,7 @@ update_font(escp_t *dev)
/* Release current font if we have one. */
if (dev->fontface)
ft_Done_Face(dev->fontface);
FT_Done_Face(dev->fontface);
if (dev->print_quality == QUALITY_DRAFT)
fn = FONT_FILE_DOTMATRIX;
@@ -580,7 +542,7 @@ update_font(escp_t *dev)
escp_log("Temp file=%s\n", path);
/* Load the new font. */
if (ft_New_Face(ft_lib, path, 0, &dev->fontface)) {
if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) {
escp_log("ESC/P: unable to load font '%s'\n", path);
dev->fontface = NULL;
}
@@ -626,7 +588,7 @@ update_font(escp_t *dev)
dev->actual_cpi /= 2.0 / 3.0;
}
ft_Set_Char_Size(dev->fontface,
FT_Set_Char_Size(dev->fontface,
(uint16_t) (hpoints * 64), (uint16_t) (vpoints * 64),
dev->dpi, dev->dpi);
@@ -636,7 +598,7 @@ update_font(escp_t *dev)
matrix.xy = (FT_Fixed) (0.20 * 0x10000L);
matrix.yx = 0;
matrix.yy = 0x10000L;
ft_Set_Transform(dev->fontface, &matrix, 0);
FT_Set_Transform(dev->fontface, &matrix, 0);
}
}
@@ -1611,9 +1573,9 @@ handle_char(escp_t *dev, uint8_t ch)
/* ok, so we need to print the character now */
if (ft_lib) {
char_index = ft_Get_Char_Index(dev->fontface, dev->curr_cpmap[ch]);
ft_Load_Glyph(dev->fontface, char_index, FT_LOAD_DEFAULT);
ft_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL);
char_index = FT_Get_Char_Index(dev->fontface, dev->curr_cpmap[ch]);
FT_Load_Glyph(dev->fontface, char_index, FT_LOAD_DEFAULT);
FT_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL);
}
pen_x = PIXX + dev->fontface->glyph->bitmap_left;
@@ -1986,23 +1948,12 @@ read_status(void *priv)
static void *
escp_init(void *lpt)
{
const char *fn = PATH_FREETYPE_DLL;
escp_t *dev;
/* Dynamically load FreeType. */
if (ft_handle == NULL) {
ft_handle = dynld_module(fn, ft_imports);
if (ft_handle == NULL) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132);
return (NULL);
}
}
escp_t *dev;
/* Initialize FreeType. */
if (ft_lib == NULL) {
if (ft_Init_FreeType(&ft_lib)) {
if (FT_Init_FreeType(&ft_lib)) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132);
dynld_close(ft_lib);
ft_lib = NULL;
return (NULL);
}

View File

@@ -51,7 +51,9 @@
#elif defined __APPLE__
# define PATH_GHOSTSCRIPT_DLL "libgs.dylib"
#else
# define PATH_GHOSTSCRIPT_DLL "libgs.so.9"
# define PATH_GHOSTSCRIPT_DLL "libgs.so.9"
# define PATH_GHOSTSCRIPT_DLL_ALT1 "libgs.so.10"
# define PATH_GHOSTSCRIPT_DLL_ALT2 "libgs.so"
#endif
#define POSTSCRIPT_BUFFER_LENGTH 65536
@@ -341,12 +343,21 @@ ps_init(void *lpt)
/* Try loading the DLL. */
ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports);
if (ghostscript_handle == NULL)
#ifdef PATH_GHOSTSCRIPT_DLL_ALT1
if (ghostscript_handle == NULL) {
ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL_ALT1, ghostscript_imports);
# ifdef PATH_GHOSTSCRIPT_DLL_ALT2
if (ghostscript_handle == NULL)
ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL_ALT2, ghostscript_imports);
# endif
}
#endif
if (ghostscript_handle == NULL) {
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2115, (wchar_t *) IDS_2133);
else {
if (gsapi_revision(&rev, sizeof(rev)) == 0)
} else {
if (gsapi_revision(&rev, sizeof(rev)) == 0) {
pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate);
else {
} else {
dynld_close(ghostscript_handle);
ghostscript_handle = NULL;
}

View File

@@ -127,3 +127,9 @@ static std::array<uint32_t, 127> cocoa_keycodes = { /* key names in parentheses
0x150, /* DownArrow */
0x148, /* UpArrow */
};
// https://developer.apple.com/documentation/appkit/nseventmodifierflags/
qint32 NSEventModifierFlagCommand = 1 << 20;
qint32 nvk_Delete = 0x75;
qint32 nvk_Insert = 0x72;

View File

@@ -31,6 +31,12 @@ FileField::FileField(QWidget *parent)
fileName_ = ui->label->text();
emit fileSelected(ui->label->text(), true);
});
connect(ui->label, &QLineEdit::textChanged, this, [this]() {
fileName_ = ui->label->text();
emit fileTextEntered(ui->label->text(), true);
});
this->setFixedWidth(this->sizeHint().width() + ui->pushButton->sizeHint().width());
}

View File

@@ -19,12 +19,14 @@ public:
void setFilter(const QString &filter) { filter_ = filter; }
QString selectedFilter() const { return selectedFilter_; }
void setselectedFilter(const QString &selectedFilter) { selectedFilter_ = selectedFilter; }
void setCreateFile(bool createFile) { createFile_ = createFile; }
bool createFile() { return createFile_; }
signals:
void fileSelected(const QString &fileName, bool precheck = false);
void fileTextEntered(const QString &fileName, bool precheck = false);
private slots:
void on_pushButton_clicked();

View File

@@ -84,6 +84,13 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent)
ui->lineEditSize->setValidator(new QIntValidator());
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
filters = QStringList({ tr("Raw image") % util::DlgFilter({ "img" }, true),
tr("HDI image") % util::DlgFilter({ "hdi" }, true),
tr("HDX image") % util::DlgFilter({ "hdx" }, true),
tr("Fixed-size VHD") % util::DlgFilter({ "vhd" }, true),
tr("Dynamic-size VHD") % util::DlgFilter({ "vhd" }, true),
tr("Differencing VHD") % util::DlgFilter({ "vhd" }, true) });
if (existing) {
ui->fileField->setFilter(tr("Hard disk images") % util::DlgFilter({ "hd?", "im?", "vhd" }) % tr("All files") % util::DlgFilter({ "*" }, true));
@@ -99,24 +106,26 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent)
connect(ui->fileField, &FileField::fileSelected, this, &HarddiskDialog::onExistingFileSelected);
} else {
QStringList filters({ tr("Raw image") % util::DlgFilter({ "img" }, true),
tr("HDI image") % util::DlgFilter({ "hdi" }, true),
tr("HDX image") % util::DlgFilter({ "hdx" }, true),
tr("Fixed-size VHD") % util::DlgFilter({ "vhd" }, true),
tr("Dynamic-size VHD") % util::DlgFilter({ "vhd" }, true),
tr("Differencing VHD") % util::DlgFilter({ "vhd" }, true) });
ui->fileField->setFilter(filters.join(";;"));
setWindowTitle(tr("Add New Hard Disk"));
ui->fileField->setCreateFile(true);
connect(ui->fileField, &FileField::fileSelected, this, [this, filters] {
// Enable the OK button as long as the filename length is non-zero
connect(ui->fileField, &FileField::fileTextEntered, this, [this] {
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled((this->fileName().length() > 0));
});
connect(ui->fileField, &FileField::fileSelected, this, [this] {
int filter = filters.indexOf(ui->fileField->selectedFilter());
if (filter > -1)
ui->comboBoxFormat->setCurrentIndex(filter);
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
});
// Set the default format to Dynamic-size VHD. Do it last after everything is set up
// so the currentIndexChanged signal can do what is needed
ui->comboBoxFormat->setCurrentIndex(DEFAULT_DISK_FORMAT);
ui->fileField->setselectedFilter(filters.value(DEFAULT_DISK_FORMAT));
}
}
@@ -179,6 +188,7 @@ HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index)
ui->comboBoxBlockSize->show();
ui->labelBlockSize->show();
}
ui->fileField->setselectedFilter(filters.value(index));
}
/* If the disk geometry requested in the 86Box GUI is not compatible with the internal VHD geometry,

View File

@@ -52,6 +52,11 @@ private:
bool disallowSizeModifications = false;
QStringList filters;
// "Dynamic-size VHD" is number 4 in the `filters` list and the
// comboBoxFormat model
const uint8_t DEFAULT_DISK_FORMAT = 4;
bool checkAndAdjustCylinders();
bool checkAndAdjustHeads();
bool checkAndAdjustSectors();

View File

@@ -1092,6 +1092,11 @@ MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event)
if (mac_iso_swap)
nvk = (nvk == 0x0a) ? 0x32 : 0x0a;
}
// Special case for command + forward delete to send insert.
if ((event->nativeModifiers() & NSEventModifierFlagCommand) &&
((event->nativeVirtualKey() == nvk_Delete) || event->key() == Qt::Key_Delete)) {
nvk = nvk_Insert; // Qt::Key_Help according to event->key()
}
processKeyboardInput(down, nvk);
}
@@ -1294,7 +1299,7 @@ MainWindow::keyReleaseEvent(QKeyEvent *event)
fs_on_signal = false;
}
if (!send_keyboard_input)
if (!send_keyboard_input || event->isAutoRepeat())
return;
#ifdef Q_OS_MACOS

View File

@@ -36,7 +36,7 @@ SettingsDisplay::SettingsDisplay(QWidget *parent)
{
ui->setupUi(this);
videoCard[0] = gfxcard[0];
videoCard[0] = gfxcard[0];
videoCard[1] = gfxcard[1];
onCurrentMachineChanged(machine);
}
@@ -102,6 +102,11 @@ SettingsDisplay::onCurrentMachineChanged(int machineId)
ui->comboBoxVideoSecondary->setEnabled(true);
ui->pushButtonConfigureSecondary->setEnabled(true);
}
if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_8514)
ibm8514_has_vga = 0;
if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_XGA)
xga_has_vga = 0;
ui->comboBoxVideo->setCurrentIndex(selectedRow);
if (gfxcard[1] == 0)
ui->pushButtonConfigureSecondary->setEnabled(false);
@@ -123,10 +128,12 @@ SettingsDisplay::on_pushButtonConfigureVoodoo_clicked()
void
SettingsDisplay::on_pushButtonConfigureXga_clicked()
{
if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) {
DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast<Settings *>(Settings::settings));
} else {
DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast<Settings *>(Settings::settings));
if (!xga_has_vga) {
if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) {
DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast<Settings *>(Settings::settings));
} else {
DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast<Settings *>(Settings::settings));
}
}
}
@@ -139,7 +146,6 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
auto curVideoCard_2 = videoCard[1];
videoCard[0] = ui->comboBoxVideo->currentData().toInt();
ui->pushButtonConfigure->setEnabled(video_card_has_config(videoCard[0]) > 0);
bool machineHasPci = machine_has_bus(machineId, MACHINE_BUS_PCI) > 0;
ui->checkBoxVoodoo->setEnabled(machineHasPci);
if (machineHasPci) {
@@ -149,16 +155,16 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
bool hasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0;
bool has_MCA = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0;
ui->checkBox8514->setEnabled(hasIsa16 || has_MCA);
ui->checkBox8514->setEnabled((hasIsa16 || has_MCA) && !ibm8514_has_vga);
if (hasIsa16 || has_MCA) {
ui->checkBox8514->setChecked(ibm8514_enabled);
}
ui->checkBoxXga->setEnabled(hasIsa16 || has_MCA);
ui->checkBoxXga->setEnabled((hasIsa16 || has_MCA) && !xga_has_vga);
if (hasIsa16 || has_MCA)
ui->checkBoxXga->setChecked(xga_enabled);
ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked());
ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked() && !xga_has_vga);
int c = 2;
@@ -187,7 +193,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
c++;
}
if (videoCard[1] == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) {
if ((videoCard[1] == 0) || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) {
ui->comboBoxVideoSecondary->setCurrentIndex(0);
ui->pushButtonConfigureSecondary->setEnabled(false);
}
@@ -202,7 +208,7 @@ SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state)
void
SettingsDisplay::on_checkBoxXga_stateChanged(int state)
{
ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked);
ui->pushButtonConfigureXga->setEnabled((state == Qt::Checked) && !xga_has_vga);
}
void

View File

@@ -976,7 +976,9 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
break;
case 0xc6:
case 0xc7:
if ((!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433"))) {
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136")) {
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
}
@@ -1000,7 +1002,15 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev)
break;
case 0xc3:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) {
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) {
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
}
break;
case 0xde:
if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE74_1.00") ||
!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05")) {
bytes_per_second = 176.0 * 1024.0;
bytes_per_second *= (double) dev->drv->cur_speed;
}

View File

@@ -379,9 +379,9 @@ esp_get_cmd(esp_t *dev, uint32_t maxlen)
dma_set_drq(dev->DmaChannel, 0);
} else {
esp_pci_dma_memory_rw(dev, buf, dmalen, WRITE_TO_DEVICE);
dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen);
fifo8_push_all(&dev->cmdfifo, buf, dmalen);
}
dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen);
fifo8_push_all(&dev->cmdfifo, buf, dmalen);
} else {
dmalen = MIN(fifo8_num_used(&dev->fifo), maxlen);
esp_log("ESP Get command, dmalen = %i\n", dmalen);
@@ -545,6 +545,8 @@ esp_hard_reset(esp_t *dev)
dev->do_cmd = 0;
dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7;
esp_log("ESP Reset\n");
for (uint8_t i = 0; i < 16; i++)
scsi_device_reset(&scsi_devices[dev->bus][i]);
timer_stop(&dev->timer);
}
@@ -569,7 +571,6 @@ esp_do_nodma(esp_t *dev, scsi_device_t *sd)
esp_do_cmd(dev);
} else {
dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo);
;
esp_log("CDB offset = %i used\n", dev->cmdfifo_cdb_offset);
dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
@@ -665,7 +666,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd)
count = tdbc = esp_get_tc(dev);
if (dev->mca) { /*See the comment in the esp_do_busid_cmd() function.*/
if (dev->mca) {
if (sd->buffer_length < 0) {
if (dev->dma_enabled)
goto done;
@@ -713,7 +714,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd)
return;
}
esp_log("ESP SCSI dmaleft = %d, async_len = %i, buffer length = %d\n", esp_get_tc(dev), sd->buffer_length);
esp_log("ESP SCSI dmaleft = %d, buffer length = %d\n", esp_get_tc(dev), sd->buffer_length);
/* Make sure count is never bigger than buffer_length. */
if (count > dev->xfer_counter)
@@ -1082,6 +1083,9 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
esp_pci_soft_reset(dev);
break;
case CMD_BUSRESET:
for (uint8_t i = 0; i < 16; i++)
scsi_device_reset(&scsi_devices[dev->bus][i]);
if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) {
dev->rregs[ESP_RINTR] |= INTR_RST;
esp_log("ESP Bus Reset with IRQ\n");

View File

@@ -15,29 +15,26 @@
# include <86box/config.h>
# include <86box/device.h>
# include <86box/midi.h>
# include <86box/plat.h>
# include <86box/plat_dynld.h>
# include <86box/thread.h>
# include <86box/sound.h>
# include <86box/ui.h>
# define FLUID_CHORUS_DEFAULT_N 3
# define FLUID_CHORUS_DEFAULT_LEVEL 2.0f
# define FLUID_CHORUS_DEFAULT_SPEED 0.3f
# define FLUID_CHORUS_DEFAULT_DEPTH 8.0f
# define FLUID_CHORUS_DEFAULT_TYPE FLUID_CHORUS_MOD_SINE
# define RENDER_RATE 100
# define BUFFER_SEGMENTS 10
/* Check the FluidSynth version to determine wheteher to use the older reverb/chorus
control functions that were deprecated in 2.2.0, or their newer replacements */
# if (FLUIDSYNTH_VERSION_MAJOR < 2) || ((FLUIDSYNTH_VERSION_MAJOR == 2) && (FLUIDSYNTH_VERSION_MINOR < 2))
# define USE_OLD_FLUIDSYNTH_API
# endif
extern void givealbuffer_midi(void *buf, uint32_t size);
extern void al_set_midi(int freq, int buf_size);
typedef struct fluidsynth {
void *settings;
void *synth;
int samplerate;
int sound_font;
fluid_settings_t *settings;
fluid_synth_t *synth;
int samplerate;
int sound_font;
thread_t *thread_h;
event_t *event, *start_event;
@@ -177,7 +174,11 @@ fluidsynth_init(const device_t *info)
data->sound_font = fluid_synth_sfload(data->synth, sound_font, 1);
if (device_get_config_int("chorus")) {
# ifndef USE_OLD_FLUIDSYNTH_API
fluid_synth_chorus_on(data->synth, -1, 1);
# else
fluid_synth_set_chorus_on(data->synth, 1);
# endif
int chorus_voices = device_get_config_int("chorus_voices");
double chorus_level = device_get_config_int("chorus_level") / 100.0;
@@ -190,21 +191,48 @@ fluidsynth_init(const device_t *info)
else
chorus_waveform = FLUID_CHORUS_MOD_TRIANGLE;
# ifndef USE_OLD_FLUIDSYNTH_API
fluid_synth_set_chorus_group_nr(data->synth, -1, chorus_voices);
fluid_synth_set_chorus_group_level(data->synth, -1, chorus_level);
fluid_synth_set_chorus_group_speed(data->synth, -1, chorus_speed);
fluid_synth_set_chorus_group_depth(data->synth, -1, chorus_depth);
fluid_synth_set_chorus_group_type(data->synth, -1, chorus_waveform);
# else
fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform);
# endif
} else
# ifndef USE_OLD_FLUIDSYNTH_API
fluid_synth_chorus_on(data->synth, -1, 0);
# else
fluid_synth_set_chorus_on(data->synth, 0);
# endif
if (device_get_config_int("reverb")) {
# ifndef USE_OLD_FLUIDSYNTH_API
fluid_synth_reverb_on(data->synth, -1, 1);
# else
fluid_synth_set_reverb_on(data->synth, 1);
# endif
double reverb_room_size = device_get_config_int("reverb_room_size") / 100.0;
double reverb_damping = device_get_config_int("reverb_damping") / 100.0;
int reverb_width = device_get_config_int("reverb_width");
double reverb_width = device_get_config_int("reverb_width") / 10.0;
double reverb_level = device_get_config_int("reverb_level") / 100.0;
# ifndef USE_OLD_FLUIDSYNTH_API
fluid_synth_set_reverb_group_roomsize(data->synth, -1, reverb_room_size);
fluid_synth_set_reverb_group_damp(data->synth, -1, reverb_damping);
fluid_synth_set_reverb_group_width(data->synth, -1, reverb_width);
fluid_synth_set_reverb_group_level(data->synth, -1, reverb_level);
# else
fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level);
# endif
} else
# ifndef USE_OLD_FLUIDSYNTH_API
fluid_synth_reverb_on(data->synth, -1, 0);
# else
fluid_synth_set_reverb_on(data->synth, 0);
# endif
int interpolation = device_get_config_int("interpolation");
int fs_interpolation = FLUID_INTERP_4THORDER;
@@ -314,7 +342,7 @@ static const device_config_t fluidsynth_config[] = {
.name = "chorus",
.description = "Chorus",
.type = CONFIG_BINARY,
.default_int = 0
.default_int = 1
},
{
.name = "chorus_voices",
@@ -336,7 +364,7 @@ static const device_config_t fluidsynth_config[] = {
.min = 0,
.max = 100
},
.default_int = 100
.default_int = 20
},
{
.name = "chorus_speed",
@@ -344,7 +372,7 @@ static const device_config_t fluidsynth_config[] = {
.type = CONFIG_SPINNER,
.spinner =
{
.min = 30,
.min = 10,
.max = 500
},
.default_int = 30
@@ -356,7 +384,7 @@ static const device_config_t fluidsynth_config[] = {
.spinner =
{
.min = 0,
.max = 210
.max = 2560
},
.default_int = 80
},
@@ -381,7 +409,7 @@ static const device_config_t fluidsynth_config[] = {
.name = "reverb",
.description = "Reverb",
.type = CONFIG_BINARY,
.default_int = 0
.default_int = 1
},
{
.name = "reverb_room_size",
@@ -390,7 +418,7 @@ static const device_config_t fluidsynth_config[] = {
.spinner =
{
.min = 0,
.max = 120
.max = 100
},
.default_int = 20
},
@@ -412,9 +440,9 @@ static const device_config_t fluidsynth_config[] = {
.spinner =
{
.min = 0,
.max = 100
.max = 1000
},
.default_int = 1
.default_int = 5
},
{
.name = "reverb_level",

View File

@@ -20,7 +20,7 @@
typedef struct adgold_t {
int adgold_irq_status;
int irq, dma, hdma;
int irq, dma;
uint8_t adgold_eeprom[0x1a];
@@ -547,6 +547,7 @@ adgold_read(uint16_t addr, void *p)
temp = adgold->adgold_mma_status;
adgold->adgold_mma_status &= ~0xf3; /*JUKEGOLD expects timer status flags to auto-clear*/
adgold_update_irq_status(adgold);
picintc(1 << adgold->irq);
break;
case 5:
if (adgold->adgold_mma_addr >= 0xf)
@@ -652,7 +653,8 @@ adgold_timer_poll(void *p)
{
adgold_t *adgold = (adgold_t *) p;
timer_advance_u64(&adgold->adgold_mma_timer_count, (uint64_t) ((double) TIMER_USEC * 1.88964));
/*A small timer period will result in hangs.*/
timer_on_auto(&adgold->adgold_mma_timer_count, 4.88964);
if (adgold->adgold_midi_ctrl & 0x3f) {
if ((adgold->adgold_midi_ctrl & 0x3f) != 0x3f) {
@@ -925,7 +927,7 @@ adgold_init(const device_t *info)
adgold->adgold_eeprom[0x10] = 0xff;
adgold->adgold_eeprom[0x11] = 0x20;
adgold->adgold_eeprom[0x12] = 0x00;
adgold->adgold_eeprom[0x13] = 0xa0;
adgold->adgold_eeprom[0x13] = 0x00;
adgold->adgold_eeprom[0x14] = 0x00;
adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/
adgold->adgold_eeprom[0x16] = 0x00;
@@ -957,6 +959,7 @@ adgold_init(const device_t *info)
break;
}
adgold->adgold_eeprom[0x13] |= (adgold->dma << 3);
adgold->adgold_eeprom[0x14] |= (adgold->dma << 4);
memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19);
adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f];
adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f];

View File

@@ -18,7 +18,7 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c
vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c
vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c
vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c
vid_ati28800.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c
vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c
vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c
vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c
vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c

File diff suppressed because it is too large Load Diff

View File

@@ -45,6 +45,26 @@ ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type)
fclose(f);
}
void
ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn)
{
FILE *f;
int size;
eeprom->type = 0;
strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1);
f = nvr_fopen(eeprom->fn, "rb");
size = 128;
if (!f) { /*The ATI Graphics Ultra bios expects an immediate write to nvram if none is present at boot time otherwise
it would hang the machine.*/
memset(eeprom->data, 0, size);
f = nvr_fopen(eeprom->fn, "wb");
fwrite(eeprom->data, 1, size, f);
}
if (fread(eeprom->data, 1, size, f) != size)
memset(eeprom->data, 0, size);
fclose(f);
}
void
ati_eeprom_save(ati_eeprom_t *eeprom)
{

View File

@@ -172,7 +172,7 @@ typedef struct mach64_t {
uint32_t write_mask;
uint32_t chain_mask;
uint32_t linear_base, old_linear_base;
uint32_t linear_base;
uint32_t io_base;
struct
@@ -185,6 +185,7 @@ typedef struct mach64_t {
int src_x_start, src_y_start;
int xinc, yinc;
int x_count, y_count;
int xx_count;
int src_x_count, src_y_count;
int src_width1, src_height1;
int src_width2, src_height2;
@@ -487,35 +488,35 @@ mach64_recalctimings(svga_t *svga)
case BPP_4:
if (mach64->type != MACH64_GX)
svga->render = svga_render_4bpp_highres;
svga->hdisp *= 8;
svga->hdisp <<= 3;
break;
case BPP_8:
if (mach64->type != MACH64_GX)
svga->render = svga_render_8bpp_highres;
svga->hdisp *= 8;
svga->rowoffset /= 2;
svga->hdisp <<= 3;
svga->rowoffset >>= 1;
break;
case BPP_15:
if (mach64->type != MACH64_GX)
svga->render = svga_render_15bpp_highres;
svga->hdisp *= 8;
svga->hdisp <<= 3;
break;
case BPP_16:
if (mach64->type != MACH64_GX)
svga->render = svga_render_16bpp_highres;
svga->hdisp *= 8;
svga->hdisp <<= 3;
break;
case BPP_24:
if (mach64->type != MACH64_GX)
svga->render = svga_render_24bpp_highres;
svga->hdisp *= 8;
svga->hdisp <<= 3;
svga->rowoffset = (svga->rowoffset * 3) / 2;
break;
case BPP_32:
if (mach64->type != MACH64_GX)
svga->render = svga_render_32bpp_highres;
svga->hdisp *= 8;
svga->rowoffset *= 2;
svga->hdisp <<= 3;
svga->rowoffset <<= 1;
break;
}
@@ -530,7 +531,7 @@ mach64_updatemapping(mach64_t *mach64)
{
svga_t *svga = &mach64->svga;
if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) {
if (mach64->pci && !(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) {
mach64_log("Update mapping - PCI disabled\n");
mem_mapping_disable(&svga->mapping);
mem_mapping_disable(&mach64->linear_mapping);
@@ -543,47 +544,60 @@ mach64_updatemapping(mach64_t *mach64)
mem_mapping_disable(&mach64->mmio_mapping);
switch (svga->gdcreg[6] & 0xc) {
case 0x0: /*128k at A0000*/
mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel);
mem_mapping_set_p(&mach64->svga.mapping, mach64);
mem_mapping_set_handler(&svga->mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel);
mem_mapping_set_p(&svga->mapping, mach64);
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
mem_mapping_enable(&mach64->mmio_mapping);
svga->banked_mask = 0xffff;
break;
case 0x4: /*64k at A0000*/
mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel);
mem_mapping_set_p(&mach64->svga.mapping, mach64);
mem_mapping_set_handler(&svga->mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel);
mem_mapping_set_p(&svga->mapping, mach64);
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
svga->banked_mask = 0xffff;
break;
case 0x8: /*32k at B0000*/
mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_mapping_set_p(&mach64->svga.mapping, svga);
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_mapping_set_p(&svga->mapping, svga);
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
svga->banked_mask = 0x7fff;
break;
case 0xC: /*32k at B8000*/
mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_mapping_set_p(&mach64->svga.mapping, svga);
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_mapping_set_p(&svga->mapping, svga);
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
svga->banked_mask = 0x7fff;
break;
}
mach64_log("Mach64 linear aperture = %08x.\n", mach64->linear_base);
if (mach64->linear_base) {
if (mach64->type == MACH64_GX) {
if ((mach64->config_cntl & 3) == 2) {
/*8 MB aperture*/
mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000);
mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000);
} else {
} else if ((mach64->config_cntl & 3) == 1) {
/*4 MB aperture*/
mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000);
mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000);
} else {
/*Disable aperture on reserved values*/
mem_mapping_disable(&mach64->linear_mapping);
mem_mapping_disable(&mach64->mmio_linear_mapping);
}
} else {
/*2*8 MB aperture*/
mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000);
mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000);
mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000);
if ((mach64->config_cntl & 3) == 2) {
/*2*8 MB aperture*/
mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000);
mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000);
mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000);
} else {
/*Disable aperture on reserved values*/
mem_mapping_disable(&mach64->linear_mapping);
mem_mapping_disable(&mach64->mmio_linear_mapping);
mem_mapping_disable(&mach64->mmio_linear_mapping_2);
}
}
} else {
mem_mapping_disable(&mach64->linear_mapping);
@@ -621,7 +635,7 @@ mach64_wait_fifo_idle(mach64_t *mach64)
}
#define READ8(addr, var) \
switch ((addr) &3) { \
switch ((addr) & 3) { \
case 0: \
ret = (var) &0xff; \
break; \
@@ -637,7 +651,7 @@ mach64_wait_fifo_idle(mach64_t *mach64)
}
#define WRITE8(addr, var, val) \
switch ((addr) &3) { \
switch ((addr) & 3) { \
case 0: \
var = (var & 0xffffff00) | (val); \
break; \
@@ -1181,8 +1195,13 @@ mach64_start_fill(mach64_t *mach64)
{
mach64->accel.dst_x = 0;
mach64->accel.dst_y = 0;
mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff;
mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff;
if (((mach64->dst_y_x >> 16) & 0x1000))
mach64->accel.dst_x_start |= ~0xfff;
mach64->accel.dst_y_start = mach64->dst_y_x & 0x3fff;
if (mach64->dst_y_x & 0x4000)
mach64->accel.dst_y_start |= ~0x3fff;
mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff;
mach64->accel.dst_height = mach64->dst_height_width & 0x1fff;
@@ -1193,11 +1212,18 @@ mach64_start_fill(mach64_t *mach64)
}
mach64->accel.x_count = mach64->accel.dst_width;
mach64->accel.xx_count = 0;
mach64->accel.src_x = 0;
mach64->accel.src_y = 0;
mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff;
mach64->accel.src_y_start = mach64->src_y_x & 0xfff;
if (((mach64->src_y_x >> 16) & 0x1000))
mach64->accel.src_x_start |= ~0xfff;
mach64->accel.src_y_start = mach64->src_y_x & 0x3fff;
if (mach64->src_y_x & 0x4000)
mach64->accel.src_y_start |= ~0x3fff;
if (mach64->src_cntl & SRC_LINEAR_EN)
mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/
else
@@ -1219,11 +1245,11 @@ mach64_start_fill(mach64_t *mach64)
mach64->src_height1_width1,
mach64->src_height2_width2);
mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8;
mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8;
mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) << 3;
mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) << 3;
mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8;
mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8;
mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) << 3;
mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) << 3;
mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f;
mach64->accel.mix_bg = mach64->dp_mix & 0x1f;
@@ -1308,16 +1334,24 @@ void
mach64_start_line(mach64_t *mach64)
{
mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff;
mach64->accel.dst_y = mach64->dst_y_x & 0xfff;
if (((mach64->dst_y_x >> 16) & 0x1000))
mach64->accel.dst_x |= ~0xfff;
mach64->accel.dst_y = mach64->dst_y_x & 0x3fff;
if (mach64->dst_y_x & 0x4000)
mach64->accel.dst_y |= ~0x3fff;
mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff;
mach64->accel.src_y = mach64->src_y_x & 0xfff;
if (((mach64->src_y_x >> 16) & 0x1000))
mach64->accel.src_x |= ~0xfff;
mach64->accel.src_y = mach64->src_y_x & 0x3fff;
if (mach64->src_y_x & 0x4000)
mach64->accel.src_y |= ~0x3fff;
mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8;
mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8;
mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) << 3;
mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) << 3;
mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8;
mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8;
mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) << 3;
mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) << 3;
mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f;
mach64->accel.mix_bg = mach64->dp_mix & 0x1f;
@@ -1344,9 +1378,6 @@ mach64_start_line(mach64_t *mach64)
else
mach64->accel.dst_offset >>= mach64->accel.dst_size;
/* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width];
mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/
mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST);
for (uint8_t y = 0; y < 8; y++) {
@@ -1446,6 +1477,7 @@ mach64_start_line(mach64_t *mach64)
break; \
case 0x17: \
dest_dat = (dest_dat + src_dat) >> 1; \
break; \
}
#define WRITE(addr, width) \
@@ -1483,24 +1515,31 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
mach64_log("mach64_blit : return as not busy\n");
return;
}
switch (mach64->accel.op) {
case OP_RECT:
while (count) {
uint8_t write_mask = 0;
uint32_t src_dat = 0;
uint32_t dest_dat;
uint32_t host_dat = 0;
uint32_t old_dest_dat;
int mix = 0;
int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff;
int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff;
int dst_x;
int dst_y;
int src_x;
int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff;
int src_y;
dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff;
dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0x3fff;
if (mach64->src_cntl & SRC_LINEAR_EN)
src_x = mach64->accel.src_x;
else
src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff;
src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0x3fff;
if (mach64->accel.source_host) {
host_dat = cpu_dat;
switch (mach64->accel.host_size) {
@@ -1525,7 +1564,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
mix = cpu_dat & 1;
cpu_dat >>= 1;
} else {
mix = cpu_dat >> 31;
mix = cpu_dat >> 0x1f;
cpu_dat <<= 1;
}
break;
@@ -1544,7 +1583,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
break;
}
if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right && dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom) {
if ((dst_x) >= mach64->accel.sc_left && (dst_x) <= mach64->accel.sc_right && (dst_y) >= mach64->accel.sc_top && (dst_y) <= mach64->accel.sc_bottom) {
switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) {
case SRC_HOST:
src_dat = host_dat;
@@ -1553,24 +1592,42 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size);
break;
case SRC_FG:
if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) {
if ((mach64->accel.x_count % 3) == 2)
src_dat = mach64->accel.dp_frgd_clr & 0xff;
else if ((mach64->accel.x_count % 3) == 1)
src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff;
else if ((mach64->accel.x_count % 3) == 0)
src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff;
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) {
if (mach64->accel.xinc == -1) {
if ((mach64->accel.xx_count % 3) == 2)
src_dat = mach64->accel.dp_frgd_clr & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff;
else
src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff;
} else {
if ((mach64->accel.xx_count % 3) == 2)
src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff;
else
src_dat = mach64->accel.dp_frgd_clr & 0xff;
}
} else
src_dat = mach64->accel.dp_frgd_clr;
break;
case SRC_BG:
if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) {
if ((mach64->accel.x_count % 3) == 2)
src_dat = mach64->accel.dp_bkgd_clr & 0xff;
else if ((mach64->accel.x_count % 3) == 1)
src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff;
else if ((mach64->accel.x_count % 3) == 0)
src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff;
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) {
if (mach64->accel.xinc == -1) {
if ((mach64->accel.xx_count % 3) == 2)
src_dat = mach64->accel.dp_bkgd_clr & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff;
else
src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff;
} else {
if ((mach64->accel.xx_count % 3) == 2)
src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff;
else
src_dat = mach64->accel.dp_bkgd_clr & 0xff;
}
} else
src_dat = mach64->accel.dp_bkgd_clr;
break;
@@ -1595,7 +1652,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
}
if (!(mach64->dst_cntl & DST_POLYGON_EN) || mach64->accel.poly_draw) {
READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size);
READ(mach64->accel.dst_offset + ((dst_y) * mach64->accel.dst_pitch) + (dst_x), dest_dat, mach64->accel.dst_size);
switch (mach64->accel.clr_cmp_fn) {
case 1: /*TRUE*/
@@ -1612,19 +1669,30 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
if (!cmp_clr) {
old_dest_dat = dest_dat;
MIX
dest_dat
= (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask);
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) {
if (mach64->accel.xinc == -1) {
if ((mach64->accel.xx_count % 3) == 2)
write_mask = mach64->accel.write_mask & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
write_mask = (mach64->accel.write_mask >> 8) & 0xff;
else
write_mask = (mach64->accel.write_mask >> 16) & 0xff;
} else {
if ((mach64->accel.xx_count % 3) == 2)
write_mask = (mach64->accel.write_mask >> 16) & 0xff;
else if ((mach64->accel.xx_count % 3) == 1)
write_mask = (mach64->accel.write_mask >> 8) & 0xff;
else
write_mask = mach64->accel.write_mask & 0xff;
}
dest_dat = (dest_dat & write_mask) | (old_dest_dat & ~write_mask);
} else {
dest_dat = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask);
}
}
WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size);
}
}
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) {
if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) != (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) {
mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16);
mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16);
mach64->accel.write_mask = ((mach64->accel.write_mask >> 8) & 0xffff) | (mach64->accel.write_mask << 16);
WRITE(mach64->accel.dst_offset + ((dst_y) * mach64->accel.dst_pitch) + (dst_x), mach64->accel.dst_size);
}
}
@@ -1636,14 +1704,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
mach64->accel.src_x = 0;
if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) {
mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff;
if ((mach64->src_y_x_start >> 16) & 0x1000)
mach64->accel.src_x_start |= ~0xfff;
mach64->accel.src_x_count = mach64->accel.src_width2;
} else
mach64->accel.src_x_count = mach64->accel.src_width1;
}
}
mach64->accel.xx_count++;
mach64->accel.x_count--;
if (mach64->accel.x_count <= 0) {
mach64->accel.xx_count = 0;
mach64->accel.x_count = mach64->accel.dst_width;
mach64->accel.dst_x = 0;
mach64->accel.dst_y += mach64->accel.yinc;
@@ -1657,7 +1729,9 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
if (mach64->accel.src_y_count <= 0) {
mach64->accel.src_y = 0;
if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) {
mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff;
mach64->accel.src_y_start = mach64->src_y_x_start & 0x3fff;
if (mach64->src_y_x_start & 0x4000)
mach64->accel.src_y_start |= ~0x3fff;
mach64->accel.src_y_count = mach64->accel.src_height2;
} else
mach64->accel.src_y_count = mach64->accel.src_height1;
@@ -1702,7 +1776,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
if (mach64->accel.source_host) {
host_dat = cpu_dat;
switch (mach64->accel.src_size) {
switch (mach64->accel.host_size) {
case 0:
cpu_dat >>= 8;
count -= 8;
@@ -1783,12 +1857,10 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
if (!cmp_clr)
MIX
if (!(mach64->dst_cntl & DST_Y_MAJOR))
{
if (x == 0)
dest_dat &= ~1;
}
else {
if (!(mach64->dst_cntl & DST_Y_MAJOR)) {
if (!x)
dest_dat &= ~1;
} else {
if (x == (mach64->accel.x_count - 1))
dest_dat &= ~1;
}
@@ -1831,7 +1903,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
if (mach64->accel.source_host) {
host_dat = cpu_dat;
switch (mach64->accel.src_size) {
switch (mach64->accel.host_size) {
case 0:
cpu_dat >>= 8;
count -= 8;
@@ -1909,7 +1981,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64)
if (!cmp_clr)
MIX
WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size);
WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size);
}
mach64->accel.x_count--;
@@ -2347,6 +2419,7 @@ mach64_ext_readb(uint32_t addr, void *p)
mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4);
else
mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 24) << 4);
READ8(addr, mach64->config_cntl);
break;
case 0xe0:
@@ -2667,11 +2740,15 @@ mach64_ext_readb(uint32_t addr, void *p)
case 0x310:
case 0x311:
if (!FIFO_EMPTY)
wake_fifo_thread(mach64);
ret = 0;
if (FIFO_FULL)
ret = 0xff;
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) {
ret = 0;
} else {
if (!FIFO_EMPTY)
wake_fifo_thread(mach64);
ret = 0;
if (FIFO_FULL)
ret = 0xff;
}
break;
case 0x320:
@@ -2697,7 +2774,10 @@ mach64_ext_readb(uint32_t addr, void *p)
break;
case 0x338:
ret = FIFO_EMPTY ? 0 : 1;
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24)
ret = 0;
else
ret = FIFO_EMPTY ? 0 : 1;
break;
default:
@@ -2876,7 +2956,10 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *p)
mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val);
} else if (addr & 0x300) {
mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE);
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24)
mach64_accel_write_fifo(mach64, addr & 0x3ff, val);
else
mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE);
} else
switch (addr & 0x3ff) {
case 0x00:
@@ -3099,7 +3182,10 @@ mach64_ext_writew(uint32_t addr, uint16_t val, void *p)
mach64_ext_writeb(addr, val, p);
mach64_ext_writeb(addr + 1, val >> 8, p);
} else if (addr & 0x300) {
mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD);
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24)
mach64_accel_write_fifo_w(mach64, addr & 0x3fe, val);
else
mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD);
} else
switch (addr & 0x3fe) {
default:
@@ -3120,7 +3206,10 @@ mach64_ext_writel(uint32_t addr, uint32_t val, void *p)
mach64_ext_writew(addr, val, p);
mach64_ext_writew(addr + 2, val >> 16, p);
} else if (addr & 0x300) {
mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD);
if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24)
mach64_accel_write_fifo_l(mach64, addr & 0x3fc, val);
else
mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD);
} else
switch (addr & 0x3fc) {
default:
@@ -4210,9 +4299,8 @@ mach64_common_init(const device_t *info)
mach64_io_set(mach64);
if (info->flags & DEVICE_PCI) {
if (info->flags & DEVICE_PCI)
mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64);
}
mach64->pci_regs[PCI_REG_COMMAND] = 3;
mach64->pci_regs[0x30] = 0x00;
@@ -4252,7 +4340,7 @@ mach64gx_init(const device_t *info)
mach64->type = MACH64_GX;
mach64->pci = !!(info->flags & DEVICE_PCI);
mach64->pci_id = (int) 'X' | ((int) 'G' << 8);
mach64->config_chip_id = 0x020000d7;
mach64->config_chip_id = 0x000000d7;
mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/
mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/
if (info->flags & DEVICE_PCI)
@@ -4282,10 +4370,7 @@ mach64vt2_init(const device_t *info)
mach64_t *mach64 = mach64_common_init(info);
svga_t *svga = &mach64->svga;
if (info->flags & DEVICE_PCI)
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci);
else
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb);
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci);
mach64->type = MACH64_VT2;
mach64->pci = 1;
@@ -4299,8 +4384,7 @@ mach64vt2_init(const device_t *info)
rom_init(&mach64->bios_rom, BIOS_ROMVT2_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
if (info->flags & DEVICE_PCI)
mem_mapping_disable(&mach64->bios_rom.mapping);
mem_mapping_disable(&mach64->bios_rom.mapping);
svga->vblank_start = mach64_vblank_start;

5566
src/video/vid_ati_mach8.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -277,7 +277,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p)
svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80);
svga->hwcursor.xoff = et4000->regs[0xE2];
svga->hwcursor.yoff = et4000->regs[0xE6];
svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->type == ET4000W32) && et4000->regs[0xe2] && et4000->regs[0xe6])) ? 128 : 64;
svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->type == ET4000W32) && (et4000->regs[0xe2] >= 0x1f) && (et4000->regs[0xe6] >= 0x1f))) ? 128 : 64;
if (et4000->type == ET4000W32) {
if ((svga->bpp == 15) || (svga->bpp == 16)) {

View File

@@ -498,7 +498,7 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3);
temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask];
#define READ_PIXTRANS_WORD \
if (s3->bpp == 0 && !s3->color_16bit) { \
if ((s3->bpp == 0) && !s3->color_16bit) { \
temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \
temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \
} else { \
@@ -506,7 +506,7 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3);
}
#define READ_PIXTRANS_LONG \
if (s3->bpp == 0 && !s3->color_16bit) { \
if ((s3->bpp == 0) && !s3->color_16bit) { \
temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \
temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \
temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 2)) & s3->vram_mask] << 16); \
@@ -2671,6 +2671,7 @@ s3_out(uint16_t addr, uint8_t val, void *p)
return;
if ((s3->chip <= S3_86C924) && (svga->crtcreg >= 0x50))
return;
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
@@ -3075,7 +3076,7 @@ s3_recalctimings(svga_t *svga)
svga->rowoffset |= 0x100;
}
if (!svga->rowoffset)
svga->rowoffset = 256;
svga->rowoffset = 0x100;
if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) {
if (s3->card_type == S3_ELSAWIN2KPROX_964)
@@ -3120,7 +3121,7 @@ s3_recalctimings(svga_t *svga)
}
} else {
if (s3->card_type == S3_NUMBER9_9FX_531) {
if (svga->hdisp == 1600 && s3->width == 1600)
if ((svga->hdisp == 1600) && (s3->width == 1600))
s3->width = 800;
}
}
@@ -3131,10 +3132,10 @@ s3_recalctimings(svga_t *svga)
}
}
if ((svga->crtc[0x43] & 0x08) && (s3->color_16bit == 0) && (s3->chip <= S3_86C805)) {
if ((svga->crtc[0x43] & 0x08) && !s3->color_16bit && (s3->chip <= S3_86C805)) {
s3->color_16bit = 1;
s3->width = 1024;
} else if (!(svga->crtc[0x43] & 0x08) && (s3->color_16bit == 1) && (s3->chip <= S3_86C805)) {
s3->width = 1024;
} else if (!(svga->crtc[0x43] & 0x08) && s3->color_16bit && (s3->chip <= S3_86C805)) {
s3->color_16bit = 0;
if (s3->chip <= S3_86C924) {
if (s3->accel.advfunc_cntl & 4)
@@ -4808,9 +4809,9 @@ polygon_setup(s3_t *s3)
}
#define READ(addr, dat) \
if (s3->bpp == 0 && !s3->color_16bit) \
if ((s3->bpp == 0) && !s3->color_16bit) \
dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \
else if (s3->bpp == 1 || s3->color_16bit) \
else if ((s3->bpp == 1) || s3->color_16bit) \
dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \
else if (s3->bpp == 2) \
dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \
@@ -5660,10 +5661,10 @@ polygon_setup(s3_t *s3)
}
#define WRITE(addr, dat) \
if (s3->bpp == 0 && !s3->color_16bit) { \
if ((s3->bpp == 0) && !s3->color_16bit) { \
svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \
svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \
} else if (s3->bpp == 1 || s3->color_16bit) { \
} else if ((s3->bpp == 1) || s3->color_16bit) { \
vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \
svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \
} else if (s3->bpp == 2) { \
@@ -6123,7 +6124,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.dat_count = 0;
if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) {
if ((s3->bpp == 3) && count == 2) {
if ((s3->bpp == 3) && (count == 2)) {
if (s3->accel.dat_count) {
cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf;
count = 4;
@@ -6133,20 +6134,20 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.dat_count = 1;
}
}
if (s3->bpp == 1 || s3->color_16bit)
if ((s3->bpp == 1) || s3->color_16bit)
count >>= 1;
if (s3->bpp == 3)
count >>= 2;
}
if (s3->bpp == 0 && !s3->color_16bit)
if ((s3->bpp == 0) && !s3->color_16bit)
rd_mask &= 0xff;
else if (s3->bpp == 1 || s3->color_16bit)
else if ((s3->bpp == 1) || s3->color_16bit)
rd_mask &= 0xffff;
if (s3->bpp == 0 && !s3->color_16bit)
if ((s3->bpp == 0) && !s3->color_16bit)
compare &= 0xff;
if (s3->bpp == 1 || s3->color_16bit)
if ((s3->bpp == 1) || s3->color_16bit)
compare &= 0xffff;
switch (s3->accel.cmd & 0x600) {
@@ -6212,6 +6213,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
cpu_dat >>= 8;
else
cpu_dat >>= 16;
if (!s3->accel.ssv_len)
break;
@@ -6259,18 +6261,16 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.cx = s3->accel.cur_x & 0x7ff;
s3->accel.cy = s3->accel.cur_y & 0x7ff;
if (s3->accel.cur_x & 0x800) {
if (s3->accel.cur_x & 0x800)
s3->accel.cx |= ~0x7ff;
}
if (s3->accel.cur_y & 0x800) {
if (s3->accel.cur_y & 0x800)
s3->accel.cy |= ~0x7ff;
}
s3->accel.sy = s3->accel.maj_axis_pcnt;
if (s3_cpu_src(s3)) {
if (s3_cpu_src(s3))
return; /*Wait for data from CPU*/
}
}
frgd_mix = (s3->accel.frgd_mix >> 5) & 3;
bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3;
@@ -6305,11 +6305,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
mix_dat <<= 1;
mix_dat |= 1;
if (s3->bpp == 0 && !s3->color_16bit)
if ((s3->bpp == 0) && !s3->color_16bit)
cpu_dat >>= 8;
else {
else
cpu_dat >>= 16;
}
if (!s3->accel.sy) {
break;
@@ -6351,13 +6350,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
s3->accel.cur_y = s3->accel.cy;
} else /*Bresenham*/
{
if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/
if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/
count = s3->accel.maj_axis_pcnt + 1;
s3->accel.temp_cnt = 16;
}
while (count-- && s3->accel.sy >= 0) {
if (s3->accel.b2e8_pix && s3_cpu_src(s3) && s3->accel.temp_cnt == 0) {
if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) {
mix_dat >>= 16;
s3->accel.temp_cnt = 16;
}
@@ -6567,7 +6566,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
mix_dat |= 1;
}
if (s3->bpp == 0 && !s3->color_16bit)
if ((s3->bpp == 0) && !s3->color_16bit)
cpu_dat >>= 8;
else {
cpu_dat >>= 16;
@@ -8021,7 +8020,7 @@ s3_init(const device_t *info)
switch (vram) {
case 0: /* 512 kB */
svga->vram_mask = (1 << 19) - 1;
svga->vram_max = 2 << 20;
svga->vram_max = 1 << 19;
break;
case 1: /* 1 MB */
/* VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus.
@@ -8029,7 +8028,7 @@ s3_init(const device_t *info)
This works with the #9 9FX BIOS, and matches how my real Trio64 behaves,
but does not work with the Phoenix EDO BIOS. Possibly an FPM/EDO difference? */
svga->vram_mask = (1 << 20) - 1;
svga->vram_max = 2 << 20;
svga->vram_max = 1 << 20;
break;
case 2:
default: /*2 MB */

View File

@@ -3372,7 +3372,7 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri)
state.base_w = s3d_tri->tws;
tex_base = s3d_tri->tex_base;
for (uint8_t c = 9; c >= 0; c--) {
for (int c = 9; c >= 0; c--) {
state.texture[c] = (uint16_t *) &virge->svga.vram[tex_base];
if (c <= state.max_d)
tex_base += ((1 << (c * 2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2;

View File

@@ -41,6 +41,7 @@
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
#include <86box/vid_xga_device.h>
void svga_doblit(int wx, int wy, svga_t *svga);
@@ -131,7 +132,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
if (svga->attraddr < 16)
svga->fullchange = svga->monitor->mon_changeframecount;
if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) {
for (uint8_t c = 0; c < 16; c++) {
for (int c = 0; c < 16; c++) {
if (svga->attrregs[0x10] & 0x80) {
svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4);
} else {
@@ -165,6 +166,12 @@ svga_out(uint16_t addr, uint8_t val, void *p)
io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p);
svga_recalctimings(svga);
break;
case 0x3c3:
if (xga_enabled) {
svga->xga.on = (val & 0x01) ? 0 : 1;
vga_on = !svga->xga.on;
}
break;
case 0x3c4:
svga->seqaddr = val;
break;
@@ -407,7 +414,7 @@ svga_set_ramdac_type(svga_t *svga, int type)
if (svga->ramdac_type != type) {
svga->ramdac_type = type;
for (uint16_t c = 0; c < 256; c++) {
for (int c = 0; c < 256; c++) {
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
else
@@ -583,8 +590,14 @@ svga_recalctimings(svga_t *svga)
svga->recalctimings_ex(svga);
}
} else {
if (ibm8514_enabled)
ibm8514_recalctimings(svga);
if (ibm8514_enabled) {
if (svga->dev8514.local) {
if (svga->recalctimings_ex) {
svga->recalctimings_ex(svga);
}
} else
ibm8514_recalctimings(svga);
}
if (xga_enabled)
xga_recalctimings(svga);
}
@@ -597,8 +610,13 @@ svga_recalctimings(svga_t *svga)
crtcconst = svga->clock * svga->char_width;
disptime = svga->htotal;
_dispontime = svga->hdisp_time;
if (ibm8514_on && !svga->dev8514.local) {
disptime = svga->dev8514.h_total;
_dispontime = svga->dev8514.h_disp;
} else {
disptime = svga->htotal;
_dispontime = svga->hdisp_time;
}
if (svga->seqregs[1] & 8) {
disptime *= 2;
@@ -678,16 +696,20 @@ void
svga_poll(void *p)
{
svga_t *svga = (svga_t *) p;
ibm8514_t *dev = &svga->dev8514;
uint32_t x;
uint32_t blink_delay;
int wx;
int wy;
int ret;
int old_ma;
int linecountff = 0;
if (!vga_on && ibm8514_enabled && ibm8514_on) {
ibm8514_poll(&svga->dev8514, svga);
return;
if (!dev->local) {
ibm8514_poll(dev, svga);
return;
}
} else if (!vga_on && xga_enabled && svga->xga.on) {
xga_poll(&svga->xga, svga);
return;
@@ -695,22 +717,22 @@ svga_poll(void *p)
if (!svga->linepos) {
if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) {
svga->hwcursor_on = svga->hwcursor.cur_ysize - svga->hwcursor_latch.yoff;
svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - svga->hwcursor_latch.yoff;
svga->hwcursor_oddeven = 0;
}
if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && svga->interlace) {
svga->hwcursor_on = svga->hwcursor.cur_ysize - (svga->hwcursor_latch.yoff + 1);
svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - (svga->hwcursor_latch.yoff + 1);
svga->hwcursor_oddeven = 1;
}
if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) {
svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - svga->dac_hwcursor_latch.yoff;
svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - svga->dac_hwcursor_latch.yoff;
svga->dac_hwcursor_oddeven = 0;
}
if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) {
svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1);
svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1);
svga->dac_hwcursor_oddeven = 1;
}
@@ -783,8 +805,14 @@ svga_poll(void *p)
if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount))
svga->con = 0;
if (svga->dispon) {
if (svga->linedbl && !svga->linecountff) {
svga->linecountff = 1;
/*Real IBM 8514/A or compatibility mode doesn't have linedbl, so skip those.*/
if (dev->local && ibm8514_on) {
svga->linedbl = 0;
svga->linecountff = 0;
linecountff = 1;
}
if (svga->linedbl && !svga->linecountff && !linecountff) {
svga->linecountff = 1;
svga->ma = svga->maback;
} else if (svga->sc == svga->rowcount) {
svga->linecountff = 0;
@@ -793,23 +821,24 @@ svga_poll(void *p)
svga->maback += (svga->rowoffset << 3);
if (svga->interlace)
svga->maback += (svga->rowoffset << 3);
svga->maback &= svga->vram_display_mask;
svga->ma = svga->maback;
} else {
svga->linecountff = 0;
svga->sc++;
svga->sc &= 31;
svga->sc &= 0x1f;
svga->ma = svga->maback;
}
}
svga->hsync_divisor = !svga->hsync_divisor;
svga->hsync_divisor ^= 1;
if (svga->hsync_divisor && (svga->crtc[0x17] & 4))
return;
svga->vc++;
svga->vc &= 2047;
svga->vc &= 0x7ff;
if (svga->vc == svga->split) {
ret = 1;
@@ -835,6 +864,7 @@ svga_poll(void *p)
if (svga->vc == svga->dispend) {
if (svga->vblank_start)
svga->vblank_start(svga);
svga->dispon = 0;
blink_delay = (svga->crtc[11] & 0x60) >> 5;
if (svga->crtc[10] & 0x20)
@@ -846,6 +876,7 @@ svga_poll(void *p)
if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15))
svga->fullchange = 2;
svga->blink = (svga->blink + 1) & 0x7f;
for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) {
@@ -888,12 +919,18 @@ svga_poll(void *p)
svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2;
svga->vslines = 0;
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
else
svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5);
if ((dev->local && vga_on) || !dev->local) {
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
else
svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5);
} else if (dev->local && ibm8514_on) {
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1);
else
svga->ma = svga->maback = svga->ma_latch;
}
svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj;
svga->ma = (svga->ma << 2);
svga->maback = (svga->maback << 2);
svga->ca = (svga->ca << 2);
@@ -958,9 +995,9 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize,
svga->monitor_index = monitor_index_global;
svga->monitor = &monitors[svga->monitor_index];
for (uint16_t c = 0; c < 256; c++) {
for (int c = 0; c < 256; c++) {
e = c;
for (uint8_t d = 0; d < 8; d++) {
for (int d = 0; d < 8; d++) {
svga_rotate[d][c] = e;
e = (e >> 1) | ((e & 1) ? 0x80 : 0);
}
@@ -1100,7 +1137,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
if (!linear) {
if (xga_enabled) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) {
if (val == 0xa5) { /*Memory size test of XGA*/
svga->xga.test = val;
svga->xga.a5_test = 1;
@@ -1108,7 +1145,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
} else if (val == 0x5a) {
svga->xga.test = val;
return;
} else if (val == 0x12 || val == 0x34) {
} else if ((val == 0x12) || (val == 0x34)) {
addr += svga->xga.write_bank;
svga->xga.vram[addr & svga->xga.vram_mask] = val;
svga->xga.linear_endian_reverse = 1;
@@ -1145,10 +1182,18 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
if (addr & 1)
writemask2 <<= 1;
addr &= ~1;
addr <<= 2;
} else
addr <<= 2;
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) {
addr &= svga->vram_mask;
} else
addr <<= 2;
} else {
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) {
writemask2 = 1 << (addr & 3);
addr &= ~3;
addr &= svga->vram_mask;
} else
addr <<= 2;
}
addr &= svga->decode_mask;
if (svga->translate_address)
@@ -1303,7 +1348,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
if (!linear) {
if (xga_enabled) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) {
if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) {
if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/
svga->xga.on = 1;
vga_on = !svga->xga.on;
@@ -1312,7 +1357,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
svga->xga.on = 1;
vga_on = !svga->xga.on;
return svga->xga.test;
} else if (addr == 0xa0000 || addr == 0xa0010) {
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
addr += svga->xga.read_bank;
return svga->xga.vram[addr & svga->xga.vram_mask];
}
@@ -1354,11 +1399,24 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
} else if (svga->chain2_read) {
readplane = (readplane & 2) | (addr & 1);
addr &= ~1;
addr <<= 2;
} else
addr <<= 2;
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI))
addr &= svga->vram_mask;
else
addr <<= 2;
} else {
if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) {
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return 0xff;
latch_addr = (addr & svga->vram_mask) & ~3;
for (uint8_t i = 0; i < count; i++)
svga->latch.b[i] = svga->vram[latch_addr | i];
return svga->vram[addr & svga->vram_mask];
} else
addr <<= 2;
}
addr &= svga->decode_mask;
if (svga->translate_address) {
latch_addr = svga->translate_address(latch_addr, p);
addr = svga->translate_address(addr, p);

View File

@@ -36,6 +36,7 @@
#include <86box/vid_ega.h>
#include <86box/vid_colorplus.h>
#include <86box/vid_mda.h>
#include <86box/vid_xga_device.h>
typedef struct {
const device_t *device;
@@ -79,6 +80,8 @@ video_cards[] = {
{ &vid_none_device },
{ &vid_internal_device },
{ &atiega_device },
{ &mach8_isa_device, VIDEO_FLAG_TYPE_8514 },
{ &mach32_isa_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_isa_device },
{ &ati28800k_device },
{ &ati18800_vga88_device },
@@ -112,6 +115,7 @@ video_cards[] = {
{ &hercules_device, VIDEO_FLAG_TYPE_MDA },
{ &herculesplus_device, VIDEO_FLAG_TYPE_MDA },
{ &incolor_device },
{ &inmos_isa_device, VIDEO_FLAG_TYPE_XGA },
{ &im1024_device },
{ &iskra_ega_device },
{ &et4000_kasan_isa_device },
@@ -154,6 +158,7 @@ video_cards[] = {
{ &gd5428_mca_device },
{ &et4000_mca_device },
{ &radius_svga_multiview_mca_device },
{ &mach32_pci_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_pci_device },
{ &mach64vt2_device },
{ &et4000w32p_videomagic_revb_pci_device },
@@ -211,6 +216,7 @@ video_cards[] = {
{ &voodoo_3_1000_device },
{ &voodoo_3_2000_device },
{ &voodoo_3_3000_device },
{ &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 },
{ &mach64gx_vlb_device },
{ &et4000w32i_vlb_device },
{ &et4000w32p_videomagic_revb_vlb_device },
@@ -431,3 +437,15 @@ video_is_ega_vga(void)
{
return (video_get_type() == VIDEO_FLAG_TYPE_SPECIAL);
}
int
video_is_8514(void)
{
return (video_get_type() == VIDEO_FLAG_TYPE_8514);
}
int
video_is_xga(void)
{
return (video_get_type() == VIDEO_FLAG_TYPE_XGA);
}

View File

@@ -37,6 +37,7 @@
#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN"
#define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin"
#define INMOS_XGA_BIOS_PATH "roms/video/xga/InMOS XGA - Fairchild NM27C256Q-150.BIN"
static video_timings_t timing_xga_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 };
static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 };
@@ -44,16 +45,86 @@ static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .writ
static void xga_ext_outb(uint16_t addr, uint8_t val, void *p);
static uint8_t xga_ext_inb(uint16_t addr, void *p);
int xga_has_vga = 0;
void
svga_xga_out(uint16_t addr, uint8_t val, void *p)
{
svga_t *svga = (svga_t *)p;
uint8_t old;
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
addr ^= 0x60;
switch (addr) {
case 0x3D4:
svga->crtcreg = val & 0x3f;
return;
case 0x3D5:
if (svga->crtcreg & 0x20)
return;
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
if (old != val) {
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;
}
svga_out(addr, val, svga);
}
uint8_t
svga_xga_in(uint16_t addr, void *p)
{
svga_t *svga = (svga_t *)p;
uint8_t temp;
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
addr ^= 0x60;
switch (addr) {
case 0x3D4:
temp = svga->crtcreg;
break;
case 0x3D5:
if (svga->crtcreg & 0x20)
temp = 0xff;
else
temp = svga->crtc[svga->crtcreg];
break;
default:
temp = svga_in(addr, svga);
break;
}
return temp;
}
void
xga_updatemapping(svga_t *svga)
{
xga_t *xga = &svga->xga;
//pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x, map = %x.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode, svga->gdcreg[6] & 0x0c);
//pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, access mode = %x, map = %x, endian reverse = %d, a5test = %d, XGA on = %d.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->access_mode, svga->gdcreg[6] & 0x0c, xga->linear_endian_reverse, xga->a5_test, xga->on);
if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) {
if (xga->aperture_cntl == 1) {
if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) {
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
if (xga->aperture_cntl == 1)
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
else
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
if (!xga->linear_endian_reverse)
@@ -63,38 +134,23 @@ xga_updatemapping(svga_t *svga)
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
if (xga->pos_regs[4] & 1)
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
else if (xga->base_addr_1mb)
if (xga->base_addr_1mb)
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000);
else
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && xga->on)
xga->linear_endian_reverse = 1;
else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on)
else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on) {
xga->linear_endian_reverse = 1;
xga->on = 0;
vga_on = !xga->on;
} else {
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
mem_mapping_disable(&xga->linear_mapping);
}
if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) {
xga->on = 0;
vga_on = !xga->on;
}
}
} else {
xga->on = 0;
vga_on = !xga->on;
mem_mapping_disable(&svga->mapping);
if (xga->aperture_cntl == 2)
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
else
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
mem_mapping_enable(&xga->video_mapping);
xga->banked_mask = 0xffff;
mem_mapping_disable(&xga->linear_mapping);
//pclog("XGA opmode (not extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, xga->disp_cntl_2 & 7, xga->aperture_cntl);
//pclog("XGA opmode (extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, xga->disp_cntl_2 & 7, xga->aperture_cntl);
}
//pclog("VGA on = %d.\n", vga_on);
}
void
@@ -126,19 +182,19 @@ xga_recalctimings(svga_t *svga)
xga->ma_latch = xga->disp_start_addr;
switch (xga->clk_sel_1 & 0x0c) {
switch ((xga->clk_sel_1 >> 2) & 3) {
case 0:
if (xga->clk_sel_2 & 0x80) {
svga->clock = (cpuclock * (double) (1ULL << 32)) / 41539000.0;
svga->clock = (cpuclock * (double) (1ull << 32)) / 41539000.0;
} else {
svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
svga->clock = (cpuclock * (double) (1ull << 32)) / 25175000.0;
}
break;
case 4:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 28322000.0;
case 1:
svga->clock = (cpuclock * (double) (1ull << 32)) / 28322000.0;
break;
case 0x0c:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0;
case 3:
svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0;
break;
}
}
@@ -309,7 +365,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
if ((xga->sprite_pos >= 0) && (xga->sprite_pos <= 16)) {
if ((xga->op_mode & 7) >= 5)
xga->cursor_data_on = 1;
else if (xga->sprite_pos >= 1)
else if ((xga->sprite_pos >= 1) || ((xga->disp_cntl_2 & 7) > 3))
xga->cursor_data_on = 1;
else if (xga->aperture_cntl == 0) {
if (xga->linear_endian_reverse && !(xga->access_mode & 8))
@@ -474,7 +530,10 @@ xga_ext_inb(uint16_t addr, void *p)
case 0x0f:
switch (xga->regs_idx) {
case 4:
ret = (xga->bus & DEVICE_MCA) ? 1 : 0;
if (xga->bus & DEVICE_MCA)
ret = 0x01; /*32-bit MCA*/
else
ret = 0x10; /*16-bit ISA*/
break;
case 0x10:
ret = xga->htotal & 0xff;
@@ -653,6 +712,16 @@ xga_ext_inb(uint16_t addr, void *p)
ret = xga->clk_sel_2;
break;
case 0x74:
if (xga->bus & DEVICE_MCA)
ret = xga->regs[xga->regs_idx];
else {
ret = (xga->dma_channel << 1);
if (xga->dma_channel)
ret |= 1;
}
break;
default:
ret = xga->regs[xga->regs_idx];
break;
@@ -678,15 +747,35 @@ xga_ext_inb(uint16_t addr, void *p)
dat = xga->vram[(addr + 1) & (xga->vram_mask - 1)] & 0xff; \
dat |= (xga->vram[(addr) & (xga->vram_mask - 1)] << 8);
#define READL(addr, dat) \
dat = *(uint32_t *) &xga->vram[(addr) & (xga->vram_mask)];
#define READL_REVERSE(addr, dat) \
dat = xga->vram[(addr + 3) & (xga->vram_mask - 3)] & 0xff; \
dat |= (xga->vram[(addr + 2) & (xga->vram_mask - 3)] << 8); \
dat |= (xga->vram[(addr + 1) & (xga->vram_mask - 3)] << 16); \
dat |= (xga->vram[(addr) & (xga->vram_mask - 3)] << 24);
#define WRITEW(addr, dat) \
*(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
#define WRITEL(addr, dat) \
*(uint32_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
#define WRITEW_REVERSE(addr, dat) \
xga->vram[((addr + 1)) & (xga->vram_mask - 1)] = dat & 0xff; \
xga->vram[((addr)) & (xga->vram_mask - 1)] = dat >> 8; \
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
#define WRITEL_REVERSE(addr, dat) \
xga->vram[((addr + 3)) & (xga->vram_mask - 3)] = dat & 0xff; \
xga->vram[((addr + 2)) & (xga->vram_mask - 3)] = dat >> 8; \
xga->vram[((addr + 1)) & (xga->vram_mask - 3)] = dat >> 16; \
xga->vram[((addr)) & (xga->vram_mask - 3)] = dat >> 24; \
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
#define ROP(mix, d, s) \
{ \
switch ((mix) ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) { \
@@ -859,6 +948,23 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
byte = mem_readw_phys(addr);
}
return byte;
case 5: /*24-bit*/
addr += (y * (width << 2));
addr += (x << 2);
if (!skip) {
if ((xga->accel.px_map_format[map] & 8)) {
if (xga->linear_endian_reverse) {
READL(addr, byte);
} else {
READL_REVERSE(addr, byte);
}
} else {
READL(addr, byte);
}
} else {
byte = mem_readl_phys(addr);
}
return byte;
}
return 0;
@@ -936,6 +1042,22 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
}
mem_writew_phys(addr, pixel);
break;
case 5: /*24-bit*/
addr += (y * (width) << 2);
addr += (x << 2);
if (!skip) {
if ((xga->accel.px_map_format[map] & 8)) {
if (xga->linear_endian_reverse) {
WRITEL(addr, pixel);
} else {
WRITEL_REVERSE(addr, pixel);
}
} else {
WRITEL(addr, pixel);
}
}
mem_writel_phys(addr, pixel);
break;
}
}
@@ -1447,6 +1569,10 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
if (addr >= 0x1800) {
switch (addr & 0x7f) {
case 0x11:
xga->accel.control = val;
break;
case 0x12:
xga->accel.px_map_idx = val & 3;
break;
@@ -1923,11 +2049,21 @@ xga_mem_read(uint32_t addr, xga_t *xga, svga_t *svga)
uint8_t temp = 0;
addr &= 0x1fff;
if (addr < 0x1800) {
temp = xga->bios_rom.rom[addr];
if (!xga_has_vga)
temp = xga->bios_rom.rom[addr];
else
temp = xga->vga_bios_rom.rom[addr];
} else {
switch (addr & 0x7f) {
case 0x11:
temp = xga->accel.control;
if (xga->accel.control & 0x08)
temp |= 0x10;
else
temp &= ~0x10;
break;
case 0x20:
temp = xga->accel.bres_err_term & 0xff;
break;
@@ -2092,8 +2228,9 @@ xga_render_overscan_left(xga_t *xga, svga_t *svga)
if (svga->scrblank || (xga->h_disp == 0))
return;
uint32_t *line_ptr = svga->monitor->target_buffer->line[xga->displine + svga->y_add];
for (int i = 0; i < svga->x_add; i++)
buffer32->line[xga->displine + svga->y_add][i] = svga->overscan_color;
*line_ptr++ = svga->overscan_color;
}
static void
@@ -2107,9 +2244,10 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga)
if (svga->scrblank || (xga->h_disp == 0))
return;
right = (overscan_x >> 1);
uint32_t *line_ptr = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp];
right = (overscan_x >> 1);
for (int i = 0; i < right; i++)
buffer32->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp + i] = svga->overscan_color;
*line_ptr++ = svga->overscan_color;
}
static void
@@ -2122,7 +2260,7 @@ xga_render_8bpp(xga_t *xga, svga_t *svga)
return;
if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[xga->displine + svga->y_add][svga->x_add];
p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add];
if (xga->firstline_draw == 2000)
xga->firstline_draw = xga->displine;
@@ -2159,7 +2297,7 @@ xga_render_16bpp(xga_t *xga, svga_t *svga)
return;
if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) {
p = &buffer32->line[xga->displine + svga->y_add][svga->x_add];
p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add];
if (xga->firstline_draw == 2000)
xga->firstline_draw = xga->displine;
@@ -2524,7 +2662,7 @@ xga_poll(xga_t *xga, svga_t *svga)
}
xga->vc++;
xga->vc &= 2047;
xga->vc &= 0x7ff;
if (xga->vc == xga->split) {
if (xga->interlace && xga->oddeven)
@@ -2683,8 +2821,149 @@ static uint8_t
xga_pos_in(uint16_t addr, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = &svga->xga;
uint8_t ret = 0xff;
return (xga_mca_read(addr, svga));
if (xga_has_vga) {
switch (addr) {
case 0x0100:
case 0x0101:
if (xga->instance_isa == xga->instance_num)
ret = xga->pos_regs[addr & 7];
else
ret = 0xff;
break;
case 0x0102:
case 0x0105:
ret = xga->pos_regs[addr & 7];
break;
case 0x0106:
ret = xga->pos_idx >> 8;
break;
case 0x0107:
ret = xga->pos_idx & 0xff;
break;
case 0x0103:
if (!(xga->pos_idx & 3)) {
ret = xga->pos_regs[3];
} else
ret = 0;
//pclog("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret);
break;
case 0x0104:
switch (xga->pos_idx & 3) {
case 0:
ret = xga->pos_regs[4];
break;
case 1:
ret = xga->pos_regs[0];
break;
case 2:
ret = xga->pos_regs[1];
break;
case 3:
ret = 0;
break;
}
//pclog("POS IDX for 0104 = %d, ret = %02x.\n", xga->pos_idx & 3, ret);
break;
case 0x0108:
case 0x0109:
case 0x010a:
case 0x010b:
case 0x010c:
case 0x010d:
case 0x010e:
case 0x010f:
xga->instance_num = addr & 7;
if (xga->instance_isa == xga->instance_num)
ret = xga->instance_isa;
else
ret = 0;
ret |= xga->isa_pos_enable;
break;
}
} else {
switch (addr) {
case 0x0100:
case 0x0101:
ret = xga->pos_regs[addr & 7];
break;
case 0x0103:
ret = xga->pos_regs[3] | 7;
ret |= (xga->dma_channel << 3);
break;
case 0x0102:
case 0x0104:
case 0x0105:
case 0x0106:
case 0x0107:
ret = (xga_mca_read(addr, svga));
break;
case 0x0108:
case 0x0109:
case 0x010a:
case 0x010b:
case 0x010c:
case 0x010d:
case 0x010e:
case 0x010f:
xga->instance_num = addr & 7;
if (xga->instance_isa == xga->instance_num)
ret = xga->instance_isa;
else
ret = 0;
ret |= xga->isa_pos_enable;
break;
}
}
return ret;
}
static void
xga_pos_out(uint16_t addr, uint8_t val, void *priv)
{
svga_t *svga = (svga_t *) priv;
xga_t *xga = &svga->xga;
if (xga_has_vga) {
switch (addr) {
case 0x0106:
xga->pos_idx = (xga->pos_idx & 0x00ff) | (val << 8);
break;
case 0x0107:
xga->pos_idx = (xga->pos_idx & 0xff00) | (val);
//pclog("POS IDX Write = %04x.\n", xga->pos_idx);
break;
case 0x0108:
case 0x0109:
case 0x010a:
case 0x010b:
case 0x010c:
case 0x010d:
case 0x010e:
case 0x010f:
xga->instance_num = addr & 7;
xga->isa_pos_enable = val & 0x08;
break;
}
} else {
switch (addr) {
case 0x0108:
case 0x0109:
case 0x010a:
case 0x010b:
case 0x010c:
case 0x010d:
case 0x010e:
case 0x010f:
xga->instance_num = addr & 7;
xga->isa_pos_enable = val & 0x08;
break;
}
}
}
static void
@@ -2700,7 +2979,10 @@ static void
uint32_t temp;
uint8_t *rom = NULL;
xga->ext_mem_addr = device_get_config_hex16("ext_mem_addr");
xga->instance_isa = device_get_config_int("instance");
xga->type = device_get_config_int("type");
xga->dma_channel = device_get_config_int("dma");
xga->bus = info->flags;
xga->vram_size = (1024 << 10);
@@ -2739,12 +3021,16 @@ static void
xga->rom_addr = 0;
rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
} else {
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa);
xga->pos_regs[2] = 1 | 0x0c | 0xf0;
if (xga_has_vga) {
rom_init(&xga->vga_bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
} else
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa);
xga->pos_regs[2] = 1 | (xga->instance_isa << 1) | xga->ext_mem_addr;
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
xga->pos_regs[4] = 1 | 2;
xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22);
xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000);
xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000);
}
mem_mapping_add(&xga->video_mapping, 0, 0, xga_readb, xga_readw, xga_readl,
@@ -2755,7 +3041,7 @@ static void
NULL, MEM_MAPPING_EXTERNAL, svga);
mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl,
xga_memio_writeb, xga_memio_writew, xga_memio_writel,
xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga);
xga_has_vga ? xga->vga_bios_rom.rom : xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga);
mem_mapping_disable(&xga->video_mapping);
mem_mapping_disable(&xga->linear_mapping);
@@ -2768,13 +3054,41 @@ static void
mca_add(xga_mca_read, xga_mca_write, xga_mca_feedb, xga_mca_reset, svga);
} else {
io_sethandler(0x0100, 0x0008, xga_pos_in, NULL, NULL, NULL, NULL, NULL, svga);
if (xga_has_vga)
io_sethandler(0x0106, 0x0002, NULL, NULL, NULL, xga_pos_out, NULL, NULL, svga);
io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga);
io_sethandler(0x0108, 0x0008, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga);
mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80);
}
return svga;
}
static void
*
svga_xga_init(const device_t *info)
{
svga_t *svga = malloc(sizeof(svga_t));
memset(svga, 0, sizeof(svga_t));
video_inform(VIDEO_FLAG_TYPE_XGA, &timing_xga_isa);
svga_init(info, svga, svga, 1 << 18, /*256kB*/
NULL,
svga_xga_in, svga_xga_out,
NULL,
NULL);
io_sethandler(0x03c0, 0x0020, svga_xga_in, NULL, NULL, svga_xga_out, NULL, NULL, svga);
svga->bpp = 8;
svga->miscout = 1;
xga_has_vga = 1;
xga_enabled = 1;
return xga_init(info);
}
static void
xga_close(void *p)
{
@@ -2793,6 +3107,12 @@ xga_available(void)
return rom_present(XGA_BIOS_PATH) && rom_present(XGA2_BIOS_PATH);
}
static int
inmos_xga_available(void)
{
return rom_present(INMOS_XGA_BIOS_PATH);
}
static void
xga_speed_changed(void *p)
{
@@ -2809,7 +3129,7 @@ xga_force_redraw(void *p)
svga->fullchange = svga->monitor->mon_changeframecount;
}
static const device_config_t xga_configuration[] = {
static const device_config_t xga_mca_configuration[] = {
// clang-format off
{
.name = "type",
@@ -2835,6 +3155,91 @@ static const device_config_t xga_configuration[] = {
// clang-format on
};
static const device_config_t xga_isa_configuration[] = {
// clang-format off
{
.name = "type",
.description = "XGA type",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.selection = {
{
.description = "XGA-1",
.value = 0
},
{
.description = "XGA-2",
.value = 1
},
{ .description = "" }
}
},
{
.name = "instance",
.description = "Instance",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 6,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "0 (2100h-210Fh)", .value = 0 },
{ .description = "1 (2110h-211Fh)", .value = 1 },
{ .description = "2 (2120h-212Fh)", .value = 2 },
{ .description = "3 (2130h-213Fh)", .value = 3 },
{ .description = "4 (2140h-214Fh)", .value = 4 },
{ .description = "5 (2150h-215Fh)", .value = 5 },
{ .description = "6 (2160h-216Fh)", .value = 6 },
{ .description = "7 (2170h-217Fh)", .value = 7 },
{ .description = "" }
},
},
{
.name = "ext_mem_addr",
.description = "MMIO address",
.type = CONFIG_HEX16,
.default_string = "",
.default_int = 0x00f0,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "C800h", .value = 0x0040 },
{ .description = "CA00h", .value = 0x0050 },
{ .description = "CC00h", .value = 0x0060 },
{ .description = "CE00h", .value = 0x0070 },
{ .description = "D000h", .value = 0x0080 },
{ .description = "D200h", .value = 0x0090 },
{ .description = "D400h", .value = 0x00a0 },
{ .description = "D600h", .value = 0x00b0 },
{ .description = "D800h", .value = 0x00c0 },
{ .description = "DA00h", .value = 0x00d0 },
{ .description = "DC00h", .value = 0x00e0 },
{ .description = "DE00h", .value = 0x00f0 },
{ .description = "" }
},
},
{
.name = "dma",
.description = "DMA channel",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 7,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "Disabled", .value = 0 },
{ .description = "DMA 6", .value = 6 },
{ .description = "DMA 7", .value = 7 },
{ .description = "" }
},
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t xga_device = {
.name = "XGA (MCA)",
.internal_name = "xga_mca",
@@ -2846,7 +3251,7 @@ const device_t xga_device = {
{ .available = xga_available },
.speed_changed = xga_speed_changed,
.force_redraw = xga_force_redraw,
.config = xga_configuration
.config = xga_mca_configuration
};
const device_t xga_isa_device = {
@@ -2860,13 +3265,27 @@ const device_t xga_isa_device = {
{ .available = xga_available },
.speed_changed = xga_speed_changed,
.force_redraw = xga_force_redraw,
.config = xga_configuration
.config = xga_isa_configuration
};
const device_t inmos_isa_device = {
.name = "INMOS XGA (ISA)",
.internal_name = "inmos_xga_isa",
.flags = DEVICE_ISA | DEVICE_AT,
.local = 0,
.init = svga_xga_init,
.close = xga_close,
.reset = xga_reset,
{ .available = inmos_xga_available },
.speed_changed = xga_speed_changed,
.force_redraw = xga_force_redraw,
.config = xga_isa_configuration
};
void
xga_device_add(void)
{
if (!xga_enabled)
if (!xga_enabled || (xga_has_vga && xga_enabled))
return;
if (machine_has_bus(machine, MACHINE_BUS_MCA))

View File

@@ -242,13 +242,13 @@ PROG := 86Box
# Nothing should need changing from here on.. #
#########################################################################
VPATH := $(EXPATH) . $(CODEGEN) minitrace cpu cpu/softfloat \
cdrom chipset device disk disk/minivhd floppy \
cpu/808x cdrom chipset device disk disk/minivhd floppy \
game machine mem printer \
sio sound \
sound/munt sound/munt/c_interface sound/munt/sha1 \
sound/munt/srchelper sound/munt/srchelper/srctools/src \
sound/resid-fp sound/ymfm \
scsi video network network/slirp win
scsi video network win
WINDRES := windres
STRIP := strip
@@ -545,14 +545,16 @@ MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.
usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \
$(VNCOBJ)
MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o \
MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o row.o smram.o spd.o sst_flash.o \
815ep_spd_hack.o
CPU808XOBJ := queue.o
CPUOBJ := $(DYNARECOBJ) \
$(CGTOBJ) \
cpu.o cpu_table.o fpu.o x86.o \
8080.o 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \
x86seg.o x87.o x87_timings.o \
x86_ops_mmx.o x86seg.o x87.o x87_timings.o \
f2xm1.o fpatan.o fprem.o fsincos.o fyl2x.o softfloat_poly.o softfloat.o softfloat16.o \
softfloat-muladd.o softfloat-round-pack.o softfloat-specialize.o softfloatx80.o
@@ -661,18 +663,9 @@ SCSIOBJ := scsi.o scsi_device.o \
scsi_ncr5380.o scsi_ncr53c8xx.o \
scsi_pcscsi.o scsi_spock.o
SLIRPOBJ := net_slirp.o tinyglib.o \
arp_table.o bootp.o cksum.o dhcpv6.o dnssearch.o if.o \
ip_icmp.o ip_input.o ip_output.o \
ip6_icmp.o ip6_input.o ip6_output.o \
mbuf.o misc.o sbuf.o slirp.o socket.o \
tcp_input.o tcp_output.o tcp_subr.o tcp_timer.o \
udp.o udp6.o \
util.o version.o \
NETOBJ := network.o \
net_pcap.o \
${SLIRPOBJ} \
net_slirp.o \
net_dp8390.o net_3c501.o \
net_3c503.o net_ne2000.o \
net_pcnet.o net_wd8003.o \
@@ -727,6 +720,7 @@ VIDOBJ := agpgart.o video.o \
vid_vga.o \
vid_ati_eeprom.o \
vid_ati18800.o vid_ati28800.o \
vid_ati_mach8.o \
vid_ati_mach64.o vid_ati68860_ramdac.o \
vid_bt48x_ramdac.o \
vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \
@@ -788,7 +782,7 @@ ifeq ($(RTMIDI), y)
SNDOBJ += midi_rtmidi.o
endif
OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \
OBJ := $(MAINOBJ) $(CPU808XOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \
$(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \
$(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \
$(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ)
@@ -802,13 +796,24 @@ else
MWIN := -mwindows
endif
LIBS := -lfreetype -lfluidsynth -lslirp -lbz2 -lharfbuzz -lgraphite2 -lbrotlidec \
-lbrotlicommon -lusp10 -lrpcrt4 -lgomp -lsndfile -lflac -lmp3lame -lmpg123 \
-lopus -lvorbis -lvorbisenc -logg -ldsound -lshlwapi -lksuser -lreadline \
-ltermcap -lportaudio -lgmodule-2.0 -lglib-2.0 -lintl -liconv
ifeq ($(OPENAL), y)
LIBS := $(MWIN) -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32
LIBS += $(MWIN) -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \
-luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \
-luuid -lws2_32
else
ifeq ($(FAUDIO), y)
LIBS := $(MWIN) -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32
LIBS += $(MWIN) -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \
-luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \
-luuid -lws2_32
else
LIBS := $(MWIN) -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32
LIBS += $(MWIN) -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 \
-lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid \
-lws2_32
endif
endif