Merge branch '86Box:master' into machine_23

This commit is contained in:
BurnedPinguin
2023-07-22 11:40:21 +02:00
committed by GitHub
70 changed files with 9353 additions and 1659 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

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

@@ -213,7 +213,7 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv)
ali1489_t *dev = (ali1489_t *) priv;
uint8_t old;
uint8_t irq;
const uint8_t irq_array[16] = { 0, 3, 4, 7, 0, 0, 0, 0, 9, 10, 5, 6, 11, 12, 14, 15 };
const uint8_t irq_array[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 0, 11, 0, 12, 0, 14, 0, 15 };
switch (addr) {
case 0x22:

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

View File

@@ -223,10 +223,11 @@ extern void x386_dynarec_log(const char *fmt, ...);
static int
opVPCEXT(uint32_t fetchdat)
{
uint8_t b1, b2;
uint8_t b1;
uint8_t b2;
uint16_t cent;
time_t now;
struct tm *tm;
struct tm *tm = NULL;
if (!is_vpc) /* only emulate this on Virtual PC machines */
return ILLEGAL(fetchdat);

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

@@ -850,4 +850,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);
}

View File

@@ -51,8 +51,10 @@ opSETALC(uint32_t fetchdat)
static int
opF6_a16(uint32_t fetchdat)
{
int tempws, tempws2 = 0;
uint16_t tempw, src16;
int tempws = 0;
int tempws2 = 0;
uint16_t tempw = 0;
uint16_t src16;
uint8_t src, dst;
int8_t temps;
@@ -167,8 +169,10 @@ opF6_a16(uint32_t fetchdat)
static int
opF6_a32(uint32_t fetchdat)
{
int tempws, tempws2 = 0;
uint16_t tempw, src16;
int tempws = 0;
int tempws2 = 0;
uint16_t tempw = 0;
uint16_t src16;
uint8_t src, dst;
int8_t temps;
@@ -282,10 +286,13 @@ opF6_a32(uint32_t fetchdat)
static int
opF7_w_a16(uint32_t fetchdat)
{
uint32_t templ, templ2 = 0;
int tempws, tempws2 = 0;
uint32_t templ;
uint32_t templ2 = 0;
int tempws;
int tempws2 = 0;
int16_t temps16;
uint16_t src, dst;
uint16_t src;
uint16_t dst;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
@@ -392,8 +399,10 @@ opF7_w_a16(uint32_t fetchdat)
static int
opF7_w_a32(uint32_t fetchdat)
{
uint32_t templ, templ2 = 0;
int tempws, tempws2 = 1;
uint32_t templ;
uint32_t templ2 = 0;
int tempws;
int tempws2 = 1;
int16_t temps16;
uint16_t src, dst;

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

@@ -668,8 +668,8 @@ img_load(int drive, char *fn)
uint16_t track_bytes = 0;
uint8_t *literal;
img_t *dev;
int temp_rate;
int guess = 0;
int temp_rate = 0;
int guess = 0;
int size;
ext = path_get_extension(fn);

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

@@ -556,9 +556,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);

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

@@ -200,8 +200,8 @@ machine_at_p2bls_init(const machine_t *model)
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* SCSI */
pci_register_slot(0x07, PCI_CARD_NORMAL, 3, 4, 1, 2); /* LAN */
pci_register_slot(0x06, PCI_CARD_SCSI, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_NETWORK, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);

View File

@@ -2587,8 +2587,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,
@@ -2904,8 +2904,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,
@@ -2943,8 +2943,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,
@@ -4670,9 +4670,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,
@@ -4692,13 +4691,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,
@@ -4709,7 +4746,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",
@@ -4731,7 +4767,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

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

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

@@ -1513,14 +1513,14 @@ buslogic_init(const device_t *info)
{
x54x_t *dev;
char *bios_rom_name;
uint16_t bios_rom_size;
uint16_t bios_rom_mask;
uint16_t bios_rom_size = 0;
uint16_t bios_rom_mask = 0;
uint8_t has_autoscsi_rom;
char *autoscsi_rom_name;
uint16_t autoscsi_rom_size;
char *autoscsi_rom_name = NULL;
uint16_t autoscsi_rom_size = 0;
uint8_t has_scam_rom;
char *scam_rom_name;
uint16_t scam_rom_size;
char *scam_rom_name = NULL;
uint16_t scam_rom_size = 0;
FILE *f;
buslogic_data_t *bl;
uint32_t bios_rom_addr;

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

@@ -142,7 +142,7 @@ i82091aa_write(uint16_t port, uint8_t val, void *priv)
{
i82091aa_t *dev = (i82091aa_t *) priv;
uint8_t index;
uint8_t valxor;
uint8_t valxor = 0;
uint8_t uart = (dev->cur_reg >> 4) - 0x03;
uint8_t *reg = &(dev->regs[dev->cur_reg]);

View File

@@ -65,8 +65,8 @@ ad1848_updatevolmask(ad1848_t *ad1848)
static void
ad1848_updatefreq(ad1848_t *ad1848)
{
double freq;
uint8_t set = 0;
double freq = 0.0;
uint8_t set = 0;
if (ad1848->type >= AD1848_TYPE_CS4235) {
if (ad1848->xregs[11] & 0x20) {

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

@@ -311,7 +311,13 @@ es1371_reset(void *p)
/* Interrupt/Chip Select Control Register, Address 00H
Addressable as longword only */
dev->int_status = 0x7ffffec0;
/* Bit 13 is supposed to be always 1 on ES1371, and one of the GPIO interrupt
flags on ES1373. The 5.12.01 WDM driver only initializes its GPIO interrupt
handler on chip revisions which support this feature (1371 >= 0x04 and 5880
all), but calls it anyway during interrupt servicing regardless of revision,
crashing on ES1371 as soon as an interrupt arrives while that bit is set.
Pending hardware research because actual early ES1371 cards are rare. */
dev->int_status = 0x7fffdec0;
/* UART Status Register, Address 09H
Addressable as byte only */
@@ -621,11 +627,11 @@ es1371_inb(uint16_t port, void *p)
audiopci_log("[R] STATUS 8-15 = %02X\n", ret);
break;
case 0x06:
ret = (dev->int_status >> 16) & 0x0f;
ret = (dev->int_status >> 16) & 0xff;
audiopci_log("[R] STATUS 16-23 = %02X\n", ret);
break;
case 0x07:
ret = ((dev->int_status >> 24) & 0x03) | 0xfc;
ret = (dev->int_status >> 24) & 0xff;
audiopci_log("[R] STATUS 24-31 = %02X\n", ret);
break;
@@ -1551,7 +1557,7 @@ es1371_pci_read(int func, int addr, void *p)
return 0x00;
case 0x08:
return 0x08; /* Revision ID - 0x02 (datasheet, VMware) has issues with the 2001 Creative WDM driver */
return 0x02; /* Revision ID - 0x02 is supposed to be early Ensoniq-branded ES1371 but unconfirmed */
case 0x09:
return 0x00; /* Multimedia audio device */
case 0x0a:
@@ -2069,10 +2075,6 @@ static const device_config_t es1371_config[] = {
.description = "Crystal CS4297A",
.value = AC97_CODEC_CS4297A
},
{
.description = "SigmaTel STAC9708",
.value = AC97_CODEC_STAC9708
},
{
.description = "SigmaTel STAC9721",
.value = AC97_CODEC_STAC9721

View File

@@ -348,7 +348,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *p)
sb_t *sb = (sb_t *) p;
sb_ct1745_mixer_t *mixer = &sb->mixer_sb16;
int dsp_rec_pos = sb->dsp.record_pos_write;
int c_emu8k;
int c_emu8k = 0;
int c_record;
int32_t in_l;
int32_t in_r;

View File

@@ -79,15 +79,20 @@ static void
wss_get_buffer(int32_t *buffer, int len, void *priv)
{
wss_t *wss = (wss_t *) priv;
int32_t *opl_buf = NULL;
if (wss->opl_enabled)
opl_buf = wss->opl.update(wss->opl.priv);
int32_t *opl_buf = wss->opl.update(wss->opl.priv);
ad1848_update(&wss->ad1848);
for (int c = 0; c < len * 2; c++) {
buffer[c] += opl_buf[c];
if (opl_buf)
buffer[c] += opl_buf[c];
buffer[c] += wss->ad1848.buffer[c] / 2;
}
wss->opl.reset_buffer(wss->opl.priv);
if (wss->opl_enabled)
wss->opl.reset_buffer(wss->opl.priv);
wss->ad1848.pos = 0;
}

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:
@@ -3134,7 +3223,7 @@ uint8_t
mach64_ext_inb(uint16_t port, void *p)
{
mach64_t *mach64 = (mach64_t *) p;
uint8_t ret;
uint8_t ret = 0xff;
switch (port) {
case 0x02ec:
@@ -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)) {
@@ -2084,7 +2084,7 @@ et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4
uint8_t source;
uint8_t dest;
uint8_t rop;
uint8_t out;
uint8_t out = 0;
int mixmap;
if (!(et4000->acl.status & ACL_XYST) && !et4000->acl.mmu_start) {

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))
@@ -448,7 +504,7 @@ xga_ext_inb(uint16_t addr, void *p)
{
svga_t *svga = (svga_t *) p;
xga_t *xga = &svga->xga;
uint8_t ret;
uint8_t ret = 0xff;
uint8_t index;
switch (addr & 0x0f) {
@@ -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,7 +242,7 @@ 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 \
@@ -547,11 +547,13 @@ MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.
MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o row.o smram.o spd.o sst_flash.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
@@ -711,6 +713,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 \
@@ -772,7 +775,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)
@@ -786,15 +789,24 @@ else
MWIN := -mwindows
endif
LIBS := -lfluidsynth -lslirp -lgomp -lsndfile -lflac -lmp3lame -lmpg123 -lopus -lvorbis -lvorbisenc -logg -ldsound -lshlwapi -lksuser -lreadline -ltermcap -lportaudio -lgmodule-2.0 -lglib-2.0 -lintl -liconv
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