mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 17:45:31 -07:00
Merge remote-tracking branch 'upstream/master' into feature/mtrr
This commit is contained in:
21
.ci/build.sh
21
.ci/build.sh
@@ -540,12 +540,25 @@ then
|
||||
# Attempt to install dependencies.
|
||||
sudo "$macports/bin/port" install $(cat .ci/dependencies_macports.txt) 2>&1 | tee macports.log
|
||||
|
||||
# Stop if no port version activation errors were found.
|
||||
# Check for port activation errors.
|
||||
stuck_dep=$(grep " cannot be built while another version of " macports.log | cut -d" " -f10)
|
||||
[ -z $stuck_dep ] && break
|
||||
if [ -n "$stuck_dep" ]
|
||||
then
|
||||
# Deactivate the stuck dependency and try again.
|
||||
sudo "$macports/bin/port" -f deactivate "$stuck_dep"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Deactivate the stuck dependency and try again.
|
||||
sudo "$macports/bin/port" -f deactivate $stuck_dep
|
||||
stuck_dep=$(grep " Please deactivate this port first, or " macports.log | cut -d" " -f5 | tr -d :)
|
||||
if [ -n "$stuck_dep" ]
|
||||
then
|
||||
# Activate the stuck dependency and try again.
|
||||
sudo "$macports/bin/port" -f activate "$stuck_dep"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Stop if no errors were found.
|
||||
break
|
||||
done
|
||||
|
||||
# Remove MacPorts error detection log.
|
||||
|
||||
@@ -9,5 +9,6 @@ zlib
|
||||
libpng
|
||||
rtmidi
|
||||
libslirp
|
||||
fluidsynth
|
||||
qt5-static
|
||||
qt5-translations
|
||||
|
||||
21
.gitattributes
vendored
Normal file
21
.gitattributes
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.c text
|
||||
*.cc text
|
||||
*.cpp text
|
||||
*.h text
|
||||
*.hpp text
|
||||
*.rc text
|
||||
|
||||
|
||||
# Declare files that will always have CRLF line endings on checkout.
|
||||
*.sln text eol=crlf
|
||||
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
*.ico binary
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.dat
|
||||
8
.github/workflows/cmake.yml
vendored
8
.github/workflows/cmake.yml
vendored
@@ -115,7 +115,7 @@ jobs:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v1
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
@@ -234,7 +234,7 @@ jobs:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v1
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >
|
||||
@@ -341,7 +341,7 @@ jobs:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v1
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
@@ -427,7 +427,7 @@ jobs:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v1
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#
|
||||
|
||||
# Define our flags
|
||||
string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition")
|
||||
string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing")
|
||||
string(APPEND CMAKE_C_FLAGS_INIT " -std=c99 -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition")
|
||||
string(APPEND CMAKE_CXX_FLAGS_INIT " -std=c++11 -fomit-frame-pointer -Wall -fno-strict-aliasing")
|
||||
string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3")
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3")
|
||||
string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -ggdb -Og")
|
||||
|
||||
72
src/86box.c
72
src/86box.c
@@ -918,11 +918,15 @@ pc_init_modules(void)
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
# if defined(__APPLE__) && defined(__aarch64__)
|
||||
pthread_jit_write_protect_np(0);
|
||||
if (__builtin_available(macOS 11.0, *)) {
|
||||
pthread_jit_write_protect_np(0);
|
||||
}
|
||||
# endif
|
||||
codegen_init();
|
||||
# if defined(__APPLE__) && defined(__aarch64__)
|
||||
pthread_jit_write_protect_np(1);
|
||||
if (__builtin_available(macOS 11.0, *)) {
|
||||
pthread_jit_write_protect_np(1);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -1048,19 +1052,9 @@ pc_reset_hard_init(void)
|
||||
/* Initialize the actual machine and its basic modules. */
|
||||
machine_init();
|
||||
|
||||
/* Reset and reconfigure the serial ports. */
|
||||
serial_standalone_init();
|
||||
serial_passthrough_init();
|
||||
|
||||
/* Reset and reconfigure the Sound Card layer. */
|
||||
sound_card_reset();
|
||||
|
||||
/* Reset any ISA RTC cards. */
|
||||
isartc_reset();
|
||||
|
||||
fdc_card_init();
|
||||
|
||||
fdd_reset();
|
||||
/* Reset some basic devices. */
|
||||
speaker_init();
|
||||
shadowbios = 0;
|
||||
|
||||
/*
|
||||
* Once the machine has been initialized, all that remains
|
||||
@@ -1071,10 +1065,20 @@ pc_reset_hard_init(void)
|
||||
* that will be a call to device_reset_all() later !
|
||||
*/
|
||||
|
||||
/* Reset some basic devices. */
|
||||
speaker_init();
|
||||
if (joystick_type)
|
||||
gameport_update_joystick_type();
|
||||
|
||||
/* Reset and reconfigure the Sound Card layer. */
|
||||
sound_card_reset();
|
||||
|
||||
/* Reset and reconfigure the Network Card layer. */
|
||||
network_reset();
|
||||
|
||||
lpt_devices_init();
|
||||
shadowbios = 0;
|
||||
|
||||
/* Reset and reconfigure the serial ports. */
|
||||
serial_standalone_init();
|
||||
serial_passthrough_init();
|
||||
|
||||
/*
|
||||
* Reset the mouse, this will attach it to any port needed.
|
||||
@@ -1084,25 +1088,30 @@ pc_reset_hard_init(void)
|
||||
/* Reset the Hard Disk Controller module. */
|
||||
hdc_reset();
|
||||
|
||||
fdc_card_init();
|
||||
|
||||
fdd_reset();
|
||||
|
||||
/* Reset the CD-ROM Controller module. */
|
||||
cdrom_interface_reset();
|
||||
|
||||
/* Reset and reconfigure the SCSI layer. */
|
||||
scsi_card_init();
|
||||
|
||||
cdrom_hard_reset();
|
||||
scsi_disk_hard_reset();
|
||||
|
||||
zip_hard_reset();
|
||||
cdrom_hard_reset();
|
||||
|
||||
mo_hard_reset();
|
||||
|
||||
scsi_disk_hard_reset();
|
||||
zip_hard_reset();
|
||||
|
||||
/* Reset and reconfigure the Network Card layer. */
|
||||
network_reset();
|
||||
/* Reset any ISA RTC cards. */
|
||||
isartc_reset();
|
||||
|
||||
if (joystick_type)
|
||||
gameport_update_joystick_type();
|
||||
/* Initialize the Voodoo cards here inorder to minmize
|
||||
the chances of the SCSI controller ending up on the bridge. */
|
||||
video_voodoo_init();
|
||||
|
||||
ui_sb_update_panes();
|
||||
|
||||
@@ -1119,6 +1128,11 @@ pc_reset_hard_init(void)
|
||||
if (postcard_enabled)
|
||||
device_add(&postcard_device);
|
||||
|
||||
if (IS_ARCH(machine, MACHINE_BUS_PCI)) {
|
||||
pci_register_cards();
|
||||
device_reset_all(DEVICE_PCI);
|
||||
}
|
||||
|
||||
/* Reset the CPU module. */
|
||||
resetx86();
|
||||
dma_reset();
|
||||
@@ -1273,10 +1287,12 @@ pc_run(void)
|
||||
startblit();
|
||||
cpu_exec(cpu_s->rspeed / 100);
|
||||
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
|
||||
// if (gdbstub_step == GDBSTUB_EXEC)
|
||||
if (gdbstub_step == GDBSTUB_EXEC) {
|
||||
#endif
|
||||
#if 0
|
||||
mouse_process();
|
||||
if (!mouse_timed)
|
||||
mouse_process();
|
||||
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
|
||||
}
|
||||
#endif
|
||||
joystick_process();
|
||||
endblit();
|
||||
|
||||
15
src/acpi.c
15
src/acpi.c
@@ -124,18 +124,18 @@ acpi_update_irq(acpi_t *dev)
|
||||
|
||||
if (sci_level) {
|
||||
if (dev->irq_mode == 1)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state);
|
||||
else if (dev->irq_mode == 2)
|
||||
pci_set_mirq(5, dev->mirq_is_level);
|
||||
pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state);
|
||||
else
|
||||
pci_set_mirq(0xf0 | dev->irq_line, 1);
|
||||
pci_set_mirq(PCI_DIRQ_BASE | dev->irq_line, 1, &dev->irq_state);
|
||||
} else {
|
||||
if (dev->irq_mode == 1)
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
|
||||
else if (dev->irq_mode == 2)
|
||||
pci_clear_mirq(5, dev->mirq_is_level);
|
||||
pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state);
|
||||
else
|
||||
pci_clear_mirq(0xf0 | dev->irq_line, 1);
|
||||
pci_clear_mirq(PCI_DIRQ_BASE | dev->irq_line, 1, &dev->irq_state);
|
||||
}
|
||||
|
||||
acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS));
|
||||
@@ -1657,6 +1657,9 @@ acpi_reset(void *priv)
|
||||
dev->regs.pmsts |= 0x8000;
|
||||
|
||||
acpi_rtc_status = 0;
|
||||
|
||||
acpi_update_irq(dev);
|
||||
dev->irq_state = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -652,9 +652,7 @@ cdi_cue_get_buffer(char *str, char **line, int up)
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
#ifdef FALLTHROUGH_ANNOTATION
|
||||
[[fallthrough]];
|
||||
#endif
|
||||
fallthrough;
|
||||
|
||||
default:
|
||||
if (up && islower((int) *s))
|
||||
|
||||
@@ -331,7 +331,7 @@ viso_fill_fn_short(char *data, const viso_entry_t *entry, viso_entry_t **entries
|
||||
}
|
||||
|
||||
/* Check if this filename is unique, and add a tail if required, while also adding the extension. */
|
||||
char tail[8];
|
||||
char tail[16];
|
||||
for (int i = force_tail; i <= 999999; i++) {
|
||||
/* Add tail to the filename if this is not the first run. */
|
||||
int tail_len = -1;
|
||||
@@ -429,7 +429,7 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform)
|
||||
or way too far into 64-bit space (Linux). Fall back to epoch. */
|
||||
time_t epoch = 0;
|
||||
time_s = localtime(&epoch);
|
||||
if (!time_s)
|
||||
if (UNLIKELY(!time_s))
|
||||
fatal("VISO: localtime(0) = NULL\n");
|
||||
|
||||
/* Force year clamping if the timestamp is known to be outside the supported ranges. */
|
||||
@@ -636,12 +636,8 @@ pad_susp:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((p - data) > 255)
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
fatal("VISO: Directory record overflow (%d) on entry %016" PRIX64 "\n", (uint32_t) (uintptr_t) (p - data), (uint64_t) (uintptr_t) entry);
|
||||
#else
|
||||
fatal("VISO: Directory record overflow (%d) on entry %08X\n", (uint32_t) (uintptr_t) (p - data), (uint32_t) (uintptr_t) entry);
|
||||
#endif
|
||||
if (UNLIKELY((p - data) > 255))
|
||||
fatal("VISO: Directory record overflow (%" PRIuPTR ") on entry %08" PRIXPTR "\n", (uintptr_t) (p - data), (uintptr_t) entry);
|
||||
|
||||
data[0] = p - data; /* length */
|
||||
return data[0];
|
||||
|
||||
@@ -324,9 +324,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
case 5:
|
||||
dev->readmsf = 0;
|
||||
#ifdef FALLTHROUGH_ANNOTATION
|
||||
[[fallthrough]];
|
||||
#endif
|
||||
fallthrough;
|
||||
case 4:
|
||||
case 3:
|
||||
dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3);
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c ali1531.c ali1541.c ali1543.c
|
||||
ali1621.c ali6117.c headland.c ims8848.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c
|
||||
intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c
|
||||
opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
|
||||
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c
|
||||
sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c
|
||||
via_pipc.c vl82c480.c wd76c10.c)
|
||||
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c
|
||||
ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c ims8848.c intel_82335.c
|
||||
compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c
|
||||
intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c
|
||||
opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c sis_85c496.c
|
||||
sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c
|
||||
sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c
|
||||
via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
|
||||
|
||||
if(OLIVETTI)
|
||||
target_sources(chipset PRIVATE olivetti_eva.c)
|
||||
|
||||
@@ -46,11 +46,12 @@
|
||||
typedef struct ali_1435_t {
|
||||
uint8_t index;
|
||||
uint8_t cfg_locked;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t regs[16];
|
||||
uint8_t pci_regs[256];
|
||||
} ali1435_t;
|
||||
|
||||
#define ENABLE_ALI1435_LOG 1
|
||||
#ifdef ENABLE_ALI1435_LOG
|
||||
int ali1435_do_log = ENABLE_ALI1435_LOG;
|
||||
|
||||
@@ -190,24 +191,20 @@ ali1435_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
#if 0
|
||||
#ifdef ENABLE_ALI1435_LOG
|
||||
if (dev->index != 0x03)
|
||||
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
#endif
|
||||
#endif
|
||||
if (dev->index == 0x03)
|
||||
dev->cfg_locked = (val != 0x69);
|
||||
#ifdef ENABLE_ALI1435_LOG
|
||||
else
|
||||
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
#endif
|
||||
|
||||
if (!dev->cfg_locked) {
|
||||
pclog("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
switch (dev->index) {
|
||||
/* PCI Mechanism select? */
|
||||
case 0x00:
|
||||
dev->regs[dev->index] = val;
|
||||
pclog("PMC = %i\n", val != 0xc8);
|
||||
pci_set_pmc(val != 0xc8);
|
||||
ali1435_log("PMC = %i\n", val != 0xc8);
|
||||
pci_key_write(((val & 0xc8) == 0xc8) ? 0xf0 : 0x00);
|
||||
break;
|
||||
|
||||
/* ???? */
|
||||
@@ -253,8 +250,6 @@ ali1435_reset(void *priv)
|
||||
|
||||
dev->regs[0x00] = 0xff;
|
||||
|
||||
pci_set_pmc(0);
|
||||
|
||||
dev->cfg_locked = 1;
|
||||
|
||||
memset(dev->pci_regs, 0, 256);
|
||||
@@ -298,17 +293,10 @@ ali1435_init(UNUSED(const device_t *info))
|
||||
*/
|
||||
io_sethandler(0x0022, 0x0002, ali1435_read, NULL, NULL, ali1435_write, NULL, NULL, dev);
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
ali1435_reset(dev);
|
||||
|
||||
#if 0
|
||||
pci_set_irq_level(PCI_INTA, 0);
|
||||
pci_set_irq_level(PCI_INTB, 0);
|
||||
pci_set_irq_level(PCI_INTC, 0);
|
||||
pci_set_irq_level(PCI_INTD, 0);
|
||||
#endif
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
@@ -622,7 +622,7 @@ ali1489_init(UNUSED(const device_t *info))
|
||||
io_sethandler(0x0fc, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev);
|
||||
|
||||
/* Dummy M1489 PCI device */
|
||||
dev->pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct ali1531_t {
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t *smram;
|
||||
@@ -374,7 +379,7 @@ ali1531_init(UNUSED(const device_t *info))
|
||||
ali1531_t *dev = (ali1531_t *) malloc(sizeof(ali1531_t));
|
||||
memset(dev, 0, sizeof(ali1531_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->smram = smram_add();
|
||||
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct ali1541_t {
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t *smram;
|
||||
@@ -641,7 +646,7 @@ ali1541_init(UNUSED(const device_t *info))
|
||||
ali1541_t *dev = (ali1541_t *) malloc(sizeof(ali1541_t));
|
||||
memset(dev, 0, sizeof(ali1541_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->smram = smram_add();
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct ali1543_t {
|
||||
uint8_t mirq_states[8];
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pmu_conf[256];
|
||||
uint8_t usb_conf[256];
|
||||
@@ -1474,12 +1475,12 @@ ali7101_read(int func, int addr, void *priv)
|
||||
static void
|
||||
ali5237_usb_update_interrupt(usb_t* usb, void *priv)
|
||||
{
|
||||
const ali1543_t *dev = (ali1543_t *) priv;
|
||||
ali1543_t *dev = (ali1543_t *) priv;
|
||||
|
||||
if (usb->irq_level)
|
||||
pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
|
||||
pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]);
|
||||
else
|
||||
pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
|
||||
pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1595,16 +1596,16 @@ ali1543_init(const device_t *info)
|
||||
memset(dev, 0, sizeof(ali1543_t));
|
||||
|
||||
/* Device 02: M1533 Southbridge */
|
||||
dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev, &dev->pci_slot);
|
||||
|
||||
/* Device 0B: M5229 IDE Controller*/
|
||||
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev, &dev->ide_slot);
|
||||
|
||||
/* Device 0C: M7101 Power Managment Controller */
|
||||
dev->pmu_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev, &dev->pmu_slot);
|
||||
|
||||
/* Device 0F: M5237 USB */
|
||||
dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev, &dev->usb_slot);
|
||||
|
||||
/* ACPI */
|
||||
dev->acpi = device_add(&acpi_ali_device);
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct ali1621_t {
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t *smram[2];
|
||||
@@ -109,9 +114,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
|
||||
switch (val & 0x30) {
|
||||
case 0x10: /* Open. */
|
||||
access_normal = ACCESS_SMRAM_RX;
|
||||
#ifdef FALLTHROUGH_ANNOTATION
|
||||
[[fallthrough]];
|
||||
#endif
|
||||
fallthrough;
|
||||
case 0x30: /* Protect. */
|
||||
access_smm |= ACCESS_SMRAM_R;
|
||||
break;
|
||||
@@ -124,9 +127,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
|
||||
switch (val & 0x30) {
|
||||
case 0x10: /* Open. */
|
||||
access_normal |= ACCESS_SMRAM_W;
|
||||
#ifdef FALLTHROUGH_ANNOTATION
|
||||
[[fallthrough]];
|
||||
#endif
|
||||
fallthrough;
|
||||
case 0x30: /* Protect. */
|
||||
access_smm |= ACCESS_SMRAM_W;
|
||||
break;
|
||||
@@ -671,7 +672,7 @@ ali1621_init(UNUSED(const device_t *info))
|
||||
ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t));
|
||||
memset(dev, 0, sizeof(ali1621_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->smram[0] = smram_add();
|
||||
dev->smram[1] = smram_add();
|
||||
|
||||
@@ -234,9 +234,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
case 0x12:
|
||||
val &= 0xf7;
|
||||
#ifdef FALLTHROUGH_ANNOTATION
|
||||
[[fallthrough]];
|
||||
#endif
|
||||
fallthrough;
|
||||
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
|
||||
767
src/chipset/compaq_386.c
Normal file
767
src/chipset/compaq_386.c
Normal file
@@ -0,0 +1,767 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running 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.
|
||||
*
|
||||
* Emulation of the Compaq 386 memory controller.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2023 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#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>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#define RAM_DIAG_L_BASE_MEM_640KB 0x00
|
||||
#define RAM_DIAG_L_BASE_MEM_INV 0x10
|
||||
#define RAM_DIAG_L_BASE_MEM_512KB 0x20
|
||||
#define RAM_DIAG_L_BASE_MEM_256KB 0x30
|
||||
#define RAM_DIAG_L_BASE_MEM_MASK 0x30
|
||||
#define RAM_DIAG_L_PERMA_BITS 0x80
|
||||
|
||||
#define RAM_DIAG_H_SYS_RAM_4MB 0x01
|
||||
#define RAM_DIAG_H_SYS_RAM_1MB 0x02
|
||||
#define RAM_DIAG_H_SYS_RAM_NONE 0x03
|
||||
#define RAM_DIAG_H_SYS_RAM_MASK 0x03
|
||||
#define RAM_DIAG_H_MOD_A_RAM_4MB 0x04
|
||||
#define RAM_DIAG_H_MOD_A_RAM_1MB 0x08
|
||||
#define RAM_DIAG_H_MOD_A_RAM_NONE 0x0c
|
||||
#define RAM_DIAG_H_MOD_A_RAM_MASK 0x0c
|
||||
#define RAM_DIAG_H_MOD_B_RAM_4MB 0x10
|
||||
#define RAM_DIAG_H_MOD_B_RAM_1MB 0x20
|
||||
#define RAM_DIAG_H_MOD_B_RAM_NONE 0x30
|
||||
#define RAM_DIAG_H_MOD_B_RAM_MASK 0x30
|
||||
#define RAM_DIAG_H_MOD_C_RAM_4MB 0x40
|
||||
#define RAM_DIAG_H_MOD_C_RAM_1MB 0x80
|
||||
#define RAM_DIAG_H_MOD_C_RAM_NONE 0xc0
|
||||
#define RAM_DIAG_H_MOD_C_RAM_MASK 0xc0
|
||||
|
||||
#define MEM_STATE_BUS 0x00
|
||||
#define MEM_STATE_SYS 0x01
|
||||
#define MEM_STATE_SYS_RELOC 0x02
|
||||
#define MEM_STATE_MOD_A 0x04
|
||||
#define MEM_STATE_MOD_B 0x08
|
||||
#define MEM_STATE_MOD_C 0x10
|
||||
#define MEM_STATE_MASK (MEM_STATE_SYS | MEM_STATE_MOD_A | MEM_STATE_MOD_B | MEM_STATE_MOD_C)
|
||||
#define MEM_STATE_WP 0x20
|
||||
|
||||
typedef struct cpq_ram_t {
|
||||
uint8_t wp;
|
||||
|
||||
uint32_t phys_base;
|
||||
uint32_t virt_base;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
} cpq_ram_t;
|
||||
|
||||
typedef struct cpq_386_t {
|
||||
uint8_t regs[8];
|
||||
|
||||
uint8_t old_state[256];
|
||||
uint8_t mem_state[256];
|
||||
|
||||
uint32_t ram_bases[4];
|
||||
|
||||
uint32_t ram_sizes[4];
|
||||
uint32_t ram_map_sizes[4];
|
||||
|
||||
cpq_ram_t ram[4][64];
|
||||
cpq_ram_t high_ram[16];
|
||||
|
||||
mem_mapping_t regs_mapping;
|
||||
} cpq_386_t;
|
||||
|
||||
static uint8_t
|
||||
cpq_read_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
uint32_t old = addr;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = mem_read_ram(addr, priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
cpq_read_ramw(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
uint32_t old = addr;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = mem_read_ramw(addr, priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
cpq_read_raml(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint32_t ret = 0xffffffff;
|
||||
uint32_t old = addr;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = mem_read_raml(addr, priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_write_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint32_t old = addr;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
if (!dev->wp && (addr < (mem_size << 10)))
|
||||
mem_write_ram(addr, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_write_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint32_t old = addr;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
if (!dev->wp && (addr < (mem_size << 10)))
|
||||
mem_write_ramw(addr, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_write_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint32_t old = addr;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
if (!dev->wp && (addr < (mem_size << 10)))
|
||||
mem_write_raml(addr, val, priv);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
cpq_read_regs(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000000:
|
||||
case 0x00000001:
|
||||
/* RAM Diagnostics (Read Only) */
|
||||
case 0x00000002:
|
||||
case 0x00000003:
|
||||
/* RAM Setup Port (Read/Write) */
|
||||
ret = dev->regs[addr];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
cpq_read_regsw(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
ret = cpq_read_regs(addr, priv);
|
||||
ret |= (((uint16_t) cpq_read_regs(addr + 1, priv)) << 8);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
cpq_read_regsl(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
ret = cpq_read_regsw(addr, priv);
|
||||
ret |= (((uint32_t) cpq_read_regsw(addr + 2, priv)) << 16);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_recalc_state(cpq_386_t *dev, uint8_t i)
|
||||
{
|
||||
uint32_t addr;
|
||||
|
||||
addr = ((uint32_t) i) << 16;
|
||||
if (dev->mem_state[i] == 0x00)
|
||||
mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else if (dev->mem_state[i] == MEM_STATE_WP)
|
||||
mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_DISABLED);
|
||||
else if (dev->mem_state[i] & MEM_STATE_WP)
|
||||
mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
dev->old_state[i] = dev->mem_state[i];
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_recalc_states(cpq_386_t *dev)
|
||||
{
|
||||
/* Recalculate the entire 16 MB space. */
|
||||
for (uint16_t i = 0; i < 256; i++) {
|
||||
if (dev->mem_state[i] != dev->old_state[i])
|
||||
cpq_recalc_state(dev, i);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_recalc_cache(cpq_386_t *dev)
|
||||
{
|
||||
cpu_cache_ext_enabled = (dev->regs[0x00000002] & 0x40);
|
||||
cpu_update_waitstates();
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_recalc_ram(cpq_386_t *dev)
|
||||
{
|
||||
uint8_t sys_ram = (dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK) & 0x01;
|
||||
uint8_t setup_port = dev->regs[0x00000002] & 0x0f;
|
||||
uint8_t sys_min_high = sys_ram ? 0xfa : 0xf4;
|
||||
uint8_t ram_states[4] = { MEM_STATE_SYS, MEM_STATE_MOD_A,
|
||||
MEM_STATE_MOD_B, MEM_STATE_MOD_C };
|
||||
uint8_t ram_bases[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 } },
|
||||
{ { 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00 },
|
||||
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } },
|
||||
{ { 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x20, 0x20,
|
||||
0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 },
|
||||
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50,
|
||||
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 } },
|
||||
{ { 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60,
|
||||
0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x00, 0x00 },
|
||||
{ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
|
||||
0x00, 0x00, 0x90, 0x00, 0x00, 0xc0, 0xc0, 0xc0 } } };
|
||||
uint8_t ram_sizes[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x30, 0x00, 0x10, 0x20, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 } },
|
||||
{ { 0x00, 0x00, 0x10, 0x10, 0x10, 0x40, 0x10, 0x10,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 },
|
||||
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } },
|
||||
{ { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40,
|
||||
0x30, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 },
|
||||
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
|
||||
0x00, 0x10, 0x10, 0x30, 0x40, 0x40, 0x40, 0x40 } },
|
||||
{ { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10,
|
||||
0x00, 0x00, 0x10, 0x20, 0x30, 0x40, 0x00, 0x00 },
|
||||
{ 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x20, 0x30 } } };
|
||||
uint8_t size;
|
||||
uint8_t start;
|
||||
uint8_t end;
|
||||
uint8_t k;
|
||||
uint32_t virt_base;
|
||||
uint32_t virt_addr;
|
||||
uint32_t phys_addr;
|
||||
cpq_ram_t *cram;
|
||||
|
||||
for (uint16_t i = 0x10; i < sys_min_high; i++)
|
||||
dev->mem_state[i] &= ~MEM_STATE_MASK;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
for (uint8_t j = 0; j <= 64; j++) {
|
||||
if ((i >= 1) || (j >= 0x10))
|
||||
mem_mapping_disable(&dev->ram[i][j].mapping);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
size = ram_sizes[i][sys_ram][setup_port];
|
||||
if (size > 0x00) {
|
||||
start = ram_bases[i][sys_ram][setup_port];
|
||||
end = start + (size - 1);
|
||||
|
||||
virt_base = ((uint32_t) start) << 16;
|
||||
|
||||
for (uint16_t j = start; j <= end; j++) {
|
||||
k = j - start;
|
||||
if (i == 0)
|
||||
k += 0x10;
|
||||
|
||||
cram = &(dev->ram[i][k]);
|
||||
|
||||
dev->mem_state[j] |= ram_states[i];
|
||||
|
||||
cram->virt_base = ((uint32_t) j) << 16;
|
||||
cram->phys_base = cram->virt_base - virt_base + dev->ram_bases[i];
|
||||
|
||||
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
|
||||
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Recalculate the entire 16 MB space. */
|
||||
cpq_recalc_states(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_write_regs(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000000:
|
||||
case 0x00000001:
|
||||
/* RAM Relocation (Write Only) */
|
||||
dev->regs[addr + 4] = val;
|
||||
if (addr == 0x00000000) {
|
||||
dev->mem_state[0x0e] &= ~(MEM_STATE_SYS | MEM_STATE_WP);
|
||||
dev->mem_state[0x0f] &= ~(MEM_STATE_SYS | MEM_STATE_WP);
|
||||
dev->mem_state[0xfe] &= ~MEM_STATE_WP;
|
||||
dev->mem_state[0xff] &= ~MEM_STATE_WP;
|
||||
if (!(val & 0x01)) {
|
||||
dev->mem_state[0x0e] |= MEM_STATE_SYS;
|
||||
dev->mem_state[0x0f] |= MEM_STATE_SYS;
|
||||
}
|
||||
if (!(val & 0x02)) {
|
||||
dev->mem_state[0x0e] |= MEM_STATE_WP;
|
||||
dev->mem_state[0x0f] |= MEM_STATE_WP;
|
||||
dev->mem_state[0xfe] |= MEM_STATE_WP;
|
||||
dev->mem_state[0xff] |= MEM_STATE_WP;
|
||||
}
|
||||
cpq_recalc_state(dev, 0x0e);
|
||||
cpq_recalc_state(dev, 0x0f);
|
||||
cpq_recalc_state(dev, 0xfe);
|
||||
cpq_recalc_state(dev, 0xff);
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
break;
|
||||
case 0x00000002:
|
||||
case 0x00000003:
|
||||
/* RAM Setup Port (Read/Write) */
|
||||
dev->regs[addr] = val;
|
||||
if (addr == 0x00000002) {
|
||||
cpq_recalc_ram(dev);
|
||||
cpq_recalc_cache(dev);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_write_regsw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
|
||||
cpq_write_regs(addr, val & 0xff, priv);
|
||||
cpq_write_regs(addr + 1, (val >> 8) & 0xff, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_write_regsl(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
|
||||
cpq_write_regsw(addr, val & 0xff, priv);
|
||||
cpq_write_regsw(addr + 2, (val >> 16) & 0xff, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_ram_init(cpq_ram_t *dev)
|
||||
{
|
||||
mem_mapping_add(&dev->mapping,
|
||||
0x00000000,
|
||||
0x00010000,
|
||||
cpq_read_ram,
|
||||
cpq_read_ramw,
|
||||
cpq_read_raml,
|
||||
cpq_write_ram,
|
||||
cpq_write_ramw,
|
||||
cpq_write_raml,
|
||||
NULL,
|
||||
MEM_MAPPING_INTERNAL,
|
||||
dev);
|
||||
|
||||
mem_mapping_disable(&dev->mapping);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_ram_diags_parse(cpq_386_t *dev)
|
||||
{
|
||||
uint8_t val = dev->regs[0x00000001];
|
||||
uint32_t accum = 0x00100000;
|
||||
|
||||
val;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
dev->ram_bases[i] = accum;
|
||||
|
||||
switch (val & 0x03) {
|
||||
case RAM_DIAG_H_SYS_RAM_1MB:
|
||||
dev->ram_sizes[i] = 0x00100000;
|
||||
break;
|
||||
case RAM_DIAG_H_SYS_RAM_4MB:
|
||||
dev->ram_sizes[i] = 0x00400000;
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
dev->ram_sizes[i] -= 0x00100000;
|
||||
|
||||
dev->ram_map_sizes[i] = dev->ram_sizes[i];
|
||||
accum += dev->ram_sizes[i];
|
||||
|
||||
if (accum >= (mem_size << 10)) {
|
||||
dev->ram_sizes[i] = (mem_size << 10) - dev->ram_bases[i];
|
||||
break;
|
||||
}
|
||||
|
||||
val >>= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_recalc_base_ram(cpq_386_t *dev)
|
||||
{
|
||||
uint8_t base_mem = dev->regs[0x00000000] & RAM_DIAG_L_BASE_MEM_MASK;
|
||||
uint8_t sys_ram = dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK;
|
||||
uint8_t low_start = 0x00;
|
||||
uint8_t low_end = 0x00;
|
||||
uint8_t high_start = 0x00;
|
||||
uint8_t high_end = 0x00;
|
||||
uint32_t phys_addr = 0x00000000;
|
||||
uint32_t virt_addr = 0x00000000;
|
||||
cpq_ram_t *cram;
|
||||
|
||||
switch (base_mem) {
|
||||
case RAM_DIAG_L_BASE_MEM_256KB:
|
||||
switch (sys_ram) {
|
||||
case RAM_DIAG_H_SYS_RAM_1MB:
|
||||
low_start = 0x00;
|
||||
low_end = 0x03;
|
||||
high_start = 0xf4;
|
||||
high_end = 0xff;
|
||||
break;
|
||||
case RAM_DIAG_H_SYS_RAM_4MB:
|
||||
low_start = 0x00;
|
||||
low_end = 0x03;
|
||||
high_start = 0xfa;
|
||||
high_end = 0xff;
|
||||
break;
|
||||
default:
|
||||
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RAM_DIAG_L_BASE_MEM_512KB:
|
||||
switch (sys_ram) {
|
||||
case RAM_DIAG_H_SYS_RAM_1MB:
|
||||
low_start = 0x00;
|
||||
low_end = 0x07;
|
||||
high_start = 0xf8;
|
||||
high_end = 0xff;
|
||||
break;
|
||||
case RAM_DIAG_H_SYS_RAM_4MB:
|
||||
low_start = 0x00;
|
||||
low_end = 0x07;
|
||||
high_start = 0xfa;
|
||||
high_end = 0xff;
|
||||
break;
|
||||
default:
|
||||
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RAM_DIAG_L_BASE_MEM_640KB:
|
||||
switch (sys_ram) {
|
||||
case RAM_DIAG_H_SYS_RAM_1MB:
|
||||
low_start = 0x00;
|
||||
low_end = 0x09;
|
||||
high_start = 0xfa;
|
||||
high_end = 0xff;
|
||||
break;
|
||||
case RAM_DIAG_H_SYS_RAM_4MB:
|
||||
low_start = 0x00;
|
||||
low_end = 0x09;
|
||||
high_start = 0xfa;
|
||||
high_end = 0xff;
|
||||
break;
|
||||
default:
|
||||
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sys_ram) {
|
||||
case RAM_DIAG_H_SYS_RAM_1MB:
|
||||
if (mem_size < 1024)
|
||||
dev->regs[0x00000002] = 0x01;
|
||||
else if (mem_size == 8192)
|
||||
dev->regs[0x00000002] = 0x09;
|
||||
else if (mem_size >= 11264)
|
||||
dev->regs[0x00000002] = 0x0d;
|
||||
else
|
||||
dev->regs[0x00000002] = (mem_size >> 10);
|
||||
break;
|
||||
case RAM_DIAG_H_SYS_RAM_4MB:
|
||||
if (mem_size < 4096)
|
||||
dev->regs[0x00000002] = 0x04;
|
||||
else if (mem_size == 11264)
|
||||
dev->regs[0x00000002] = 0x0c;
|
||||
else if (mem_size >= 16384)
|
||||
dev->regs[0x00000002] = 0x00;
|
||||
else if (mem_size > 13312)
|
||||
dev->regs[0x00000002] = 0x0d;
|
||||
else
|
||||
dev->regs[0x00000002] = (mem_size >> 10);
|
||||
break;
|
||||
default:
|
||||
fatal("Compaq 386 - Invalid configuation: %02X\n", sys_ram);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The base 640 kB. */
|
||||
for (uint8_t i = low_start; i <= low_end; i++) {
|
||||
cram = &(dev->ram[0][i]);
|
||||
|
||||
cram->phys_base = cram->virt_base = ((uint32_t) i) << 16;
|
||||
dev->mem_state[i] |= MEM_STATE_SYS;
|
||||
|
||||
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
|
||||
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
|
||||
|
||||
cpq_recalc_state(dev, i);
|
||||
}
|
||||
|
||||
/* The relocated 128 kB. */
|
||||
for (uint8_t i = 0x0e; i <= 0x0f; i++) {
|
||||
cram = &(dev->ram[0][i]);
|
||||
|
||||
cram->phys_base = cram->virt_base = ((uint32_t) i) << 16;
|
||||
|
||||
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
|
||||
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
|
||||
}
|
||||
|
||||
/* Blocks FA-FF. */
|
||||
for (uint16_t i = high_start; i <= high_end; i++) {
|
||||
cram = &(dev->high_ram[i & 0x0f]);
|
||||
|
||||
cram->phys_base = ((uint32_t) (i & 0x0f)) << 16;
|
||||
cram->virt_base = ((uint32_t) i) << 16;
|
||||
dev->mem_state[i] |= MEM_STATE_SYS;
|
||||
|
||||
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
|
||||
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
|
||||
|
||||
cpq_recalc_state(dev, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_386_close(void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
compaq_386_init(const device_t *info)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) calloc(1, sizeof(cpq_386_t));
|
||||
|
||||
mem_mapping_add(&dev->regs_mapping,
|
||||
0x80c00000,
|
||||
0x00001000,
|
||||
cpq_read_regs,
|
||||
cpq_read_regsw,
|
||||
cpq_read_regsl,
|
||||
cpq_write_regs,
|
||||
cpq_write_regsw,
|
||||
cpq_write_regsl,
|
||||
NULL,
|
||||
MEM_MAPPING_INTERNAL,
|
||||
dev);
|
||||
|
||||
mem_set_mem_state(0x80c00000, 0x00001000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
dev->regs[0x00000000] = RAM_DIAG_L_PERMA_BITS;
|
||||
if (mem_size >= 640)
|
||||
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_640KB;
|
||||
else if (mem_size >= 512)
|
||||
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_512KB;
|
||||
else if (mem_size >= 256)
|
||||
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_256KB;
|
||||
else
|
||||
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_INV;
|
||||
/* Indicate no parity error. */
|
||||
dev->regs[0x00000000] |= 0x0f;
|
||||
|
||||
if (mem_size >= 1024) {
|
||||
switch (mem_size) {
|
||||
case 1024:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
|
||||
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
break;
|
||||
case 2048:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
|
||||
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
break;
|
||||
case 3072:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
|
||||
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
break;
|
||||
case 4096:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
|
||||
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
break;
|
||||
case 5120:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
break;
|
||||
case 6144:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
break;
|
||||
case 7168:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB;
|
||||
break;
|
||||
case 8192:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
break;
|
||||
case 9216:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
break;
|
||||
case 10240:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB;
|
||||
break;
|
||||
case 11264:
|
||||
case 12288:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
break;
|
||||
case 13312:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_1MB;
|
||||
break;
|
||||
case 14336:
|
||||
case 15360:
|
||||
case 16384:
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_4MB;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_1MB | RAM_DIAG_H_MOD_A_RAM_NONE |
|
||||
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
|
||||
|
||||
dev->regs[0x00000003] = 0xfc;
|
||||
dev->regs[0x00000004] = dev->regs[0x00000005] = 0xff;
|
||||
|
||||
compaq_ram_diags_parse(dev);
|
||||
|
||||
mem_mapping_disable(&ram_low_mapping);
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
/* Should never be the case, but you never know what a user may set. */
|
||||
if (mem_size > 1048576)
|
||||
mem_mapping_disable(&ram_2gb_mapping);
|
||||
#endif
|
||||
|
||||
/* Initialize in reverse order for memory mapping precedence
|
||||
reasons. */
|
||||
for (int8_t i = 3; i >= 0; i--) {
|
||||
for (uint8_t j = 0; j < 64; j++)
|
||||
compaq_ram_init(&(dev->ram[i][j]));
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++)
|
||||
compaq_ram_init(&(dev->high_ram[i]));
|
||||
|
||||
/* First, set the entire 256 MB of space to invalid states. */
|
||||
for (uint16_t i = 0; i < 256; i++)
|
||||
dev->old_state[i] = 0xff;
|
||||
|
||||
/* Then, recalculate the base RAM mappings. */
|
||||
compaq_recalc_base_ram(dev);
|
||||
|
||||
/* Enable the external cache. */
|
||||
dev->regs[0x00000002] |= 0x40;
|
||||
cpq_recalc_cache(dev);
|
||||
|
||||
/* Recalculate the rest of the RAM mapping. */
|
||||
cpq_recalc_ram(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t compaq_386_device = {
|
||||
.name = "Compaq 386 Memory Control",
|
||||
.internal_name = "opti391",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = compaq_386_init,
|
||||
.close = compaq_386_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -122,6 +122,9 @@
|
||||
typedef struct ims8848_t {
|
||||
uint8_t idx;
|
||||
uint8_t access_data;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
|
||||
uint8_t regs[256];
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
@@ -392,7 +395,7 @@ ims8848_init(UNUSED(const device_t *info))
|
||||
PCI Device 0: IMS 8849 Dummy for compatibility reasons
|
||||
*/
|
||||
io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->smram = smram_add();
|
||||
smram_set_separate_smram(1);
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
typedef struct i420ex_t {
|
||||
uint8_t has_ide;
|
||||
uint8_t smram_locked;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
|
||||
uint8_t regs[256];
|
||||
|
||||
uint16_t timer_base;
|
||||
@@ -534,7 +537,7 @@ i420ex_init(const device_t *info)
|
||||
|
||||
dev->smram = smram_add();
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->has_ide = info->local;
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@ typedef struct i4x0_t {
|
||||
uint8_t max_drb;
|
||||
uint8_t drb_unit;
|
||||
uint8_t drb_default;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t regs[256];
|
||||
uint8_t regs_locked[256];
|
||||
uint8_t mem_state[256];
|
||||
@@ -1241,12 +1244,12 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
switch (dev->type) {
|
||||
case INTEL_440FX:
|
||||
regs[0x93] = (val & 0x0f);
|
||||
trc_write(0x0093, val & 0x06, NULL);
|
||||
pci_write(0x0cf9, val & 0x06, NULL);
|
||||
break;
|
||||
case INTEL_440LX:
|
||||
case INTEL_440EX:
|
||||
regs[0x93] = (val & 0x0e);
|
||||
trc_write(0x0093, val & 0x06, NULL);
|
||||
pci_write(0x0cf9, val & 0x06, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1518,7 +1521,7 @@ i4x0_read(int func, int addr, void *priv)
|
||||
/* Special behavior for 440FX register 0x93 which is basically TRC in PCI space
|
||||
with the addition of bits 3 and 0. */
|
||||
if ((func == 0) && (addr == 0x93) && ((dev->type == INTEL_440FX) || (dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)))
|
||||
ret = (ret & 0xf9) | (trc_read(0x0093, NULL) & 0x06);
|
||||
ret = (ret & 0xf9) | (pci_read(0x0cf9, NULL) & 0x06);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1910,7 +1913,7 @@ i4x0_init(const device_t *info)
|
||||
(dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev);
|
||||
}
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev, &dev->pci_slot);
|
||||
|
||||
if ((dev->type >= INTEL_440BX) && !(regs[0x7a] & 0x02)) {
|
||||
device_add((dev->type == INTEL_440GX) ? &i440gx_agp_device : &i440bx_agp_device);
|
||||
|
||||
@@ -62,11 +62,15 @@ i450kx_log(const char *fmt, ...)
|
||||
typedef struct i450kx_t {
|
||||
smram_t *smram[2];
|
||||
|
||||
uint8_t bus_index;
|
||||
uint8_t pb_slot;
|
||||
uint8_t mc_slot;
|
||||
uint8_t pad;
|
||||
|
||||
uint8_t pb_pci_conf[256];
|
||||
uint8_t mc_pci_conf[256];
|
||||
uint8_t mem_state[2][256];
|
||||
|
||||
uint8_t bus_index;
|
||||
uint8_t mem_state[2][256];
|
||||
} i450kx_t;
|
||||
|
||||
static void
|
||||
@@ -801,8 +805,8 @@ i450kx_init(UNUSED(const device_t *info))
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *) malloc(sizeof(i450kx_t));
|
||||
memset(dev, 0, sizeof(i450kx_t));
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19h: Intel 450KX PCI Bridge PB */
|
||||
pci_add_card(PCI_ADD_AGPBRIDGE, mc_read, mc_write, dev); /* Device 14h: Intel 450KX Memory Controller MC */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev, &dev->pb_slot); /* Device 19h: Intel 450KX PCI Bridge PB */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE_SEC, mc_read, mc_write, dev, &dev->mc_slot); /* Device 14h: Intel 450KX Memory Controller MC */
|
||||
|
||||
dev->smram[0] = smram_add();
|
||||
dev->smram[1] = smram_add();
|
||||
|
||||
@@ -66,7 +66,7 @@ typedef struct _piix_ {
|
||||
uint8_t max_func;
|
||||
uint8_t pci_slot;
|
||||
uint8_t no_mirq0;
|
||||
uint8_t pad;
|
||||
uint8_t usb_irq_state;
|
||||
uint8_t regs[4][256];
|
||||
uint8_t readout_regs[256];
|
||||
uint8_t board_config[2];
|
||||
@@ -1446,12 +1446,12 @@ piix_fast_off_count(void *priv)
|
||||
static void
|
||||
piix_usb_update_interrupt(usb_t* usb, void *priv)
|
||||
{
|
||||
const piix_t *dev = (piix_t *) priv;
|
||||
piix_t *dev = (piix_t *) priv;
|
||||
|
||||
if (usb->irq_level)
|
||||
pci_set_irq(dev->pci_slot, PCI_INTD);
|
||||
pci_set_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->pci_slot, PCI_INTD);
|
||||
pci_clear_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1574,7 +1574,7 @@ piix_init(const device_t *info)
|
||||
dev->no_mirq0 = (info->local >> 12) & 0x0f;
|
||||
dev->func0_id = info->local >> 16;
|
||||
|
||||
dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev, &dev->pci_slot);
|
||||
piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot);
|
||||
piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot);
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@
|
||||
|
||||
typedef struct sio_t {
|
||||
uint8_t id;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
|
||||
uint8_t regs[256];
|
||||
|
||||
uint16_t timer_base;
|
||||
@@ -507,7 +511,7 @@ sio_init(const device_t *info)
|
||||
sio_t *dev = (sio_t *) malloc(sizeof(sio_t));
|
||||
memset(dev, 0, sizeof(sio_t));
|
||||
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->id = info->local;
|
||||
|
||||
|
||||
@@ -229,9 +229,7 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
case 0x14:
|
||||
reset_on_hlt = !!(val & 0x40);
|
||||
#ifdef FALLTHROUGH_ANNOTATION
|
||||
[[fallthrough]];
|
||||
#endif
|
||||
fallthrough;
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
|
||||
typedef struct opti822_t {
|
||||
uint8_t irq_convert;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
|
||||
uint8_t pci_regs[256];
|
||||
} opti822_t;
|
||||
|
||||
@@ -393,7 +397,7 @@ opti822_init(UNUSED(const device_t *info))
|
||||
opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t));
|
||||
memset(dev, 0, sizeof(opti822_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
opti822_reset(dev);
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dev->regs[dev->idx] = val;
|
||||
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
|
||||
|
||||
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
|
||||
switch (dev->idx) {
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
@@ -213,12 +214,14 @@ opti895_read(uint16_t addr, void *priv)
|
||||
ret = dev->regs[dev->idx];
|
||||
break;
|
||||
case 0x24:
|
||||
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
|
||||
ret = dev->regs[dev->idx];
|
||||
if (dev->idx == 0xe0)
|
||||
ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[addr - 0xe1];
|
||||
|
||||
@@ -66,13 +66,15 @@ sis_5511_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5511_t {
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[2][256];
|
||||
uint8_t index;
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t pad;
|
||||
|
||||
uint8_t regs[16];
|
||||
|
||||
int nb_pci_slot;
|
||||
int sb_pci_slot;
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[2][256];
|
||||
|
||||
sff8038i_t *ide_drive[2];
|
||||
smram_t *smram;
|
||||
@@ -713,8 +715,8 @@ sis_5511_reset(void *priv)
|
||||
dev->pci_conf_sb[1][0x0a] = 1;
|
||||
dev->pci_conf_sb[1][0x0b] = 1;
|
||||
dev->pci_conf_sb[1][0x0e] = 0x80;
|
||||
sff_set_slot(dev->ide_drive[0], dev->sb_pci_slot);
|
||||
sff_set_slot(dev->ide_drive[1], dev->sb_pci_slot);
|
||||
sff_set_slot(dev->ide_drive[0], dev->sb_slot);
|
||||
sff_set_slot(dev->ide_drive[1], dev->sb_slot);
|
||||
sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE);
|
||||
sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8);
|
||||
}
|
||||
@@ -734,8 +736,8 @@ sis_5511_init(UNUSED(const device_t *info))
|
||||
sis_5511_t *dev = (sis_5511_t *) malloc(sizeof(sis_5511_t));
|
||||
memset(dev, 0, sizeof(sis_5511_t));
|
||||
|
||||
dev->nb_pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev); /* Device 0: SiS 5511 */
|
||||
dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev); /* Device 1: SiS 5513 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); /* Device 0: SiS 5511 */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot); /* Device 1: SiS 5513 */
|
||||
io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); /* Ports 22h-23h: SiS 5513 ISA */
|
||||
|
||||
/* MIRQ */
|
||||
|
||||
@@ -75,12 +75,14 @@ sis_5571_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5571_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t pad;
|
||||
uint8_t usb_irq_state;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[3][256];
|
||||
|
||||
int nb_pci_slot;
|
||||
int sb_pci_slot;
|
||||
|
||||
port_92_t *port_92;
|
||||
sff8038i_t *ide_drive[2];
|
||||
smram_t *smram;
|
||||
@@ -670,7 +672,7 @@ pci_isa_bridge_read(int func, int addr, void *priv)
|
||||
static void
|
||||
sis_5571_usb_update_interrupt(usb_t* usb, void* priv)
|
||||
{
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
if (dev->pci_conf_sb[0][0x68] & 0x80) {
|
||||
/* TODO: Is the normal PCI interrupt inhibited when USB IRQ remapping is enabled? */
|
||||
@@ -691,9 +693,9 @@ sis_5571_usb_update_interrupt(usb_t* usb, void* priv)
|
||||
}
|
||||
} else {
|
||||
if (usb->irq_level)
|
||||
pci_set_irq(dev->sb_pci_slot, PCI_INTA);
|
||||
pci_set_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->sb_pci_slot, PCI_INTA);
|
||||
pci_clear_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,8 +741,8 @@ sis_5571_reset(void *priv)
|
||||
dev->pci_conf_sb[1][0x0b] = 0x01;
|
||||
dev->pci_conf_sb[1][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[1][0x4a] = 0x06;
|
||||
sff_set_slot(dev->ide_drive[0], dev->sb_pci_slot);
|
||||
sff_set_slot(dev->ide_drive[1], dev->sb_pci_slot);
|
||||
sff_set_slot(dev->ide_drive[0], dev->sb_slot);
|
||||
sff_set_slot(dev->ide_drive[1], dev->sb_slot);
|
||||
sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE);
|
||||
sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8);
|
||||
|
||||
@@ -773,8 +775,8 @@ sis_5571_init(UNUSED(const device_t *info))
|
||||
sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t));
|
||||
memset(dev, 0x00, sizeof(sis_5571_t));
|
||||
|
||||
dev->nb_pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev);
|
||||
dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot);
|
||||
|
||||
/* MIRQ */
|
||||
pci_enable_mirq(0);
|
||||
|
||||
@@ -45,9 +45,13 @@
|
||||
typedef struct sis_85c496_t {
|
||||
uint8_t cur_reg;
|
||||
uint8_t rmsmiblk_count;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
#ifndef USE_DRB_HACK
|
||||
uint8_t drb_default;
|
||||
uint8_t drb_bits;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
#endif
|
||||
uint8_t regs[127];
|
||||
uint8_t pci_conf[256];
|
||||
@@ -648,7 +652,7 @@ static void
|
||||
dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */
|
||||
dev->pci_conf[0xd1] = 0xff;
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
#if 0
|
||||
sis_85c497_isa_reset(dev);
|
||||
|
||||
@@ -59,6 +59,10 @@ sis_85c50x_log(const char *fmt, ...)
|
||||
|
||||
typedef struct sis_85c50x_t {
|
||||
uint8_t index;
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t pad;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[256];
|
||||
uint8_t regs[256];
|
||||
@@ -426,10 +430,10 @@ sis_85c50x_init(UNUSED(const device_t *info))
|
||||
memset(dev, 0x00, sizeof(sis_85c50x_t));
|
||||
|
||||
/* 501/502 (Northbridge) */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev, &dev->nb_slot);
|
||||
|
||||
/* 503 (Southbridge) */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev, &dev->sb_slot);
|
||||
io_sethandler(0x0022, 0x0002, sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev);
|
||||
|
||||
dev->smram[0] = smram_add();
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
#define STPC_CLIENT 0x100e55cc
|
||||
|
||||
typedef struct stpc_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t ide_slot;
|
||||
uint8_t usb_slot;
|
||||
|
||||
uint32_t local;
|
||||
|
||||
/* Main registers (port 22h/23h) */
|
||||
@@ -54,19 +59,19 @@ typedef struct stpc_t {
|
||||
/* Host bus interface */
|
||||
uint16_t host_base;
|
||||
uint8_t host_offset;
|
||||
uint8_t usb_irq_state;
|
||||
uint8_t host_regs[256];
|
||||
|
||||
/* Local bus */
|
||||
uint16_t localbus_base;
|
||||
uint8_t localbus_offset;
|
||||
uint8_t pad0;
|
||||
uint8_t localbus_regs[256];
|
||||
|
||||
/* PCI devices */
|
||||
uint8_t pci_conf[4][256];
|
||||
smram_t *smram;
|
||||
usb_t *usb;
|
||||
int ide_slot;
|
||||
int usb_slot;
|
||||
sff8038i_t *bm[2];
|
||||
|
||||
/* Miscellaneous */
|
||||
@@ -896,12 +901,12 @@ stpc_setup(stpc_t *dev)
|
||||
static void
|
||||
stpc_usb_update_interrupt(usb_t* usb, void* priv)
|
||||
{
|
||||
const stpc_t *dev = (stpc_t *) priv;
|
||||
stpc_t *dev = (stpc_t *) priv;
|
||||
|
||||
if (usb->irq_level)
|
||||
pci_set_irq(dev->usb_slot, PCI_INTA);
|
||||
pci_set_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->usb_slot, PCI_INTA);
|
||||
pci_clear_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -926,16 +931,16 @@ stpc_init(const device_t *info)
|
||||
|
||||
dev->local = info->local;
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev);
|
||||
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev, &dev->nb_slot);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev, &dev->sb_slot);
|
||||
if (dev->local == STPC_ATLAS) {
|
||||
dev->usb_params.smi_handle = NULL;
|
||||
dev->usb_params.update_interrupt = stpc_usb_update_interrupt;
|
||||
dev->usb_params.parent_priv = dev;
|
||||
|
||||
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_ide_read, stpc_ide_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, stpc_ide_read, stpc_ide_write, dev, &dev->ide_slot);
|
||||
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
|
||||
dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_usb_read, stpc_usb_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, stpc_usb_read, stpc_usb_write, dev, &dev->usb_slot);
|
||||
}
|
||||
|
||||
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
|
||||
@@ -121,8 +121,13 @@ umc_8886_log(const char *fmt, ...)
|
||||
#define SB_ID dev->sb_id
|
||||
|
||||
typedef struct umc_8886_t {
|
||||
uint8_t max_func; /* Last function number */
|
||||
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
|
||||
uint8_t max_func; /* Last function number */
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
|
||||
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
|
||||
|
||||
uint16_t sb_id; /* Southbridge Revision */
|
||||
int has_ide; /* Check if Southbridge Revision is AF or F */
|
||||
} umc_8886_t;
|
||||
@@ -371,7 +376,7 @@ umc_8886_init(const device_t *info)
|
||||
memset(dev, 0, sizeof(umc_8886_t));
|
||||
|
||||
dev->has_ide = !!(info->local == 0x886a);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev); /* Device 12: UMC 8886xx */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Device 12: UMC 8886xx */
|
||||
|
||||
/* Add IDE if UM8886AF variant */
|
||||
if (HAS_IDE)
|
||||
|
||||
@@ -146,6 +146,8 @@ typedef struct hb4_t {
|
||||
uint8_t shadow;
|
||||
uint8_t shadow_read;
|
||||
uint8_t shadow_write;
|
||||
uint8_t pci_slot;
|
||||
|
||||
uint8_t pci_conf[256]; /* PCI Registers */
|
||||
int mem_state[9];
|
||||
smram_t *smram[3]; /* SMRAM Handlers */
|
||||
@@ -393,7 +395,7 @@ hb4_init(UNUSED(const device_t *info))
|
||||
hb4_t *dev = (hb4_t *) malloc(sizeof(hb4_t));
|
||||
memset(dev, 0, sizeof(hb4_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev); /* Device 10: UMC 8881x */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev, &dev->pci_slot); /* Device 10: UMC 8881x */
|
||||
|
||||
/* Port 92 */
|
||||
device_add(&port_92_pci_device);
|
||||
|
||||
@@ -45,10 +45,15 @@
|
||||
#define VIA_8601 0x86010500
|
||||
|
||||
typedef struct via_apollo_t {
|
||||
uint32_t id;
|
||||
uint8_t drb_unit;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
uint32_t id;
|
||||
|
||||
smram_t *smram;
|
||||
agpgart_t *agpgart;
|
||||
} via_apollo_t;
|
||||
@@ -715,7 +720,7 @@ via_apollo_init(const device_t *info)
|
||||
if (dev->id != VIA_8601)
|
||||
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->id = info->local;
|
||||
|
||||
|
||||
@@ -117,9 +117,10 @@ typedef struct {
|
||||
} pipc_io_trap_t;
|
||||
|
||||
typedef struct _pipc_ {
|
||||
uint32_t local;
|
||||
uint8_t max_func;
|
||||
uint8_t max_pcs;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
|
||||
uint8_t pci_isa_regs[256];
|
||||
uint8_t ide_regs[256];
|
||||
@@ -129,10 +130,11 @@ typedef struct _pipc_ {
|
||||
uint8_t fmnmi_regs[4];
|
||||
uint8_t fmnmi_status;
|
||||
|
||||
uint32_t local;
|
||||
|
||||
sff8038i_t *bm[2];
|
||||
nvr_t *nvr;
|
||||
int nvr_enabled;
|
||||
int slot;
|
||||
ddma_t *ddma;
|
||||
smbus_piix4_t *smbus;
|
||||
usb_t *usb[2];
|
||||
@@ -1094,7 +1096,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
||||
|
||||
case 0x47:
|
||||
if (val & 0x01)
|
||||
trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL);
|
||||
pci_write(0x0cf9, (val & 0x80) ? 0x06 : 0x04, NULL);
|
||||
pic_set_shadow(!!(val & 0x10));
|
||||
pic_elcr_io_handler(!!(val & 0x20));
|
||||
dev->pci_isa_regs[0x47] = val & 0xfe;
|
||||
@@ -1475,9 +1477,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0xd2:
|
||||
if (dev->local == VIA_PIPC_686B)
|
||||
smbus_piix4_setclock(dev->smbus, (val & 0x04) ? 65536 : 16384);
|
||||
#ifdef FALLTHROUGH_ANNOTATION
|
||||
[[fallthrough]];
|
||||
#endif
|
||||
fallthrough;
|
||||
|
||||
case 0x90:
|
||||
case 0x91:
|
||||
@@ -1620,6 +1620,14 @@ pipc_reset(void *priv)
|
||||
pipc_write(0, 0x44, 0x00, priv);
|
||||
|
||||
pipc_write(0, 0x77, 0x00, priv);
|
||||
|
||||
sff_set_slot(dev->bm[0], dev->pci_slot);
|
||||
sff_set_slot(dev->bm[1], dev->pci_slot);
|
||||
|
||||
if (dev->local >= VIA_PIPC_686A)
|
||||
ac97_via_set_slot(dev->ac97, dev->pci_slot, PCI_INTC);
|
||||
if (dev->acpi)
|
||||
acpi_set_slot(dev->acpi, dev->pci_slot);
|
||||
}
|
||||
|
||||
static void *
|
||||
@@ -1631,16 +1639,14 @@ pipc_init(const device_t *info)
|
||||
pipc_log("PIPC: init()\n");
|
||||
|
||||
dev->local = info->local;
|
||||
dev->slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
sff_set_slot(dev->bm[0], dev->slot);
|
||||
sff_set_irq_mode(dev->bm[0], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[0], 1, 0);
|
||||
sff_set_irq_pin(dev->bm[0], PCI_INTA);
|
||||
|
||||
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
|
||||
sff_set_slot(dev->bm[1], dev->slot);
|
||||
sff_set_irq_mode(dev->bm[1], 0, 0);
|
||||
sff_set_irq_mode(dev->bm[1], 1, 0);
|
||||
sff_set_irq_pin(dev->bm[1], PCI_INTA);
|
||||
@@ -1665,7 +1671,6 @@ pipc_init(const device_t *info)
|
||||
dev->usb[1] = device_add_inst(&usb_device, 2);
|
||||
|
||||
dev->ac97 = device_add(&ac97_via_device);
|
||||
ac97_via_set_slot(dev->ac97, dev->slot, PCI_INTC);
|
||||
|
||||
dev->sb = device_add_inst(&sb_pro_compat_device, 2);
|
||||
sound_add_handler(pipc_sb_get_buffer, dev);
|
||||
@@ -1695,7 +1700,6 @@ pipc_init(const device_t *info)
|
||||
dev->ddma = device_add(&ddma_device);
|
||||
|
||||
if (dev->acpi) {
|
||||
acpi_set_slot(dev->acpi, dev->slot);
|
||||
acpi_set_nvr(dev->acpi, dev->nvr);
|
||||
|
||||
acpi_init_gporeg(dev->acpi, 0xff, 0xbf, 0xff, 0x7f);
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
|
||||
typedef struct vt82c505_t {
|
||||
uint8_t index;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
} vt82c505_t;
|
||||
|
||||
@@ -203,7 +207,7 @@ vt82c505_init(UNUSED(const device_t *info))
|
||||
vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t));
|
||||
memset(dev, 0, sizeof(vt82c505_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev);
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->pci_conf[0x00] = 0x06;
|
||||
dev->pci_conf[0x01] = 0x11;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#if defined __aarch64__ || defined _M_ARM64
|
||||
|
||||
# include <inttypes.h>
|
||||
# include <stdint.h>
|
||||
# include <86box/86box.h>
|
||||
# include "cpu.h"
|
||||
@@ -340,7 +341,7 @@ host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm
|
||||
} else if (imm_data & 0xfff000)
|
||||
codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1));
|
||||
} else
|
||||
fatal("ADD_IMM_X %016llx\n", imm_data);
|
||||
fatal("ADD_IMM_X %016" PRIu64 "\n", imm_data);
|
||||
}
|
||||
void
|
||||
host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
|
||||
@@ -662,7 +663,7 @@ host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data)
|
||||
} else if (!(imm_data & 0xfffffffffffff000ull)) {
|
||||
codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0));
|
||||
} else
|
||||
fatal("CMNX_IMM %08x\n", imm_data);
|
||||
fatal("CMNX_IMM %016" PRIx64 "\n", imm_data);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -683,7 +684,7 @@ host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data)
|
||||
} else if (!(imm_data & 0xfffffffffffff000ull)) {
|
||||
codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0));
|
||||
} else
|
||||
fatal("CMPX_IMM %08x\n", imm_data);
|
||||
fatal("CMPX_IMM %08" PRIu64 "\n", imm_data);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -553,7 +553,7 @@ codegen_FABS(codeblock_t *block, uop_t *uop)
|
||||
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) {
|
||||
host_arm64_FABS_D(block, dest_reg, src_reg_a);
|
||||
} else
|
||||
fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
fatal("codegen_FABS %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -566,7 +566,7 @@ codegen_FCHS(codeblock_t *block, uop_t *uop)
|
||||
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) {
|
||||
host_arm64_FNEG_D(block, dest_reg, src_reg_a);
|
||||
} else
|
||||
fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
fatal("codegen_FCHS %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -579,7 +579,7 @@ codegen_FSQRT(codeblock_t *block, uop_t *uop)
|
||||
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) {
|
||||
host_arm64_FSQRT_D(block, dest_reg, src_reg_a);
|
||||
} else
|
||||
fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
fatal("codegen_FSQRT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1548,7 +1548,7 @@ codegen_PF2ID(codeblock_t *block, uop_t *uop)
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) {
|
||||
host_arm64_FCVTZS_V2S(block, dest_reg, src_reg_a);
|
||||
} else
|
||||
fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real);
|
||||
fatal("PF2ID %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1655,7 +1655,7 @@ codegen_PFRCP(codeblock_t *block, uop_t *uop)
|
||||
host_arm64_FDIV_S(block, dest_reg, REG_V_TEMP, src_reg_a);
|
||||
host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0);
|
||||
} else
|
||||
fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real);
|
||||
fatal("PFRCP %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1672,7 +1672,7 @@ codegen_PFRSQRT(codeblock_t *block, uop_t *uop)
|
||||
host_arm64_FDIV_S(block, dest_reg, dest_reg, REG_V_TEMP);
|
||||
host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0);
|
||||
} else
|
||||
fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real);
|
||||
fatal("PFRSQRT %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1698,7 +1698,7 @@ codegen_PI2FD(codeblock_t *block, uop_t *uop)
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) {
|
||||
host_arm64_SCVTF_V2S(block, dest_reg, src_reg_a);
|
||||
} else
|
||||
fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real);
|
||||
fatal("PI2FD %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -305,7 +306,7 @@ add_to_block_list(codeblock_t *block)
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
if (!block->page_mask)
|
||||
fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask, block->page_mask2);
|
||||
fatal("add_to_block_list - mask = 0 %" PRIx64 " %" PRIx64 "\n", block->page_mask, block->page_mask2);
|
||||
#endif
|
||||
|
||||
if (block_prev_nr) {
|
||||
|
||||
236
src/cpu/386.c
236
src/cpu/386.c
@@ -12,17 +12,22 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/gdbstub.h>
|
||||
#ifndef OPS_286_386
|
||||
# define OPS_286_386
|
||||
#endif
|
||||
#include "386_common.h"
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# include "codegen.h"
|
||||
@@ -33,54 +38,7 @@
|
||||
|
||||
extern int codegen_flags_changed;
|
||||
|
||||
int tempc, oldcpl, optype, inttype, oddeven = 0;
|
||||
int timetolive;
|
||||
|
||||
uint16_t oldcs;
|
||||
|
||||
uint32_t oldds, oldss, olddslimit, oldsslimit,
|
||||
olddslimitw, oldsslimitw;
|
||||
uint32_t oxpc;
|
||||
uint32_t rmdat32;
|
||||
uint32_t backupregs[16];
|
||||
|
||||
x86seg _oldds;
|
||||
|
||||
#if 1
|
||||
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
|
||||
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
|
||||
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */
|
||||
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x3x */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */
|
||||
1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */
|
||||
3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */
|
||||
3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */
|
||||
3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */
|
||||
1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */
|
||||
#else
|
||||
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
|
||||
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
|
||||
3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x2x */
|
||||
3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x3x */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */
|
||||
1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */
|
||||
3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */
|
||||
3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */
|
||||
3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */
|
||||
3, 1, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */
|
||||
#endif
|
||||
static int fpu_cycles = 0;
|
||||
|
||||
#ifdef ENABLE_386_LOG
|
||||
int x386_do_log = ENABLE_386_LOG;
|
||||
@@ -103,9 +61,6 @@ x386_log(const char *fmt, ...)
|
||||
#undef CPU_BLOCK_END
|
||||
#define CPU_BLOCK_END()
|
||||
|
||||
#include "x86_flags.h"
|
||||
|
||||
/*
|
||||
#define getbytef() \
|
||||
((uint8_t) (fetchdat)); \
|
||||
cpu_state.pc++
|
||||
@@ -118,40 +73,169 @@ x386_log(const char *fmt, ...)
|
||||
#define getword2f() \
|
||||
((uint16_t) (fetchdat >> 8)); \
|
||||
cpu_state.pc += 2
|
||||
*/
|
||||
|
||||
#define OP_TABLE(name) ops_##name
|
||||
static __inline void
|
||||
fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (cpu_rm == 4) {
|
||||
uint8_t sib = rmdat >> 8;
|
||||
|
||||
#if 0
|
||||
# define CLOCK_CYCLES(c) \
|
||||
{ \
|
||||
if (fpu_cycles > 0) { \
|
||||
fpu_cycles -= (c); \
|
||||
if (fpu_cycles < 0) { \
|
||||
cycles += fpu_cycles; \
|
||||
} \
|
||||
} else { \
|
||||
cycles -= (c); \
|
||||
} \
|
||||
switch (cpu_mod) {
|
||||
case 0:
|
||||
cpu_state.eaaddr = cpu_state.regs[sib & 7].l;
|
||||
cpu_state.pc++;
|
||||
break;
|
||||
case 1:
|
||||
cpu_state.pc++;
|
||||
cpu_state.eaaddr = ((uint32_t) (int8_t) getbyte()) + cpu_state.regs[sib & 7].l;
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
|
||||
cpu_state.pc += 5;
|
||||
break;
|
||||
}
|
||||
/*SIB byte present*/
|
||||
if ((sib & 7) == 5 && !cpu_mod)
|
||||
cpu_state.eaaddr = getlong();
|
||||
else if ((sib & 6) == 4 && !cpu_state.ssegs) {
|
||||
easeg = ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
|
||||
} else {
|
||||
cpu_state.eaaddr = cpu_state.regs[cpu_rm].l;
|
||||
if (cpu_mod) {
|
||||
if (cpu_rm == 5 && !cpu_state.ssegs) {
|
||||
easeg = ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
if (cpu_mod == 1) {
|
||||
cpu_state.eaaddr += ((uint32_t) (int8_t) (rmdat >> 8));
|
||||
cpu_state.pc++;
|
||||
} else {
|
||||
cpu_state.eaaddr += getlong();
|
||||
}
|
||||
} else if (cpu_rm == 5) {
|
||||
cpu_state.eaaddr = getlong();
|
||||
}
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) {
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if (readlookup2[addr >> 12] != (uintptr_t) -1)
|
||||
eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != (uintptr_t) -1)
|
||||
eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
}
|
||||
|
||||
# define CLOCK_CYCLES_FPU(c) cycles -= (c)
|
||||
# define CONCURRENCY_CYCLES(c) fpu_cycles = (c)
|
||||
#else
|
||||
# define CLOCK_CYCLES(c) cycles -= (c)
|
||||
# define CLOCK_CYCLES_FPU(c) cycles -= (c)
|
||||
# define CONCURRENCY_CYCLES(c)
|
||||
static __inline void
|
||||
fetch_ea_16_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (!cpu_mod && cpu_rm == 6) {
|
||||
cpu_state.eaaddr = getword();
|
||||
} else {
|
||||
switch (cpu_mod) {
|
||||
case 0:
|
||||
cpu_state.eaaddr = 0;
|
||||
break;
|
||||
case 1:
|
||||
cpu_state.eaaddr = (uint16_t) (int8_t) (rmdat >> 8);
|
||||
cpu_state.pc++;
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.eaaddr = getword();
|
||||
break;
|
||||
}
|
||||
cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
|
||||
if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) {
|
||||
easeg = ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
cpu_state.eaaddr &= 0xFFFF;
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) {
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if (readlookup2[addr >> 12] != (uintptr_t) -1)
|
||||
eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != (uintptr_t) -1)
|
||||
eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) \
|
||||
cpu_state.pc++; \
|
||||
cpu_mod = (rmdat >> 6) & 3; \
|
||||
cpu_reg = (rmdat >> 3) & 7; \
|
||||
cpu_rm = rmdat & 7; \
|
||||
if (cpu_mod != 3) { \
|
||||
fetch_ea_16_long(rmdat); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
}
|
||||
#define fetch_ea_32(rmdat) \
|
||||
cpu_state.pc++; \
|
||||
cpu_mod = (rmdat >> 6) & 3; \
|
||||
cpu_reg = (rmdat >> 3) & 7; \
|
||||
cpu_rm = rmdat & 7; \
|
||||
if (cpu_mod != 3) { \
|
||||
fetch_ea_32_long(rmdat); \
|
||||
} \
|
||||
if (cpu_state.abrt) \
|
||||
return 1
|
||||
|
||||
#include "x86_flags.h"
|
||||
|
||||
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
|
||||
do { \
|
||||
if (cpu_prefetch_cycles) \
|
||||
prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); \
|
||||
} while (0)
|
||||
|
||||
#define PREFETCH_PREFIX() \
|
||||
do { \
|
||||
if (cpu_prefetch_cycles) \
|
||||
prefetch_prefixes++; \
|
||||
} while (0)
|
||||
#define PREFETCH_FLUSH() prefetch_flush()
|
||||
|
||||
#ifndef FPU_CYCLES
|
||||
# define FPU_CYCLES
|
||||
#endif
|
||||
|
||||
#define OP_TABLE(name) ops_2386_##name
|
||||
#define CLOCK_CYCLES(c) \
|
||||
{ \
|
||||
if (fpu_cycles > 0) { \
|
||||
fpu_cycles -= (c); \
|
||||
if (fpu_cycles < 0) { \
|
||||
cycles += fpu_cycles; \
|
||||
} \
|
||||
} else { \
|
||||
cycles -= (c); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLOCK_CYCLES_FPU(c) cycles -= (c)
|
||||
#define CONCURRENCY_CYCLES(c) fpu_cycles = (c)
|
||||
|
||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||
|
||||
#include "x86_ops.h"
|
||||
#include "386_ops.h"
|
||||
|
||||
void
|
||||
exec386(int cycs)
|
||||
exec386_2386(int cycs)
|
||||
{
|
||||
int vector, tempi, cycdiff, oldcyc;
|
||||
int cycle_period, ins_cycles;
|
||||
int vector;
|
||||
int tempi;
|
||||
int cycdiff;
|
||||
int oldcyc;
|
||||
int cycle_period;
|
||||
int ins_cycles;
|
||||
uint32_t addr;
|
||||
|
||||
cycles += cycs;
|
||||
@@ -184,7 +268,7 @@ exec386(int cycs)
|
||||
if (!cpu_state.abrt) {
|
||||
#ifdef ENABLE_386_LOG
|
||||
if (in_smm)
|
||||
x386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
|
||||
x386_2386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
|
||||
#endif
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "386_common.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg.h"
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
# include "codegen.h"
|
||||
@@ -34,19 +35,26 @@
|
||||
# define CPU_BLOCK_END()
|
||||
#endif
|
||||
|
||||
x86seg gdt, ldt, idt, tr;
|
||||
x86seg gdt;
|
||||
x86seg ldt;
|
||||
x86seg idt;
|
||||
x86seg tr;
|
||||
|
||||
uint32_t cr2, cr3, cr4;
|
||||
uint32_t cr2;
|
||||
uint32_t cr3;
|
||||
uint32_t cr4;
|
||||
uint32_t dr[8];
|
||||
|
||||
uint32_t use32;
|
||||
int stack32;
|
||||
|
||||
uint32_t *eal_r, *eal_w;
|
||||
uint32_t *eal_r;
|
||||
uint32_t *eal_w;
|
||||
|
||||
int nmi_enable = 1;
|
||||
|
||||
int alt_access, cpl_override = 0;
|
||||
int alt_access;
|
||||
int cpl_override = 0;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint16_t cpu_cur_status = 0;
|
||||
@@ -59,16 +67,60 @@ extern uint8_t *pccache2;
|
||||
extern int optype;
|
||||
extern uint32_t pccache;
|
||||
|
||||
int in_sys = 0, unmask_a20_in_smm = 0;
|
||||
uint32_t old_rammask = 0xffffffff;
|
||||
int in_sys = 0;
|
||||
int unmask_a20_in_smm = 0;
|
||||
uint32_t old_rammask = 0xffffffff;
|
||||
|
||||
int soft_reset_mask = 0;
|
||||
|
||||
int smi_latched = 0;
|
||||
int smm_in_hlt = 0, smi_block = 0;
|
||||
int smm_in_hlt = 0;
|
||||
int smi_block = 0;
|
||||
|
||||
uint32_t addr64, addr64_2;
|
||||
uint32_t addr64a[8], addr64a_2[8];
|
||||
int prefetch_prefixes = 0;
|
||||
|
||||
int tempc;
|
||||
int oldcpl;
|
||||
int optype;
|
||||
int inttype;
|
||||
int oddeven = 0;
|
||||
int timetolive;
|
||||
|
||||
uint16_t oldcs;
|
||||
|
||||
uint32_t oldds;
|
||||
uint32_t oldss;
|
||||
uint32_t olddslimit;
|
||||
uint32_t oldsslimit;
|
||||
uint32_t olddslimitw;
|
||||
uint32_t oldsslimitw;
|
||||
uint32_t oxpc;
|
||||
uint32_t rmdat32;
|
||||
uint32_t backupregs[16];
|
||||
|
||||
x86seg _oldds;
|
||||
|
||||
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
|
||||
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
|
||||
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */
|
||||
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x3x */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */
|
||||
1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */
|
||||
3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */
|
||||
3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */
|
||||
3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */
|
||||
1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */
|
||||
|
||||
uint32_t addr64;
|
||||
uint32_t addr64_2;
|
||||
uint32_t addr64a[8];
|
||||
uint32_t addr64a_2[8];
|
||||
|
||||
static pc_timer_t *cpu_fast_off_timer = NULL;
|
||||
static double cpu_fast_off_period = 0.0;
|
||||
@@ -321,6 +373,77 @@ x386_common_log(const char *fmt, ...)
|
||||
# define x386_common_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
/*Prefetch emulation is a fairly simplistic model:
|
||||
- All instruction bytes must be fetched before it starts.
|
||||
- Cycles used for non-instruction memory accesses are counted and subtracted
|
||||
from the total cycles taken
|
||||
- Any remaining cycles are used to refill the prefetch queue.
|
||||
|
||||
Note that this is only used for 286 / 386 systems. It is disabled when the
|
||||
internal cache on 486+ CPUs is enabled.
|
||||
*/
|
||||
static int prefetch_bytes = 0;
|
||||
|
||||
void
|
||||
prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32)
|
||||
{
|
||||
int mem_cycles = reads * cpu_cycles_read + reads_l * cpu_cycles_read_l + writes * cpu_cycles_write + writes_l * cpu_cycles_write_l;
|
||||
|
||||
if (instr_cycles < mem_cycles)
|
||||
instr_cycles = mem_cycles;
|
||||
|
||||
prefetch_bytes -= prefetch_prefixes;
|
||||
prefetch_bytes -= bytes;
|
||||
if (modrm != -1) {
|
||||
if (ea32) {
|
||||
if ((modrm & 7) == 4) {
|
||||
if ((modrm & 0x700) == 0x500)
|
||||
prefetch_bytes -= 5;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 5;
|
||||
} else {
|
||||
if ((modrm & 0xc7) == 0x05)
|
||||
prefetch_bytes -= 4;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes--;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 4;
|
||||
}
|
||||
} else {
|
||||
if ((modrm & 0xc7) == 0x06)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) != 0xc0)
|
||||
prefetch_bytes -= ((modrm & 0xc0) >> 6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill up prefetch queue */
|
||||
while (prefetch_bytes < 0) {
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
/* Subtract cycles used for memory access by instruction */
|
||||
instr_cycles -= mem_cycles;
|
||||
|
||||
while (instr_cycles >= cpu_prefetch_cycles) {
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
instr_cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
prefetch_prefixes = 0;
|
||||
if (prefetch_bytes > 16)
|
||||
prefetch_bytes = 16;
|
||||
}
|
||||
|
||||
void
|
||||
prefetch_flush(void)
|
||||
{
|
||||
prefetch_bytes = 0;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
set_stack32(int s)
|
||||
{
|
||||
@@ -391,12 +514,10 @@ smm_seg_load(x86seg *s)
|
||||
static void
|
||||
smram_save_state_p5(uint32_t *saved_state, int in_hlt)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
saved_state[SMRAM_FIELD_P5_SMM_REVISION_ID] = SMM_REVISION_ID;
|
||||
saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase;
|
||||
|
||||
for (n = 0; n < 8; n++)
|
||||
for (uint8_t n = 0; n < 8; n++)
|
||||
saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l;
|
||||
|
||||
if (in_hlt)
|
||||
@@ -485,9 +606,7 @@ smram_save_state_p5(uint32_t *saved_state, int in_hlt)
|
||||
static void
|
||||
smram_restore_state_p5(uint32_t *saved_state)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (n = 0; n < 8; n++)
|
||||
for (uint8_t n = 0; n < 8; n++)
|
||||
cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n];
|
||||
|
||||
if (saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] & 0xffff)
|
||||
@@ -598,12 +717,10 @@ smram_restore_state_p5(uint32_t *saved_state)
|
||||
static void
|
||||
smram_save_state_p6(uint32_t *saved_state, int in_hlt)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
saved_state[SMRAM_FIELD_P6_SMM_REVISION_ID] = SMM_REVISION_ID;
|
||||
saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase;
|
||||
|
||||
for (n = 0; n < 8; n++)
|
||||
for (uint8_t n = 0; n < 8; n++)
|
||||
saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l;
|
||||
|
||||
if (in_hlt)
|
||||
@@ -684,9 +801,7 @@ smram_save_state_p6(uint32_t *saved_state, int in_hlt)
|
||||
static void
|
||||
smram_restore_state_p6(uint32_t *saved_state)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (n = 0; n < 8; n++)
|
||||
for (uint8_t n = 0; n < 8; n++)
|
||||
cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n];
|
||||
|
||||
if (saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] & 0xffff)
|
||||
@@ -791,12 +906,10 @@ smram_restore_state_p6(uint32_t *saved_state)
|
||||
static void
|
||||
smram_save_state_amd_k(uint32_t *saved_state, int in_hlt)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
saved_state[SMRAM_FIELD_AMD_K_SMM_REVISION_ID] = SMM_REVISION_ID;
|
||||
saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase;
|
||||
|
||||
for (n = 0; n < 8; n++)
|
||||
for (uint8_t n = 0; n < 8; n++)
|
||||
saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l;
|
||||
|
||||
if (in_hlt)
|
||||
@@ -876,9 +989,7 @@ smram_save_state_amd_k(uint32_t *saved_state, int in_hlt)
|
||||
static void
|
||||
smram_restore_state_amd_k(uint32_t *saved_state)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (n = 0; n < 8; n++)
|
||||
for (uint8_t n = 0; n < 8; n++)
|
||||
cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n];
|
||||
|
||||
if (saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] & 0xffff)
|
||||
@@ -977,7 +1088,7 @@ smram_restore_state_amd_k(uint32_t *saved_state)
|
||||
}
|
||||
|
||||
static void
|
||||
smram_save_state_cyrix(uint32_t *saved_state, int in_hlt)
|
||||
smram_save_state_cyrix(uint32_t *saved_state, UNUSED(int in_hlt))
|
||||
{
|
||||
saved_state[0] = dr[7];
|
||||
saved_state[1] = cpu_state.flags | (cpu_state.eflags << 16);
|
||||
@@ -1001,7 +1112,7 @@ smram_restore_state_cyrix(uint32_t *saved_state)
|
||||
void
|
||||
enter_smm(int in_hlt)
|
||||
{
|
||||
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
|
||||
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE];
|
||||
uint32_t smram_state = smbase + 0x10000;
|
||||
|
||||
/* If it's a CPU on which SMM is not supported, do nothing. */
|
||||
@@ -1053,13 +1164,13 @@ enter_smm(int in_hlt)
|
||||
|
||||
memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t));
|
||||
|
||||
if (is_cxsmm) /* Cx6x86 */
|
||||
if (is_cxsmm) /* Cx6x86 */
|
||||
smram_save_state_cyrix(saved_state, in_hlt);
|
||||
else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */
|
||||
smram_save_state_p5(saved_state, in_hlt);
|
||||
else if (is_k5 || is_k6) /* AMD K5 and K6 */
|
||||
else if (is_k5 || is_k6) /* AMD K5 and K6 */
|
||||
smram_save_state_amd_k(saved_state, in_hlt);
|
||||
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
|
||||
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
|
||||
smram_save_state_p6(saved_state, in_hlt);
|
||||
|
||||
cr0 &= ~0x8000000d;
|
||||
@@ -1128,7 +1239,7 @@ enter_smm(int in_hlt)
|
||||
writememl(0, smram_state - 0x18, saved_state[5]);
|
||||
writememl(0, smram_state - 0x24, saved_state[6]);
|
||||
} else {
|
||||
for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
|
||||
for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
|
||||
smram_state -= 4;
|
||||
writememl(0, smram_state, saved_state[n]);
|
||||
}
|
||||
@@ -1188,7 +1299,7 @@ enter_smm_check(int in_hlt)
|
||||
void
|
||||
leave_smm(void)
|
||||
{
|
||||
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
|
||||
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE];
|
||||
uint32_t smram_state = smbase + 0x10000;
|
||||
|
||||
/* If it's a CPU on which SMM is not supported (or not implemented in 86Box), do nothing. */
|
||||
@@ -1209,7 +1320,7 @@ leave_smm(void)
|
||||
cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs);
|
||||
saved_state[6] = readmeml(0, smram_state - 0x24);
|
||||
} else {
|
||||
for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
|
||||
for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
|
||||
smram_state -= 4;
|
||||
saved_state[n] = readmeml(0, smram_state);
|
||||
x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n);
|
||||
@@ -1224,13 +1335,13 @@ leave_smm(void)
|
||||
}
|
||||
|
||||
x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]);
|
||||
if (is_cxsmm) /* Cx6x86 */
|
||||
if (is_cxsmm) /* Cx6x86 */
|
||||
smram_restore_state_cyrix(saved_state);
|
||||
else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */
|
||||
smram_restore_state_p5(saved_state);
|
||||
else if (is_k5 || is_k6) /* AMD K5 and K6 */
|
||||
else if (is_k5 || is_k6) /* AMD K5 and K6 */
|
||||
smram_restore_state_amd_k(saved_state);
|
||||
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
|
||||
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
|
||||
smram_restore_state_p6(saved_state);
|
||||
|
||||
in_smm = 0;
|
||||
@@ -1380,7 +1491,8 @@ int
|
||||
x86_int_sw_rm(int num)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint16_t new_pc, new_cs;
|
||||
uint16_t new_pc;
|
||||
uint16_t new_cs;
|
||||
|
||||
flags_rebuild();
|
||||
cycles -= timing_int;
|
||||
@@ -1468,8 +1580,10 @@ checkio(uint32_t port, int mask)
|
||||
int
|
||||
divl(uint32_t val)
|
||||
{
|
||||
uint64_t num, quo;
|
||||
uint32_t rem, quo32;
|
||||
uint64_t num;
|
||||
uint64_t quo;
|
||||
uint32_t rem;
|
||||
uint32_t quo32;
|
||||
|
||||
if (val == 0) {
|
||||
divexcp();
|
||||
@@ -1495,8 +1609,10 @@ divl(uint32_t val)
|
||||
int
|
||||
idivl(int32_t val)
|
||||
{
|
||||
int64_t num, quo;
|
||||
int32_t rem, quo32;
|
||||
int64_t num;
|
||||
int64_t quo;
|
||||
int32_t rem;
|
||||
int32_t quo32;
|
||||
|
||||
if (val == 0) {
|
||||
divexcp();
|
||||
|
||||
@@ -20,83 +20,112 @@
|
||||
#define _386_COMMON_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
#define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
#define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
#define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
#define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
#define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
#define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
#ifdef OPS_286_386
|
||||
# define readmemb_n(s, a, b) readmembl_no_mmut_2386((s) + (a), b)
|
||||
# define readmemw_n(s, a, b) readmemwl_no_mmut_2386((s) + (a), b)
|
||||
# define readmeml_n(s, a, b) readmemll_no_mmut_2386((s) + (a), b)
|
||||
# define readmemb(s, a) readmembl_2386((s) + (a))
|
||||
# define readmemw(s, a) readmemwl_2386((s) + (a))
|
||||
# define readmeml(s, a) readmemll_2386((s) + (a))
|
||||
# define readmemq(s, a) readmemql_2386((s) + (a))
|
||||
|
||||
#define writememb_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
writemembl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememw_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
writememwl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememl_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
writememll_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememb(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
writemembl((s) + (a), v); \
|
||||
else \
|
||||
*(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememw(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
writememwl((s) + (a), v); \
|
||||
else \
|
||||
*(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememl(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
writememll((s) + (a), v); \
|
||||
else \
|
||||
*(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememq(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \
|
||||
writememql((s) + (a), v); \
|
||||
else \
|
||||
*(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememb_n(s, a, b, v) writemembl_no_mmut_2386((s) + (a), b, v)
|
||||
# define writememw_n(s, a, b, v) writememwl_no_mmut_2386((s) + (a), b, v)
|
||||
# define writememl_n(s, a, b, v) writememll_no_mmut_2386((s) + (a), b, v)
|
||||
# define writememb(s, a, v) writemembl_2386((s) + (a), v)
|
||||
# define writememw(s, a, v) writememwl_2386((s) + (a), v)
|
||||
# define writememl(s, a, v) writememll_2386((s) + (a), v)
|
||||
# define writememq(s, a, v) writememql_2386((s) + (a), v)
|
||||
|
||||
#define do_mmut_rb(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
do_mmutranslate((s) + (a), b, 1, 0)
|
||||
#define do_mmut_rw(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 0)
|
||||
#define do_mmut_rl(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 0)
|
||||
#define do_mmut_rb2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
do_mmutranslate((s) + (a), b, 1, 0)
|
||||
#define do_mmut_rw2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 0)
|
||||
#define do_mmut_rl2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 0)
|
||||
# define do_mmut_rb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 0)
|
||||
# define do_mmut_rw(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 0)
|
||||
# define do_mmut_rl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 0)
|
||||
# define do_mmut_rb2(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 0)
|
||||
# define do_mmut_rw2(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 0)
|
||||
# define do_mmut_rl2(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 0)
|
||||
|
||||
#define do_mmut_wb(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
do_mmutranslate((s) + (a), b, 1, 1)
|
||||
#define do_mmut_ww(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 1)
|
||||
#define do_mmut_wl(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 1)
|
||||
# define do_mmut_wb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 1)
|
||||
# define do_mmut_ww(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 1)
|
||||
# define do_mmut_wl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 1)
|
||||
#else
|
||||
# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
|
||||
# define writememb_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
writemembl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememw_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
writememwl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememl_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
writememll_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememb(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
writemembl((s) + (a), v); \
|
||||
else \
|
||||
*(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememw(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
writememwl((s) + (a), v); \
|
||||
else \
|
||||
*(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememl(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
writememll((s) + (a), v); \
|
||||
else \
|
||||
*(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememq(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \
|
||||
writememql((s) + (a), v); \
|
||||
else \
|
||||
*(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
|
||||
# define do_mmut_rb(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
do_mmutranslate((s) + (a), b, 1, 0)
|
||||
# define do_mmut_rw(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 0)
|
||||
# define do_mmut_rl(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 0)
|
||||
# define do_mmut_rb2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
do_mmutranslate((s) + (a), b, 1, 0)
|
||||
# define do_mmut_rw2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 0)
|
||||
# define do_mmut_rl2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 0)
|
||||
|
||||
# define do_mmut_wb(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
do_mmutranslate((s) + (a), b, 1, 1)
|
||||
# define do_mmut_ww(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 1)
|
||||
# define do_mmut_wl(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 1)
|
||||
#endif
|
||||
|
||||
int checkio(uint32_t port, int mask);
|
||||
|
||||
@@ -191,27 +220,47 @@ int checkio(uint32_t port, int mask);
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#ifdef OPS_286_386
|
||||
/* TODO: Introduce functions to read exec. */
|
||||
static __inline uint8_t
|
||||
fastreadb(uint32_t a)
|
||||
{
|
||||
return readmembl(a);
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
fastreadw(uint32_t a)
|
||||
{
|
||||
return readmemwl(a);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
fastreadl(uint32_t a)
|
||||
{
|
||||
return readmemll(a);
|
||||
}
|
||||
#else
|
||||
static __inline uint8_t
|
||||
fastreadb(uint32_t a)
|
||||
{
|
||||
uint8_t *t;
|
||||
|
||||
if ((a >> 12) == pccache)
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
|
||||
#else
|
||||
# else
|
||||
return *((uint8_t *) &pccache2[a]);
|
||||
#endif
|
||||
# endif
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
pccache = a >> 12;
|
||||
pccache2 = t;
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
|
||||
#else
|
||||
# else
|
||||
return *((uint8_t *) &pccache2[a]);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
@@ -225,22 +274,22 @@ fastreadw(uint32_t a)
|
||||
return val;
|
||||
}
|
||||
if ((a >> 12) == pccache)
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
|
||||
#else
|
||||
# else
|
||||
return *((uint16_t *) &pccache2[a]);
|
||||
#endif
|
||||
# endif
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
|
||||
pccache = a >> 12;
|
||||
pccache2 = t;
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
|
||||
#else
|
||||
# else
|
||||
return *((uint16_t *) &pccache2[a]);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
@@ -256,16 +305,17 @@ fastreadl(uint32_t a)
|
||||
pccache2 = t;
|
||||
pccache = a >> 12;
|
||||
}
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
|
||||
#else
|
||||
# else
|
||||
return *((uint32_t *) &pccache2[a]);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
val = fastreadw(a);
|
||||
val |= (fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline void *
|
||||
get_ram_ptr(uint32_t a)
|
||||
@@ -288,6 +338,37 @@ get_ram_ptr(uint32_t a)
|
||||
|
||||
extern int opcode_length[256];
|
||||
|
||||
#ifdef OPS_286_386
|
||||
static __inline uint16_t
|
||||
fastreadw_fetch(uint32_t a)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
if ((a & 0xFFF) > 0xFFE) {
|
||||
val = fastreadb(a);
|
||||
if (opcode_length[val & 0xff] > 1)
|
||||
val |= (fastreadb(a + 1) << 8);
|
||||
return val;
|
||||
}
|
||||
|
||||
return readmemwl(a);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
fastreadl_fetch(uint32_t a)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
if ((a & 0xFFF) > 0xFFC) {
|
||||
val = fastreadw_fetch(a);
|
||||
if (opcode_length[val & 0xff] > 2)
|
||||
val |= (fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
}
|
||||
|
||||
return readmemll(a);
|
||||
}
|
||||
#else
|
||||
static __inline uint16_t
|
||||
fastreadw_fetch(uint32_t a)
|
||||
{
|
||||
@@ -300,22 +381,22 @@ fastreadw_fetch(uint32_t a)
|
||||
return val;
|
||||
}
|
||||
if ((a >> 12) == pccache)
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
|
||||
#else
|
||||
# else
|
||||
return *((uint16_t *) &pccache2[a]);
|
||||
#endif
|
||||
# endif
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
|
||||
pccache = a >> 12;
|
||||
pccache2 = t;
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
|
||||
#else
|
||||
# else
|
||||
return *((uint16_t *) &pccache2[a]);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
@@ -331,17 +412,18 @@ fastreadl_fetch(uint32_t a)
|
||||
pccache2 = t;
|
||||
pccache = a >> 12;
|
||||
}
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
|
||||
#else
|
||||
# else
|
||||
return *((uint32_t *) &pccache2[a]);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
val = fastreadw_fetch(a);
|
||||
if (opcode_length[val & 0xff] > 2)
|
||||
val |= (fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline uint8_t
|
||||
getbyte(void)
|
||||
@@ -371,6 +453,93 @@ getquad(void)
|
||||
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
|
||||
}
|
||||
|
||||
#ifdef OPS_286_386
|
||||
static __inline uint8_t
|
||||
geteab(void)
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l;
|
||||
return readmemb(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
geteaw(void)
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].w;
|
||||
return readmemw(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
geteal(void)
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].l;
|
||||
return readmeml(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
geteaq(void)
|
||||
{
|
||||
return readmemq(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline uint8_t
|
||||
geteab_mem(void)
|
||||
{
|
||||
return readmemb(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
static __inline uint16_t
|
||||
geteaw_mem(void)
|
||||
{
|
||||
return readmemw(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
static __inline uint32_t
|
||||
geteal_mem(void)
|
||||
{
|
||||
return readmeml(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
seteaq_cwc(void)
|
||||
{
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
seteaq(uint64_t v)
|
||||
{
|
||||
if (seteaq_cwc())
|
||||
return;
|
||||
writememql(easeg + cpu_state.eaaddr, v);
|
||||
}
|
||||
|
||||
# define seteab(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \
|
||||
writemembl_2386(easeg + cpu_state.eaaddr, v); \
|
||||
} else if (cpu_rm & 4) \
|
||||
cpu_state.regs[cpu_rm & 3].b.h = v; \
|
||||
else \
|
||||
cpu_state.regs[cpu_rm].b.l = v
|
||||
# define seteaw(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
|
||||
writememwl_2386(easeg + cpu_state.eaaddr, v); \
|
||||
} else \
|
||||
cpu_state.regs[cpu_rm].w = v
|
||||
# define seteal(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
writememll_2386(easeg + cpu_state.eaaddr, v); \
|
||||
} else \
|
||||
cpu_state.regs[cpu_rm].l = v
|
||||
|
||||
# define seteab_mem(v) writemembl_2386(easeg + cpu_state.eaaddr, v);
|
||||
# define seteaw_mem(v) writememwl_2386(easeg + cpu_state.eaaddr, v);
|
||||
# define seteal_mem(v) writememll_2386(easeg + cpu_state.eaaddr, v);
|
||||
#else
|
||||
static __inline uint8_t
|
||||
geteab(void)
|
||||
{
|
||||
@@ -444,51 +613,52 @@ seteaq(uint64_t v)
|
||||
writememql(easeg + cpu_state.eaaddr, v);
|
||||
}
|
||||
|
||||
#define seteab(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \
|
||||
if (eal_w) \
|
||||
*(uint8_t *) eal_w = v; \
|
||||
else \
|
||||
writemembl(easeg + cpu_state.eaaddr, v); \
|
||||
} else if (cpu_rm & 4) \
|
||||
cpu_state.regs[cpu_rm & 3].b.h = v; \
|
||||
else \
|
||||
cpu_state.regs[cpu_rm].b.l = v
|
||||
#define seteaw(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
|
||||
if (eal_w) \
|
||||
*(uint16_t *) eal_w = v; \
|
||||
# define seteab(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \
|
||||
if (eal_w) \
|
||||
*(uint8_t *) eal_w = v; \
|
||||
else \
|
||||
writemembl(easeg + cpu_state.eaaddr, v); \
|
||||
} else if (cpu_rm & 4) \
|
||||
cpu_state.regs[cpu_rm & 3].b.h = v; \
|
||||
else \
|
||||
writememwl(easeg + cpu_state.eaaddr, v); \
|
||||
} else \
|
||||
cpu_state.regs[cpu_rm].w = v
|
||||
#define seteal(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
if (eal_w) \
|
||||
*eal_w = v; \
|
||||
else \
|
||||
writememll(easeg + cpu_state.eaaddr, v); \
|
||||
} else \
|
||||
cpu_state.regs[cpu_rm].l = v
|
||||
cpu_state.regs[cpu_rm].b.l = v
|
||||
# define seteaw(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
|
||||
if (eal_w) \
|
||||
*(uint16_t *) eal_w = v; \
|
||||
else \
|
||||
writememwl(easeg + cpu_state.eaaddr, v); \
|
||||
} else \
|
||||
cpu_state.regs[cpu_rm].w = v
|
||||
# define seteal(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
if (eal_w) \
|
||||
*eal_w = v; \
|
||||
else \
|
||||
writememll(easeg + cpu_state.eaaddr, v); \
|
||||
} else \
|
||||
cpu_state.regs[cpu_rm].l = v
|
||||
|
||||
#define seteab_mem(v) \
|
||||
if (eal_w) \
|
||||
*(uint8_t *) eal_w = v; \
|
||||
else \
|
||||
writemembl(easeg + cpu_state.eaaddr, v);
|
||||
#define seteaw_mem(v) \
|
||||
if (eal_w) \
|
||||
*(uint16_t *) eal_w = v; \
|
||||
else \
|
||||
writememwl(easeg + cpu_state.eaaddr, v);
|
||||
#define seteal_mem(v) \
|
||||
if (eal_w) \
|
||||
*eal_w = v; \
|
||||
else \
|
||||
writememll(easeg + cpu_state.eaaddr, v);
|
||||
# define seteab_mem(v) \
|
||||
if (eal_w) \
|
||||
*(uint8_t *) eal_w = v; \
|
||||
else \
|
||||
writemembl(easeg + cpu_state.eaaddr, v);
|
||||
# define seteaw_mem(v) \
|
||||
if (eal_w) \
|
||||
*(uint16_t *) eal_w = v; \
|
||||
else \
|
||||
writememwl(easeg + cpu_state.eaaddr, v);
|
||||
# define seteal_mem(v) \
|
||||
if (eal_w) \
|
||||
*eal_w = v; \
|
||||
else \
|
||||
writememll(easeg + cpu_state.eaaddr, v);
|
||||
#endif
|
||||
|
||||
#define getbytef() \
|
||||
((uint8_t) (fetchdat)); \
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
int inrecomp = 0, cpu_block_end = 0;
|
||||
int inrecomp = 0;
|
||||
int cpu_block_end = 0;
|
||||
int cpu_end_block_after_ins = 0;
|
||||
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
@@ -183,78 +184,6 @@ fetch_ea_16_long(uint32_t rmdat)
|
||||
|
||||
#include "x86_flags.h"
|
||||
|
||||
/*Prefetch emulation is a fairly simplistic model:
|
||||
- All instruction bytes must be fetched before it starts.
|
||||
- Cycles used for non-instruction memory accesses are counted and subtracted
|
||||
from the total cycles taken
|
||||
- Any remaining cycles are used to refill the prefetch queue.
|
||||
|
||||
Note that this is only used for 286 / 386 systems. It is disabled when the
|
||||
internal cache on 486+ CPUs is enabled.
|
||||
*/
|
||||
static int prefetch_bytes = 0;
|
||||
static int prefetch_prefixes = 0;
|
||||
|
||||
static void
|
||||
prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32)
|
||||
{
|
||||
int mem_cycles = reads * cpu_cycles_read + reads_l * cpu_cycles_read_l + writes * cpu_cycles_write + writes_l * cpu_cycles_write_l;
|
||||
|
||||
if (instr_cycles < mem_cycles)
|
||||
instr_cycles = mem_cycles;
|
||||
|
||||
prefetch_bytes -= prefetch_prefixes;
|
||||
prefetch_bytes -= bytes;
|
||||
if (modrm != -1) {
|
||||
if (ea32) {
|
||||
if ((modrm & 7) == 4) {
|
||||
if ((modrm & 0x700) == 0x500)
|
||||
prefetch_bytes -= 5;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 5;
|
||||
} else {
|
||||
if ((modrm & 0xc7) == 0x05)
|
||||
prefetch_bytes -= 4;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes--;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 4;
|
||||
}
|
||||
} else {
|
||||
if ((modrm & 0xc7) == 0x06)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) != 0xc0)
|
||||
prefetch_bytes -= ((modrm & 0xc0) >> 6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill up prefetch queue */
|
||||
while (prefetch_bytes < 0) {
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
/* Subtract cycles used for memory access by instruction */
|
||||
instr_cycles -= mem_cycles;
|
||||
|
||||
while (instr_cycles >= cpu_prefetch_cycles) {
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
instr_cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
prefetch_prefixes = 0;
|
||||
if (prefetch_bytes > 16)
|
||||
prefetch_bytes = 16;
|
||||
}
|
||||
|
||||
static void
|
||||
prefetch_flush(void)
|
||||
{
|
||||
prefetch_bytes = 0;
|
||||
}
|
||||
|
||||
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
|
||||
do { \
|
||||
if (cpu_prefetch_cycles) \
|
||||
@@ -406,8 +335,9 @@ exec386_dynarec_int(void)
|
||||
static __inline void
|
||||
exec386_dynarec_dyn(void)
|
||||
{
|
||||
uint32_t start_pc = 0, phys_addr = get_phys(cs + cpu_state.pc);
|
||||
int hash = HASH(phys_addr);
|
||||
uint32_t start_pc = 0;
|
||||
uint32_t phys_addr = get_phys(cs + cpu_state.pc);
|
||||
int hash = HASH(phys_addr);
|
||||
# ifdef USE_NEW_DYNAREC
|
||||
codeblock_t *block = &codeblock[codeblock_hash[hash]];
|
||||
# else
|
||||
@@ -556,7 +486,9 @@ exec386_dynarec_dyn(void)
|
||||
x86_was_reset = 0;
|
||||
|
||||
# if defined(__APPLE__) && defined(__aarch64__)
|
||||
pthread_jit_write_protect_np(0);
|
||||
if (__builtin_available(macOS 11.0, *)) {
|
||||
pthread_jit_write_protect_np(0);
|
||||
}
|
||||
# endif
|
||||
codegen_block_start_recompile(block);
|
||||
codegen_in_recompile = 1;
|
||||
@@ -640,7 +572,9 @@ exec386_dynarec_dyn(void)
|
||||
|
||||
codegen_in_recompile = 0;
|
||||
# if defined(__APPLE__) && defined(__aarch64__)
|
||||
pthread_jit_write_protect_np(1);
|
||||
if (__builtin_available(macOS 11.0, *)) {
|
||||
pthread_jit_write_protect_np(1);
|
||||
}
|
||||
# endif
|
||||
} else if (!cpu_state.abrt) {
|
||||
/* Mark block but do not recompile */
|
||||
@@ -742,10 +676,13 @@ exec386_dynarec_dyn(void)
|
||||
void
|
||||
exec386_dynarec(int cycs)
|
||||
{
|
||||
int vector, tempi;
|
||||
int vector;
|
||||
int tempi;
|
||||
int cycdiff;
|
||||
int oldcyc, oldcyc2;
|
||||
uint64_t oldtsc, delta;
|
||||
int oldcyc;
|
||||
int oldcyc2;
|
||||
uint64_t oldtsc;
|
||||
uint64_t delta;
|
||||
|
||||
int cyc_period = cycs / 2000; /*5us*/
|
||||
|
||||
@@ -858,3 +795,160 @@ exec386_dynarec(int cycs)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
exec386(int cycs)
|
||||
{
|
||||
int vector;
|
||||
int tempi;
|
||||
int cycdiff;
|
||||
int oldcyc;
|
||||
int cycle_period;
|
||||
int ins_cycles;
|
||||
uint32_t addr;
|
||||
|
||||
cycles += cycs;
|
||||
|
||||
while (cycles > 0) {
|
||||
cycle_period = (timer_target - (uint32_t) tsc) + 1;
|
||||
|
||||
x86_was_reset = 0;
|
||||
cycdiff = 0;
|
||||
oldcyc = cycles;
|
||||
while (cycdiff < cycle_period) {
|
||||
ins_cycles = cycles;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
x86_was_reset = 0;
|
||||
#endif
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
#ifdef ENABLE_386_LOG
|
||||
if (in_smm)
|
||||
x386_dynarec_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
|
||||
#endif
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
if (x86_was_reset)
|
||||
break;
|
||||
}
|
||||
#ifdef ENABLE_386_LOG
|
||||
else if (in_smm)
|
||||
x386_dynarec_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc);
|
||||
#endif
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
if (!use32)
|
||||
cpu_state.pc &= 0xffff;
|
||||
#endif
|
||||
|
||||
if (cpu_end_block_after_ins)
|
||||
cpu_end_block_after_ins--;
|
||||
|
||||
if (cpu_state.abrt) {
|
||||
flags_rebuild();
|
||||
tempi = cpu_state.abrt & ABRT_MASK;
|
||||
cpu_state.abrt = 0;
|
||||
x86_doabrt(tempi);
|
||||
if (cpu_state.abrt) {
|
||||
cpu_state.abrt = 0;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x386_dynarec_log("Double fault\n");
|
||||
pmodeint(8, 0);
|
||||
if (cpu_state.abrt) {
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
#ifdef ENABLE_386_LOG
|
||||
x386_dynarec_log("Triple fault - reset\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else if (trap) {
|
||||
flags_rebuild();
|
||||
trap = 0;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
#endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
dr[6] |= 0x4000;
|
||||
x86_int(1);
|
||||
}
|
||||
|
||||
if (smi_line)
|
||||
enter_smm_check(0);
|
||||
else if (nmi && nmi_enable && nmi_mask) {
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
#endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int(2);
|
||||
nmi_enable = 0;
|
||||
#ifdef OLD_NMI_BEHAVIOR
|
||||
if (nmi_auto_clear) {
|
||||
nmi_auto_clear = 0;
|
||||
nmi = 0;
|
||||
}
|
||||
#else
|
||||
nmi = 0;
|
||||
#endif
|
||||
} else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) {
|
||||
vector = picinterrupt();
|
||||
if (vector != -1) {
|
||||
flags_rebuild();
|
||||
if (msw & 1)
|
||||
pmodeint(vector, 0);
|
||||
else {
|
||||
writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags);
|
||||
writememw(ss, (SP - 4) & 0xFFFF, CS);
|
||||
writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc);
|
||||
SP -= 6;
|
||||
addr = (vector << 2) + idt.base;
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc = readmemw(0, addr);
|
||||
loadcs(readmemw(0, addr + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ins_cycles -= cycles;
|
||||
tsc += ins_cycles;
|
||||
|
||||
cycdiff = oldcyc - cycles;
|
||||
|
||||
if (timetolive) {
|
||||
timetolive--;
|
||||
if (!timetolive)
|
||||
fatal("Life expired\n");
|
||||
}
|
||||
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
|
||||
timer_process_inline();
|
||||
|
||||
#ifdef USE_GDBSTUB
|
||||
if (gdbstub_instruction())
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <86box/pic.h>
|
||||
#include <86box/gdbstub.h>
|
||||
#include "codegen.h"
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
@@ -31,7 +32,7 @@
|
||||
#include "386_common.h"
|
||||
|
||||
static __inline void
|
||||
fetch_ea_32_long(uint32_t rmdat)
|
||||
fetch_ea_32_long(UNUSED(uint32_t rmdat))
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
@@ -45,7 +46,7 @@ fetch_ea_32_long(uint32_t rmdat)
|
||||
}
|
||||
|
||||
static __inline void
|
||||
fetch_ea_16_long(uint32_t rmdat)
|
||||
fetch_ea_16_long(UNUSED(uint32_t rmdat))
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
|
||||
@@ -179,7 +179,9 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#include "x86_ops_bcd.h"
|
||||
#include "x86_ops_bit.h"
|
||||
#include "x86_ops_bitscan.h"
|
||||
#include "x86_ops_cyrix.h"
|
||||
#ifndef OPS_286_386
|
||||
# include "x86_ops_cyrix.h"
|
||||
#endif
|
||||
#include "x86_ops_flag.h"
|
||||
#include "x86_ops_fpu.h"
|
||||
#include "x86_ops_inc_dec.h"
|
||||
@@ -188,38 +190,53 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#include "x86_ops_jump.h"
|
||||
#include "x86_ops_misc.h"
|
||||
#include "x87_ops.h"
|
||||
#include "x86_ops_i686.h"
|
||||
#include "x86_ops_mmx.h"
|
||||
#include "x86_ops_mmx_arith.h"
|
||||
#include "x86_ops_mmx_cmp.h"
|
||||
#include "x86_ops_mmx_logic.h"
|
||||
#include "x86_ops_mmx_mov.h"
|
||||
#include "x86_ops_mmx_pack.h"
|
||||
#include "x86_ops_mmx_shift.h"
|
||||
#ifndef OPS_286_386
|
||||
# include "x86_ops_i686.h"
|
||||
# include "x86_ops_mmx.h"
|
||||
# include "x86_ops_mmx_arith.h"
|
||||
# include "x86_ops_mmx_cmp.h"
|
||||
# include "x86_ops_mmx_logic.h"
|
||||
# include "x86_ops_mmx_mov.h"
|
||||
# include "x86_ops_mmx_pack.h"
|
||||
# include "x86_ops_mmx_shift.h"
|
||||
#endif
|
||||
#include "x86_ops_mov.h"
|
||||
#include "x86_ops_mov_ctrl.h"
|
||||
#include "x86_ops_mov_seg.h"
|
||||
#include "x86_ops_movx.h"
|
||||
#include "x86_ops_msr.h"
|
||||
#ifndef OPS_286_386
|
||||
# include "x86_ops_msr.h"
|
||||
#endif
|
||||
#include "x86_ops_mul.h"
|
||||
#include "x86_ops_pmode.h"
|
||||
#include "x86_ops_prefix.h"
|
||||
#ifdef IS_DYNAREC
|
||||
# include "x86_ops_rep_dyn.h"
|
||||
#else
|
||||
# include "x86_ops_rep.h"
|
||||
# ifdef OPS_286_386
|
||||
# include "x86_ops_rep_2386.h"
|
||||
# else
|
||||
# include "x86_ops_rep.h"
|
||||
# endif
|
||||
#endif
|
||||
#include "x86_ops_ret.h"
|
||||
#include "x86_ops_set.h"
|
||||
#include "x86_ops_stack.h"
|
||||
#include "x86_ops_string.h"
|
||||
#ifdef OPS_286_386
|
||||
# include "x86_ops_string_2386.h"
|
||||
#else
|
||||
# include "x86_ops_string.h"
|
||||
#endif
|
||||
#include "x86_ops_xchg.h"
|
||||
#include "x86_ops_call.h"
|
||||
#include "x86_ops_shift.h"
|
||||
#include "x86_ops_amd.h"
|
||||
#include "x86_ops_3dnow.h"
|
||||
#ifndef OPS_286_386
|
||||
# include "x86_ops_amd.h"
|
||||
# include "x86_ops_3dnow.h"
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
#ifndef OPS_286_386
|
||||
static int
|
||||
opVPCEXT(uint32_t fetchdat)
|
||||
{
|
||||
@@ -331,7 +348,54 @@ opVPCEXT(uint32_t fetchdat)
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OPS_286_386
|
||||
static int
|
||||
op0F_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_2386_opcodes_0f[opcode](fetchdat >> 8);
|
||||
}
|
||||
static int
|
||||
op0F_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_2386_opcodes_0f[opcode | 0x100](fetchdat >> 8);
|
||||
}
|
||||
static int
|
||||
op0F_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_2386_opcodes_0f[opcode | 0x200](fetchdat >> 8);
|
||||
}
|
||||
static int
|
||||
op0F_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_2386_opcodes_0f[opcode | 0x300](fetchdat >> 8);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
op0F_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
@@ -376,6 +440,7 @@ op0F_l_a32(uint32_t fetchdat)
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(186_0f)[1024] = {
|
||||
// clang-format off
|
||||
@@ -745,6 +810,7 @@ const OpFn OP_TABLE(486_0f)[1024] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#ifndef OPS_286_386
|
||||
const OpFn OP_TABLE(c486_0f)[1024] = {
|
||||
// clang-format off
|
||||
/*16-bit data, 16-bit addr*/
|
||||
@@ -928,6 +994,7 @@ const OpFn OP_TABLE(stpc_0f)[1024] = {
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(ibm486_0f)[1024] = {
|
||||
// clang-format off
|
||||
@@ -1021,6 +1088,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#ifndef OPS_286_386
|
||||
const OpFn OP_TABLE(winchip_0f)[1024] = {
|
||||
// clang-format off
|
||||
/*16-bit data, 16-bit addr*/
|
||||
@@ -1297,7 +1365,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
const OpFn OP_TABLE(c6x86_0f)[1024] = {
|
||||
// clang-format off
|
||||
/*16-bit data, 16-bit addr*/
|
||||
@@ -1389,7 +1457,7 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = {
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
# endif
|
||||
|
||||
const OpFn OP_TABLE(pentiummmx_0f)[1024] = {
|
||||
// clang-format off
|
||||
@@ -1667,7 +1735,7 @@ const OpFn OP_TABLE(k62_0f)[1024] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
|
||||
// clang-format off
|
||||
/*16-bit data, 16-bit addr*/
|
||||
@@ -1759,7 +1827,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
|
||||
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
# endif
|
||||
|
||||
const OpFn OP_TABLE(pentiumpro_0f)[1024] = {
|
||||
// clang-format off
|
||||
@@ -2036,6 +2104,7 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] = {
|
||||
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(186)[1024] = {
|
||||
// clang-format off
|
||||
|
||||
@@ -19,15 +19,21 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/i8080.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
static int completed = 1;
|
||||
static int in_rep = 0, repeating = 0, rep_c_flag = 0;
|
||||
static int oldc, cycdiff;
|
||||
static int completed = 1;
|
||||
static int in_rep = 0;
|
||||
static int repeating = 0;
|
||||
static int rep_c_flag = 0;
|
||||
static int oldc;
|
||||
static int cycdiff;
|
||||
#ifdef UNUSED_8080_VARS
|
||||
static int prefetching = 1;
|
||||
static int refresh = 0, clear_lock = 0;
|
||||
static int refresh = 0;
|
||||
static int clear_lock = 0;
|
||||
|
||||
static uint32_t cpu_src = 0, cpu_dest = 0;
|
||||
static uint32_t cpu_src = 0;
|
||||
static uint32_t cpu_dest = 0;
|
||||
static uint32_t cpu_data = 0;
|
||||
#endif
|
||||
|
||||
@@ -43,7 +49,7 @@ clock_end(void)
|
||||
int diff = cycdiff - cycles;
|
||||
|
||||
/* On 808x systems, clock speed is usually crystal frequency divided by an integer. */
|
||||
tsc += (uint64_t) diff * ((uint64_t) xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */
|
||||
tsc += (uint64_t) diff * (xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
|
||||
timer_process();
|
||||
}
|
||||
@@ -237,7 +243,7 @@ setreg_i8080(i8080 *cpu, uint8_t reg, uint8_t val)
|
||||
}
|
||||
|
||||
void
|
||||
interpret_exec8080(i8080 *cpu, uint8_t opcode)
|
||||
interpret_exec8080(UNUSED(i8080 *cpu), uint8_t opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case 0x00:
|
||||
|
||||
374
src/cpu/808x.c
374
src/cpu/808x.c
@@ -35,6 +35,8 @@
|
||||
#include <86box/ppi.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/gdbstub.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
/* Is the CPU 8088 or 8086. */
|
||||
int is8086 = 0;
|
||||
@@ -46,7 +48,8 @@ uint32_t custom_nmi_vector = 0x00000000;
|
||||
static uint8_t pfq[6];
|
||||
|
||||
/* Variables to aid with the prefetch queue operation. */
|
||||
static int biu_cycles = 0, pfq_pos = 0;
|
||||
static int biu_cycles = 0;
|
||||
static int pfq_pos = 0;
|
||||
|
||||
/* The IP equivalent of the current prefetch queue position. */
|
||||
static uint16_t pfq_ip;
|
||||
@@ -57,43 +60,50 @@ static x86seg *_opseg[4];
|
||||
|
||||
static int noint = 0;
|
||||
static int in_lock = 0;
|
||||
static int cpu_alu_op, pfq_size;
|
||||
static int cpu_alu_op;
|
||||
static int pfq_size;
|
||||
|
||||
static uint32_t cpu_src = 0, cpu_dest = 0;
|
||||
static uint32_t cpu_src = 0;
|
||||
static uint32_t cpu_dest = 0;
|
||||
static uint32_t cpu_data = 0;
|
||||
|
||||
static uint16_t last_addr = 0x0000;
|
||||
|
||||
static uint32_t *ovr_seg = NULL;
|
||||
static int prefetching = 1, completed = 1;
|
||||
static int in_rep = 0, repeating = 0, rep_c_flag = 0;
|
||||
static int oldc, clear_lock = 0;
|
||||
static int refresh = 0, cycdiff;
|
||||
static int prefetching = 1;
|
||||
static int completed = 1;
|
||||
static int in_rep = 0;
|
||||
static int repeating = 0;
|
||||
static int rep_c_flag = 0;
|
||||
static int oldc;
|
||||
static int clear_lock = 0;
|
||||
static int refresh = 0;
|
||||
static int cycdiff;
|
||||
|
||||
static int access_code = 0;
|
||||
static int hlda = 0;
|
||||
static int not_ready = 0;
|
||||
static int bus_request_type = 0;
|
||||
static int pic_data = -1;
|
||||
static int last_was_code = 0;
|
||||
static uint16_t mem_data = 0;
|
||||
static uint32_t mem_seg = 0;
|
||||
static uint16_t mem_addr = 0;
|
||||
static int schedule_fetch = 1;
|
||||
static int pasv = 0;
|
||||
static int access_code = 0;
|
||||
static int hlda = 0;
|
||||
static int not_ready = 0;
|
||||
static int bus_request_type = 0;
|
||||
static int pic_data = -1;
|
||||
static int last_was_code = 0;
|
||||
static uint16_t mem_data = 0;
|
||||
static uint32_t mem_seg = 0;
|
||||
static uint16_t mem_addr = 0;
|
||||
static int schedule_fetch = 1;
|
||||
static int pasv = 0;
|
||||
|
||||
#define BUS_OUT 1
|
||||
#define BUS_HIGH 2
|
||||
#define BUS_WIDE 4
|
||||
#define BUS_CODE 8
|
||||
#define BUS_IO 16
|
||||
#define BUS_MEM 32
|
||||
#define BUS_PIC 64
|
||||
#define BUS_OUT 1
|
||||
#define BUS_HIGH 2
|
||||
#define BUS_WIDE 4
|
||||
#define BUS_CODE 8
|
||||
#define BUS_IO 16
|
||||
#define BUS_MEM 32
|
||||
#define BUS_PIC 64
|
||||
#define BUS_ACCESS_TYPE (BUS_CODE | BUS_IO | BUS_MEM | BUS_PIC)
|
||||
|
||||
#define BUS_CYCLE (biu_cycles & 3)
|
||||
#define BUS_CYCLE_T1 biu_cycles = 0
|
||||
#define BUS_CYCLE_NEXT biu_cycles = (biu_cycles + 1) & 3
|
||||
#define BUS_CYCLE (biu_cycles & 3)
|
||||
#define BUS_CYCLE_T1 biu_cycles = 0
|
||||
#define BUS_CYCLE_NEXT biu_cycles = (biu_cycles + 1) & 3
|
||||
|
||||
enum {
|
||||
BUS_T1 = 0,
|
||||
@@ -204,14 +214,14 @@ clock_end(void)
|
||||
int diff = cycdiff - cycles;
|
||||
|
||||
/* On 808x systems, clock speed is usually crystal frequency divided by an integer. */
|
||||
tsc += ((uint64_t) diff * ((uint64_t) xt_cpu_multi >> 32ULL)); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */
|
||||
tsc += ((uint64_t) diff * (xt_cpu_multi >> 32ULL)); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
|
||||
timer_process();
|
||||
}
|
||||
|
||||
static void
|
||||
process_timers(void)
|
||||
{
|
||||
{
|
||||
clock_end();
|
||||
clock_start();
|
||||
}
|
||||
@@ -248,7 +258,7 @@ bus_outw(uint16_t port, uint16_t val)
|
||||
static uint8_t
|
||||
bus_inb(uint16_t port)
|
||||
{
|
||||
int old_cycles = cycles;
|
||||
int old_cycles = cycles;
|
||||
uint8_t ret;
|
||||
|
||||
cycles--;
|
||||
@@ -261,7 +271,7 @@ bus_inb(uint16_t port)
|
||||
static uint16_t
|
||||
bus_inw(uint16_t port)
|
||||
{
|
||||
int old_cycles = cycles;
|
||||
int old_cycles = cycles;
|
||||
uint16_t ret;
|
||||
|
||||
cycles--;
|
||||
@@ -367,7 +377,7 @@ run_bus_cycle(int io_type)
|
||||
not_ready = 0;
|
||||
}
|
||||
|
||||
switch(BUS_CYCLE) {
|
||||
switch (BUS_CYCLE) {
|
||||
case BUS_T1:
|
||||
access_code = !!(io_type & BUS_CODE);
|
||||
break;
|
||||
@@ -384,7 +394,7 @@ run_bus_cycle(int io_type)
|
||||
bus_do_mem(io_type);
|
||||
break;
|
||||
case BUS_PIC:
|
||||
pic_data = pic_irq_ack();
|
||||
pic_data = pic_irq_ack();
|
||||
last_was_code = 0;
|
||||
break;
|
||||
default:
|
||||
@@ -423,9 +433,7 @@ run_dma_cycle(int idle)
|
||||
static void
|
||||
cycles_idle(int c)
|
||||
{
|
||||
int d;
|
||||
|
||||
for (d = 0; d < c; d++) {
|
||||
for (int d = 0; d < c; d++) {
|
||||
x808x_log("[%04X:%04X] %02X TI\n", CS, cpu_state.pc, opcode);
|
||||
|
||||
cycles_forward(1);
|
||||
@@ -447,17 +455,20 @@ cycles_biu(int bus, int init)
|
||||
switch (BUS_CYCLE) {
|
||||
case BUS_T1:
|
||||
case BUS_T2:
|
||||
BUS_CYCLE_T1; /* Simply abort the prefetch before actual scheduling, no penalty. */
|
||||
BUS_CYCLE_T1; /* Simply abort the prefetch before actual scheduling, no penalty. */
|
||||
break;
|
||||
case BUS_T3:
|
||||
case BUS_T4:
|
||||
cycles_idle(5 - BUS_CYCLE); /* Leftover BIU cycles + 2 idle cycles. */
|
||||
BUS_CYCLE_T1; /* Abort the prefetch. */
|
||||
cycles_idle(5 - BUS_CYCLE); /* Leftover BIU cycles + 2 idle cycles. */
|
||||
BUS_CYCLE_T1; /* Abort the prefetch. */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
schedule_fetch = 0;
|
||||
access_code = 0;
|
||||
access_code = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,14 +511,12 @@ bus_init(void)
|
||||
static void
|
||||
wait(int c, int bus)
|
||||
{
|
||||
int d;
|
||||
|
||||
if (c < 0)
|
||||
pclog("Negative cycles: %i!\n", c);
|
||||
|
||||
x808x_log("[%04X:%04X] %02X %i cycles (%i)\n", CS, cpu_state.pc, opcode, c, bus);
|
||||
|
||||
for (d = 0; d < c; d++) {
|
||||
for (int d = 0; d < c; d++) {
|
||||
x808x_log("[%04X:%04X] %02X cycle %i BIU\n", CS, cpu_state.pc, opcode, d);
|
||||
cycles_biu(bus, !d);
|
||||
x808x_log("[%04X:%04X] %02X cycle %i EU\n", CS, cpu_state.pc, opcode, d);
|
||||
@@ -530,12 +539,12 @@ sub_cycles(int c)
|
||||
void
|
||||
resub_cycles(int old_cycles)
|
||||
{
|
||||
int i, cyc_diff = 0;
|
||||
int cyc_diff = 0;
|
||||
|
||||
if (old_cycles > cycles) {
|
||||
cyc_diff = old_cycles - cycles;
|
||||
|
||||
for (i = 0; i < cyc_diff; i++) {
|
||||
for (int i = 0; i < cyc_diff; i++) {
|
||||
if (not_ready > 0)
|
||||
not_ready--;
|
||||
}
|
||||
@@ -564,7 +573,7 @@ cpu_io(int bits, int out, uint16_t port)
|
||||
} else {
|
||||
bus_request_type = BUS_IO | BUS_OUT;
|
||||
wait(4, 1);
|
||||
schedule_fetch = 0;
|
||||
schedule_fetch = 0;
|
||||
bus_request_type = BUS_IO | BUS_OUT | BUS_HIGH;
|
||||
wait(4, 1);
|
||||
}
|
||||
@@ -580,7 +589,7 @@ cpu_io(int bits, int out, uint16_t port)
|
||||
} else {
|
||||
bus_request_type = BUS_IO;
|
||||
wait(4, 1);
|
||||
schedule_fetch = 0;
|
||||
schedule_fetch = 0;
|
||||
bus_request_type = BUS_IO | BUS_HIGH;
|
||||
wait(4, 1);
|
||||
}
|
||||
@@ -603,11 +612,11 @@ readmemb(uint32_t s, uint16_t a)
|
||||
bus_init();
|
||||
#endif
|
||||
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
bus_request_type = BUS_MEM;
|
||||
wait(4, 1);
|
||||
ret = mem_data & 0xff;
|
||||
ret = mem_data & 0xff;
|
||||
bus_request_type = 0;
|
||||
|
||||
return ret;
|
||||
@@ -637,7 +646,7 @@ readmemw(uint32_t s, uint16_t a)
|
||||
bus_init();
|
||||
#endif
|
||||
|
||||
mem_seg = s;
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
if (is8086 && !(a & 1)) {
|
||||
bus_request_type = BUS_MEM | BUS_WIDE;
|
||||
@@ -645,11 +654,11 @@ readmemw(uint32_t s, uint16_t a)
|
||||
} else {
|
||||
bus_request_type = BUS_MEM | BUS_HIGH;
|
||||
wait(4, 1);
|
||||
schedule_fetch = 0;
|
||||
schedule_fetch = 0;
|
||||
bus_request_type = BUS_MEM;
|
||||
wait(4, 1);
|
||||
}
|
||||
ret = mem_data;
|
||||
ret = mem_data;
|
||||
bus_request_type = 0;
|
||||
|
||||
return ret;
|
||||
@@ -710,9 +719,9 @@ writememb(uint32_t s, uint32_t a, uint8_t v)
|
||||
bus_init();
|
||||
#endif
|
||||
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
mem_data = v;
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
mem_data = v;
|
||||
bus_request_type = BUS_MEM | BUS_OUT;
|
||||
wait(4, 1);
|
||||
bus_request_type = 0;
|
||||
@@ -731,7 +740,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v)
|
||||
bus_init();
|
||||
#endif
|
||||
|
||||
mem_seg = s;
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
mem_data = v;
|
||||
if (is8086 && !(a & 1)) {
|
||||
@@ -740,7 +749,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v)
|
||||
} else {
|
||||
bus_request_type = BUS_MEM | BUS_OUT | BUS_HIGH;
|
||||
wait(4, 1);
|
||||
schedule_fetch = 0;
|
||||
schedule_fetch = 0;
|
||||
bus_request_type = BUS_MEM | BUS_OUT;
|
||||
wait(4, 1);
|
||||
}
|
||||
@@ -785,13 +794,13 @@ pfq_write(void)
|
||||
free in the queue. */
|
||||
tempw = readmemwf(pfq_ip);
|
||||
*(uint16_t *) &(pfq[pfq_pos]) = tempw;
|
||||
pfq_ip = (pfq_ip + 2) & 0xffff;
|
||||
pfq_ip = (pfq_ip + 2) & 0xffff;
|
||||
pfq_pos += 2;
|
||||
} else if (!fetch_word && (pfq_pos < pfq_size)) {
|
||||
/* The 8088 fetches 1 byte at a time, and only if there's at least 1 byte
|
||||
free in the queue. */
|
||||
pfq[pfq_pos] = readmembf(pfq_ip);
|
||||
pfq_ip = (pfq_ip + 1) & 0xffff;
|
||||
pfq_ip = (pfq_ip + 1) & 0xffff;
|
||||
pfq_pos++;
|
||||
}
|
||||
|
||||
@@ -884,8 +893,8 @@ pfq_add(void)
|
||||
static void
|
||||
pfq_clear(void)
|
||||
{
|
||||
pfq_pos = 0;
|
||||
prefetching = 0;
|
||||
pfq_pos = 0;
|
||||
prefetching = 0;
|
||||
schedule_fetch = 0;
|
||||
|
||||
BUS_CYCLE_T1;
|
||||
@@ -894,8 +903,8 @@ pfq_clear(void)
|
||||
static void
|
||||
pfq_suspend(void)
|
||||
{
|
||||
pfq_clear();
|
||||
cycles_idle(3);
|
||||
pfq_clear();
|
||||
cycles_idle(3);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -934,7 +943,7 @@ reset_808x(int hard)
|
||||
_opseg[2] = &cpu_state.seg_ss;
|
||||
_opseg[3] = &cpu_state.seg_ds;
|
||||
|
||||
pfq_size = (is8086) ? 6 : 4;
|
||||
pfq_size = is8086 ? 6 : 4;
|
||||
pfq_clear();
|
||||
}
|
||||
|
||||
@@ -949,20 +958,20 @@ reset_808x(int hard)
|
||||
schedule_fetch = 1;
|
||||
pasv = 0;
|
||||
|
||||
cpu_alu_op = 0;
|
||||
cpu_alu_op = 0;
|
||||
|
||||
use_custom_nmi_vector = 0x00;
|
||||
custom_nmi_vector = 0x00000000;
|
||||
|
||||
access_code = 0;
|
||||
hlda = 0;
|
||||
not_ready = 0;
|
||||
bus_request_type = 0;
|
||||
pic_data = -1;
|
||||
last_was_code = 0;
|
||||
mem_data = 0;
|
||||
mem_seg = 0;
|
||||
mem_addr = 0;
|
||||
access_code = 0;
|
||||
hlda = 0;
|
||||
not_ready = 0;
|
||||
bus_request_type = 0;
|
||||
pic_data = -1;
|
||||
last_was_code = 0;
|
||||
mem_data = 0;
|
||||
mem_seg = 0;
|
||||
mem_addr = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -970,7 +979,7 @@ set_ip(uint16_t new_ip)
|
||||
{
|
||||
pfq_ip = cpu_state.pc = new_ip;
|
||||
prefetching = 1;
|
||||
schedule_fetch = prefetching && (pfq_pos < pfq_size);
|
||||
schedule_fetch = prefetching && (pfq_pos < pfq_size);
|
||||
}
|
||||
|
||||
/* Memory refresh read - called by reads and writes on DMA channel 0. */
|
||||
@@ -1019,16 +1028,20 @@ do_mod_rm(void)
|
||||
easeg = ovr_seg ? *ovr_seg : ds;
|
||||
wait(2, 0);
|
||||
return;
|
||||
} else switch (cpu_rm) {
|
||||
case 0:
|
||||
case 3:
|
||||
wait(2, 0);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
wait(3, 0);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
switch (cpu_rm) {
|
||||
case 0:
|
||||
case 3:
|
||||
wait(2, 0);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
wait(3, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cpu_state.eaaddr = (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
|
||||
easeg = ovr_seg ? *ovr_seg : *mod1seg[cpu_rm];
|
||||
switch (rmdat & 0xc0) {
|
||||
@@ -1042,6 +1055,8 @@ do_mod_rm(void)
|
||||
cpu_state.eaaddr += pfq_fetchw();
|
||||
wait(1, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cpu_state.eaaddr &= 0xffff;
|
||||
wait(2, 0);
|
||||
@@ -1205,18 +1220,20 @@ pop(void)
|
||||
static void
|
||||
interrupt(uint16_t addr)
|
||||
{
|
||||
uint16_t old_cs, old_ip;
|
||||
uint16_t new_cs, new_ip;
|
||||
uint16_t old_cs;
|
||||
uint16_t old_ip;
|
||||
uint16_t new_cs;
|
||||
uint16_t new_ip;
|
||||
uint16_t tempf;
|
||||
|
||||
addr <<= 2;
|
||||
cpu_state.eaaddr = addr;
|
||||
old_cs = CS;
|
||||
new_ip = readmemw(0, cpu_state.eaaddr);
|
||||
new_ip = readmemw(0, cpu_state.eaaddr);
|
||||
wait(1, 0);
|
||||
cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff;
|
||||
new_cs = readmemw(0, cpu_state.eaaddr);
|
||||
prefetching = 0;
|
||||
new_cs = readmemw(0, cpu_state.eaaddr);
|
||||
prefetching = 0;
|
||||
pfq_clear();
|
||||
ovr_seg = NULL;
|
||||
wait(2, 0);
|
||||
@@ -1242,8 +1259,10 @@ interrupt_808x(uint16_t addr)
|
||||
static void
|
||||
custom_nmi(void)
|
||||
{
|
||||
uint16_t old_cs, old_ip;
|
||||
uint16_t new_cs, new_ip;
|
||||
uint16_t old_cs;
|
||||
uint16_t old_ip;
|
||||
uint16_t new_cs;
|
||||
uint16_t new_ip;
|
||||
uint16_t tempf;
|
||||
|
||||
cpu_state.eaaddr = 0x0002;
|
||||
@@ -1286,7 +1305,7 @@ bus_pic_ack(void)
|
||||
{
|
||||
int old_in_lock = in_lock;
|
||||
|
||||
in_lock = 1;
|
||||
in_lock = 1;
|
||||
bus_request_type = BUS_PIC;
|
||||
wait(4, 1);
|
||||
in_lock = old_in_lock;
|
||||
@@ -1366,7 +1385,7 @@ rep_interrupt(void)
|
||||
return 0;
|
||||
}
|
||||
completed = 1;
|
||||
CX = tmpc;
|
||||
CX = tmpc;
|
||||
pfq_clear();
|
||||
if (is_nec && (ovr_seg != NULL))
|
||||
set_ip(cpu_state.pc - 3);
|
||||
@@ -1376,7 +1395,7 @@ rep_interrupt(void)
|
||||
}
|
||||
|
||||
static int
|
||||
rep_action(int bits)
|
||||
rep_action(UNUSED(int bits))
|
||||
{
|
||||
uint16_t t;
|
||||
|
||||
@@ -1562,14 +1581,14 @@ alu_op(int bits)
|
||||
case 2:
|
||||
if (cpu_state.flags & C_FLAG)
|
||||
cpu_src++;
|
||||
/* Fall through. */
|
||||
fallthrough;
|
||||
case 0:
|
||||
add(bits);
|
||||
break;
|
||||
case 3:
|
||||
if (cpu_state.flags & C_FLAG)
|
||||
cpu_src++;
|
||||
/* Fall through. */
|
||||
fallthrough;
|
||||
case 5:
|
||||
case 7:
|
||||
sub(bits);
|
||||
@@ -1580,6 +1599,9 @@ alu_op(int bits)
|
||||
case 6:
|
||||
bitwise(bits, (cpu_dest ^ cpu_src));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1600,10 +1622,11 @@ mul(uint16_t a, uint16_t b)
|
||||
{
|
||||
int negate = 0;
|
||||
int bit_count = 8;
|
||||
int carry, i;
|
||||
int carry;
|
||||
uint16_t high_bit = 0x80;
|
||||
uint16_t size_mask;
|
||||
uint16_t c, r;
|
||||
uint16_t c;
|
||||
uint16_t r;
|
||||
|
||||
size_mask = (1 << bit_count) - 1;
|
||||
|
||||
@@ -1644,7 +1667,7 @@ mul(uint16_t a, uint16_t b)
|
||||
a &= size_mask;
|
||||
carry = (a & 1) != 0;
|
||||
a >>= 1;
|
||||
for (i = 0; i < bit_count; ++i) {
|
||||
for (int i = 0; i < bit_count; ++i) {
|
||||
wait(7, 0);
|
||||
if (carry) {
|
||||
cpu_src = c;
|
||||
@@ -1705,7 +1728,7 @@ set_pzs(int bits)
|
||||
}
|
||||
|
||||
static void
|
||||
set_co_mul(int bits, int carry)
|
||||
set_co_mul(UNUSED(int bits), int carry)
|
||||
{
|
||||
set_cf(carry);
|
||||
set_of(carry);
|
||||
@@ -1718,10 +1741,11 @@ set_co_mul(int bits, int carry)
|
||||
static int
|
||||
x86_div(uint16_t l, uint16_t h)
|
||||
{
|
||||
int b, bit_count = 8;
|
||||
int bit_count = 8;
|
||||
int negative = 0;
|
||||
int dividend_negative = 0;
|
||||
int size_mask, carry;
|
||||
int size_mask;
|
||||
int carry;
|
||||
uint16_t r;
|
||||
|
||||
if (opcode & 1) {
|
||||
@@ -1765,7 +1789,7 @@ x86_div(uint16_t l, uint16_t h)
|
||||
wait(1, 0);
|
||||
wait(2, 0);
|
||||
carry = 1;
|
||||
for (b = 0; b < bit_count; ++b) {
|
||||
for (int b = 0; b < bit_count; ++b) {
|
||||
r = (l << 1) + (carry ? 1 : 0);
|
||||
carry = top_bit(l, bit_count);
|
||||
l = r;
|
||||
@@ -1948,20 +1972,46 @@ cpu_outw(uint16_t port, uint16_t val)
|
||||
void
|
||||
execx86(int cycs)
|
||||
{
|
||||
uint8_t temp = 0, temp2, old_af, nests;
|
||||
uint8_t temp_val, temp_al, bit, handled = 0;
|
||||
uint8_t odd, zero, nibbles_count, destcmp;
|
||||
uint8_t destbyte, srcbyte, nibble_result, bit_length;
|
||||
uint8_t temp = 0;
|
||||
uint8_t temp2;
|
||||
uint8_t old_af;
|
||||
uint8_t nests;
|
||||
uint8_t temp_val;
|
||||
uint8_t temp_al;
|
||||
uint8_t bit;
|
||||
uint8_t handled = 0;
|
||||
uint8_t odd;
|
||||
uint8_t zero;
|
||||
uint8_t nibbles_count;
|
||||
uint8_t destcmp;
|
||||
uint8_t destbyte;
|
||||
uint8_t srcbyte;
|
||||
uint8_t nibble_result;
|
||||
uint8_t bit_length;
|
||||
uint8_t bit_offset;
|
||||
int8_t nibble_result_s;
|
||||
uint16_t addr, tempw, new_cs, new_ip;
|
||||
uint16_t tempw_int, size, tempbp, lowbound;
|
||||
uint16_t highbound, regval, orig_sp, wordtopush;
|
||||
uint16_t immediate, old_flags;
|
||||
uint16_t tmpa;
|
||||
uint16_t addr;
|
||||
uint16_t tempw;
|
||||
uint16_t new_cs;
|
||||
uint16_t new_ip;
|
||||
uint16_t tempw_int;
|
||||
uint16_t size;
|
||||
uint16_t tempbp;
|
||||
uint16_t lowbound;
|
||||
uint16_t highbound;
|
||||
uint16_t regval;
|
||||
uint16_t orig_sp;
|
||||
uint16_t wordtopush;
|
||||
uint16_t immediate;
|
||||
uint16_t old_flags;
|
||||
uint16_t tmpa;
|
||||
int bits;
|
||||
uint32_t dest_seg, i, carry, nibble;
|
||||
uint32_t srcseg, byteaddr;
|
||||
uint32_t dest_seg;
|
||||
uint32_t i;
|
||||
uint32_t carry;
|
||||
uint32_t nibble;
|
||||
uint32_t srcseg;
|
||||
uint32_t byteaddr;
|
||||
|
||||
cycles += cycs;
|
||||
|
||||
@@ -1970,10 +2020,12 @@ execx86(int cycs)
|
||||
|
||||
if (!repeating) {
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
// opcode = pfq_fetchb();
|
||||
opcode = pfq_fetchb_common();
|
||||
handled = 0;
|
||||
oldc = cpu_state.flags & C_FLAG;
|
||||
#if 0
|
||||
opcode = pfq_fetchb();
|
||||
#endif
|
||||
opcode = pfq_fetchb_common();
|
||||
handled = 0;
|
||||
oldc = cpu_state.flags & C_FLAG;
|
||||
if (clear_lock) {
|
||||
in_lock = 0;
|
||||
clear_lock = 0;
|
||||
@@ -2233,6 +2285,9 @@ execx86(int cycs)
|
||||
set_af(0);
|
||||
set_pzs(bits);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((opcode & 2) != 0)
|
||||
wait(4, 0);
|
||||
@@ -2247,6 +2302,9 @@ execx86(int cycs)
|
||||
BP = pop();
|
||||
handled = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!handled) {
|
||||
@@ -2498,7 +2556,7 @@ execx86(int cycs)
|
||||
}
|
||||
for (i = 0; i < bit_length; i++) {
|
||||
byteaddr = (es) + DI;
|
||||
writememb(es, DI, (read_mem_b(byteaddr) & ~(1 << (bit_offset))) | ((!!(AX & (1 << i))) << bit_offset));
|
||||
writememb(es, DI, (read_mem_b(byteaddr) & ~(1 << bit_offset)) | ((!!(AX & (1 << i))) << bit_offset));
|
||||
bit_offset++;
|
||||
if (bit_offset == 8) {
|
||||
DI++;
|
||||
@@ -2547,7 +2605,7 @@ execx86(int cycs)
|
||||
break;
|
||||
|
||||
default:
|
||||
opcode = orig_opcode;
|
||||
opcode = orig_opcode;
|
||||
cpu_state.pc = (cpu_state.pc - 1) & 0xffff;
|
||||
break;
|
||||
}
|
||||
@@ -3063,7 +3121,7 @@ execx86(int cycs)
|
||||
bits = 8 << (opcode & 1);
|
||||
wait(2, 0);
|
||||
cpu_state.eaaddr = pfq_fetchw();
|
||||
set_accum(bits, readmem((ovr_seg ? *ovr_seg : ds)));
|
||||
set_accum(bits, readmem(ovr_seg ? *ovr_seg : ds));
|
||||
break;
|
||||
case 0xA2:
|
||||
case 0xA3:
|
||||
@@ -3125,7 +3183,7 @@ execx86(int cycs)
|
||||
wait(2, 0);
|
||||
cpu_state.eaaddr = DI;
|
||||
cpu_data = readmem(es);
|
||||
DI = string_increment(bits);
|
||||
DI = string_increment(bits);
|
||||
cpu_src = cpu_data;
|
||||
cpu_dest = tmpa;
|
||||
sub(bits);
|
||||
@@ -3392,6 +3450,9 @@ execx86(int cycs)
|
||||
set_af(0);
|
||||
set_pzs(bits);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((opcode & 2) != 0)
|
||||
wait(4, 0);
|
||||
@@ -3453,55 +3514,61 @@ execx86(int cycs)
|
||||
if (fpu_softfloat) {
|
||||
switch (opcode) {
|
||||
case 0xD8:
|
||||
ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
|
||||
ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat);
|
||||
break;
|
||||
case 0xD9:
|
||||
ops_sf_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_sf_fpu_8087_d9[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDA:
|
||||
ops_sf_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_sf_fpu_8087_da[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDB:
|
||||
ops_sf_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_sf_fpu_8087_db[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDC:
|
||||
ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
|
||||
ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat);
|
||||
break;
|
||||
case 0xDD:
|
||||
ops_sf_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_sf_fpu_8087_dd[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDE:
|
||||
ops_sf_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_sf_fpu_8087_de[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDF:
|
||||
ops_sf_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_sf_fpu_8087_df[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (opcode) {
|
||||
case 0xD8:
|
||||
ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
|
||||
ops_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat);
|
||||
break;
|
||||
case 0xD9:
|
||||
ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_fpu_8087_d9[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDA:
|
||||
ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_fpu_8087_da[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDB:
|
||||
ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_fpu_8087_db[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDC:
|
||||
ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
|
||||
ops_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat);
|
||||
break;
|
||||
case 0xDD:
|
||||
ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_fpu_8087_dd[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDE:
|
||||
ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_fpu_8087_de[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDF:
|
||||
ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat);
|
||||
ops_fpu_8087_df[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3531,6 +3598,9 @@ execx86(int cycs)
|
||||
if (!(cpu_state.flags & Z_FLAG))
|
||||
oldc = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
oldc = (CX == 0);
|
||||
@@ -3542,7 +3612,7 @@ execx86(int cycs)
|
||||
case 0xE5:
|
||||
bits = 8 << (opcode & 1);
|
||||
wait(1, 0);
|
||||
cpu_data = pfq_fetchb();
|
||||
cpu_data = pfq_fetchb();
|
||||
cpu_state.eaaddr = cpu_data;
|
||||
wait(1, 0);
|
||||
cpu_io(bits, 0, cpu_state.eaaddr);
|
||||
@@ -3551,16 +3621,16 @@ execx86(int cycs)
|
||||
case 0xE7:
|
||||
bits = 8 << (opcode & 1);
|
||||
wait(1, 0);
|
||||
cpu_data = pfq_fetchb();
|
||||
cpu_data = pfq_fetchb();
|
||||
cpu_state.eaaddr = cpu_data;
|
||||
cpu_data = (bits == 16) ? AX : AL;
|
||||
cpu_data = (bits == 16) ? AX : AL;
|
||||
wait(2, 0);
|
||||
cpu_io(bits, 1, cpu_state.eaaddr);
|
||||
break;
|
||||
case 0xEC:
|
||||
case 0xED:
|
||||
bits = 8 << (opcode & 1);
|
||||
cpu_data = DX;
|
||||
bits = 8 << (opcode & 1);
|
||||
cpu_data = DX;
|
||||
cpu_state.eaaddr = cpu_data;
|
||||
wait(1, 0);
|
||||
cpu_io(bits, 0, cpu_state.eaaddr);
|
||||
@@ -3569,9 +3639,9 @@ execx86(int cycs)
|
||||
case 0xEF:
|
||||
bits = 8 << (opcode & 1);
|
||||
wait(2, 0);
|
||||
cpu_data = DX;
|
||||
cpu_data = DX;
|
||||
cpu_state.eaaddr = cpu_data;
|
||||
cpu_data = (bits == 16) ? AX : AL;
|
||||
cpu_data = (bits == 16) ? AX : AL;
|
||||
cpu_io(bits, 1, cpu_state.eaaddr);
|
||||
wait(1, 0);
|
||||
break;
|
||||
@@ -3703,6 +3773,9 @@ execx86(int cycs)
|
||||
if (x86_div(AL, AH))
|
||||
wait(1, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3800,7 +3873,10 @@ execx86(int cycs)
|
||||
if (cpu_mod != 3)
|
||||
wait(1, 0);
|
||||
wait(4, 0);
|
||||
push((uint16_t *) &(cpu_data));
|
||||
push((uint16_t *) &cpu_data);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* Copyright 2023 gloriouscow.
|
||||
* Copyright 2023 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@@ -41,12 +42,13 @@
|
||||
/* 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;
|
||||
/* NOTE: When porting from Rust to C, please use uintptr_t and not size_t,
|
||||
so it can be printed with PRIuPTR. */
|
||||
typedef struct queue_t {
|
||||
uintptr_t size;
|
||||
uintptr_t len;
|
||||
uintptr_t back;
|
||||
uintptr_t front;
|
||||
uint8_t q[QUEUE_MAX];
|
||||
uint16_t preload;
|
||||
queue_delay_t delay;
|
||||
@@ -73,15 +75,15 @@ queue_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
void
|
||||
queue_set_size(size_t size)
|
||||
queue_set_size(uintptr_t size)
|
||||
{
|
||||
if (size > QUEUE_MAX)
|
||||
fatal("Requested prefetch queue of %i bytes is too big\n", size);
|
||||
fatal("Requested prefetch queue of %" PRIuPTR " bytes is too big\n", size);
|
||||
|
||||
queue.size = size;
|
||||
}
|
||||
|
||||
size_t
|
||||
uintptr_t
|
||||
queue_get_len(void)
|
||||
{
|
||||
return queue.len;
|
||||
|
||||
@@ -17,27 +17,26 @@
|
||||
#ifndef EMU_QUEUE_H
|
||||
#define EMU_QUEUE_H
|
||||
|
||||
typedef enum queue_delay_t
|
||||
{
|
||||
typedef enum queue_delay_t {
|
||||
DELAY_READ,
|
||||
DELAY_WRITE,
|
||||
DELAY_NONE
|
||||
} queue_delay_t;
|
||||
|
||||
#define FLAG_PRELOADED 0x8000
|
||||
#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_set_size(uintptr_t size);
|
||||
extern uintptr_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);
|
||||
extern void queue_init(void);
|
||||
|
||||
#endif /*EMU_QUEUE_H*/
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mem.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
@@ -12,11 +14,11 @@
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
#define CYCLES(c) (int *)c
|
||||
#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8))
|
||||
#define CYCLES(c) (int *) c
|
||||
#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8))
|
||||
|
||||
static int *opcode_timings[256] =
|
||||
{
|
||||
static int *opcode_timings[256] = {
|
||||
// clang-format off
|
||||
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
|
||||
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
|
||||
/*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
|
||||
@@ -36,10 +38,11 @@ static int *opcode_timings[256] =
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_mod3[256] =
|
||||
{
|
||||
static int *opcode_timings_mod3[256] = {
|
||||
// clang-format off
|
||||
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
|
||||
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
|
||||
/*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
|
||||
@@ -59,10 +62,11 @@ static int *opcode_timings_mod3[256] =
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_0f[256] =
|
||||
{
|
||||
static int *opcode_timings_0f[256] = {
|
||||
// clang-format off
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -82,9 +86,10 @@ static int *opcode_timings_0f[256] =
|
||||
/*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_0f_mod3[256] =
|
||||
{
|
||||
static int *opcode_timings_0f_mod3[256] = {
|
||||
// clang-format off
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -104,60 +109,69 @@ static int *opcode_timings_0f_mod3[256] =
|
||||
/*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_shift[8] =
|
||||
{
|
||||
static int *opcode_timings_shift[8] = {
|
||||
// clang-format off
|
||||
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
|
||||
};
|
||||
static int *opcode_timings_shift_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_shift_mod3[8] = {
|
||||
// clang-format off
|
||||
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_f6[8] =
|
||||
{
|
||||
static int *opcode_timings_f6[8] = {
|
||||
// clang-format off
|
||||
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_f6_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_f6_mod3[8] = {
|
||||
// clang-format off
|
||||
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_f7[8] =
|
||||
{
|
||||
static int *opcode_timings_f7[8] = {
|
||||
// clang-format off
|
||||
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_f7_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_f7_mod3[8] = {
|
||||
// clang-format off
|
||||
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
};
|
||||
static int *opcode_timings_ff[8] =
|
||||
{
|
||||
static int *opcode_timings_ff[8] = {
|
||||
// clang-format off
|
||||
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
|
||||
};
|
||||
static int *opcode_timings_ff_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_ff_mod3[8] = {
|
||||
// clang-format off
|
||||
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_d8[8] =
|
||||
{
|
||||
static int *opcode_timings_d8[8] = {
|
||||
// clang-format off
|
||||
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_d8_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_d8_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
|
||||
CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_d9[8] =
|
||||
{
|
||||
static int *opcode_timings_d9[8] = {
|
||||
// clang-format off
|
||||
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
|
||||
CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_d9_mod3[64] =
|
||||
{
|
||||
static int *opcode_timings_d9_mod3[64] = {
|
||||
// clang-format off
|
||||
/*FLD*/
|
||||
CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4),
|
||||
/*FXCH*/
|
||||
@@ -174,26 +188,29 @@ static int *opcode_timings_d9_mod3[64] =
|
||||
CYCLES(140), CYCLES(196), CYCLES(200), CYCLES(218), NULL, NULL, CYCLES(3), CYCLES(3),
|
||||
/* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/
|
||||
CYCLES(70), NULL, CYCLES(83), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(257), CYCLES(257)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_da[8] =
|
||||
{
|
||||
static int *opcode_timings_da[8] = {
|
||||
// clang-format off
|
||||
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_da_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_da_mod3[8] = {
|
||||
// clang-format off
|
||||
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
static int *opcode_timings_db[8] =
|
||||
{
|
||||
static int *opcode_timings_db[8] = {
|
||||
// clang-format off
|
||||
/* FLDil FSTil FSTPil FLDe FSTPe*/
|
||||
CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_db_mod3[64] =
|
||||
{
|
||||
static int *opcode_timings_db_mod3[64] = {
|
||||
// clang-format off
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -203,219 +220,242 @@ static int *opcode_timings_db_mod3[64] =
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_dc[8] =
|
||||
{
|
||||
static int *opcode_timings_dc[8] = {
|
||||
// clang-format off
|
||||
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
|
||||
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_dc_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_dc_mod3[8] = {
|
||||
// clang-format off
|
||||
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
|
||||
CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_dd[8] =
|
||||
{
|
||||
static int *opcode_timings_dd[8] = {
|
||||
// clang-format off
|
||||
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
|
||||
CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_dd_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_dd_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FFFREE FST FSTP FUCOM FUCOMP*/
|
||||
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_de[8] =
|
||||
{
|
||||
static int *opcode_timings_de[8] = {
|
||||
// clang-format off
|
||||
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_de_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_de_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
|
||||
CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_df[8] =
|
||||
{
|
||||
static int *opcode_timings_df[8] = {
|
||||
// clang-format off
|
||||
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
|
||||
CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_df_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_df_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FFREE FST FSTP FUCOM FUCOMP*/
|
||||
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_8x[8] =
|
||||
{
|
||||
static int *opcode_timings_8x[8] = {
|
||||
// clang-format off
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_8x_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_8x_mod3[8] = {
|
||||
// clang-format off
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_81[8] =
|
||||
{
|
||||
static int *opcode_timings_81[8] = {
|
||||
// clang-format off
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_81_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_81_mod3[8] = {
|
||||
// clang-format off
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static uint32_t regmask_modified;
|
||||
|
||||
static inline int COUNT(int *c, int op_32)
|
||||
static inline int
|
||||
COUNT(int *c, int op_32)
|
||||
{
|
||||
if ((uintptr_t)c <= 10000)
|
||||
return (int)(uintptr_t)c;
|
||||
if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff))
|
||||
{
|
||||
if (op_32 & 0x100)
|
||||
return ((uintptr_t)c >> 8) & 0xff;
|
||||
return (uintptr_t)c & 0xff;
|
||||
}
|
||||
return *c;
|
||||
if ((uintptr_t) c <= 10000)
|
||||
return (int) (uintptr_t) c;
|
||||
if (((uintptr_t) c & ~0xffff) == (-1 & ~0xffff)) {
|
||||
if (op_32 & 0x100)
|
||||
return ((uintptr_t) c >> 8) & 0xff;
|
||||
return (uintptr_t) c & 0xff;
|
||||
}
|
||||
return *c;
|
||||
}
|
||||
|
||||
void codegen_timing_486_block_start(void)
|
||||
void
|
||||
codegen_timing_486_block_start(void)
|
||||
{
|
||||
regmask_modified = 0;
|
||||
regmask_modified = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_486_start(void)
|
||||
void
|
||||
codegen_timing_486_start(void)
|
||||
{
|
||||
timing_count = 0;
|
||||
last_prefix = 0;
|
||||
timing_count = 0;
|
||||
last_prefix = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
void
|
||||
codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
{
|
||||
timing_count += COUNT(opcode_timings[prefix], 0);
|
||||
last_prefix = prefix;
|
||||
timing_count += COUNT(opcode_timings[prefix], 0);
|
||||
last_prefix = prefix;
|
||||
}
|
||||
|
||||
void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
|
||||
void
|
||||
codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc))
|
||||
{
|
||||
int **timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
int **timings;
|
||||
const uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
|
||||
switch (last_prefix)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
switch (last_prefix) {
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode) {
|
||||
case 0x80:
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
case 0xc1:
|
||||
case 0xd0:
|
||||
case 0xd1:
|
||||
case 0xd2:
|
||||
case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
timing_count += COUNT(timings[opcode], op_32);
|
||||
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
|
||||
timing_count++; /*AGI stall*/
|
||||
codegen_block_cycles += timing_count;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timing_count += COUNT(timings[opcode], op_32);
|
||||
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
|
||||
timing_count++; /*AGI stall*/
|
||||
codegen_block_cycles += timing_count;
|
||||
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
|
||||
void codegen_timing_486_block_end(void)
|
||||
void
|
||||
codegen_timing_486_block_end(void)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_486 =
|
||||
{
|
||||
codegen_timing_486_start,
|
||||
codegen_timing_486_prefix,
|
||||
codegen_timing_486_opcode,
|
||||
codegen_timing_486_block_start,
|
||||
codegen_timing_486_block_end,
|
||||
NULL
|
||||
codegen_timing_t codegen_timing_486 = {
|
||||
codegen_timing_486_start,
|
||||
codegen_timing_486_prefix,
|
||||
codegen_timing_486_opcode,
|
||||
codegen_timing_486_block_start,
|
||||
codegen_timing_486_block_end,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/mem.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
@@ -22,7 +24,7 @@
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
/*Instruction has different execution time for 16 and 32 bit data. Does not pair */
|
||||
#define CYCLES_HAS_MULTI (1 << 31)
|
||||
#define CYCLES_HAS_MULTI (1 << 31)
|
||||
|
||||
#define CYCLES_MULTI(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8))
|
||||
|
||||
@@ -31,39 +33,39 @@
|
||||
|
||||
/*Instruction follows either register timing, read-modify, or read-modify-write.
|
||||
May be pairable*/
|
||||
#define CYCLES_REG (1 << 0)
|
||||
#define CYCLES_RM (1 << 0)
|
||||
#define CYCLES_RMW (1 << 0)
|
||||
#define CYCLES_REG (1 << 0)
|
||||
#define CYCLES_RM (1 << 0)
|
||||
#define CYCLES_RMW (1 << 0)
|
||||
#define CYCLES_BRANCH (1 << 0)
|
||||
|
||||
#define CYCLES_MASK ((1 << 7) - 1)
|
||||
#define CYCLES_MASK ((1 << 7) - 1)
|
||||
|
||||
/*Instruction does not pair*/
|
||||
#define PAIR_NP (0 << 29)
|
||||
/*Instruction pairs in X pipe only*/
|
||||
#define PAIR_X (1 << 29)
|
||||
#define PAIR_X (1 << 29)
|
||||
/*Instruction pairs in X pipe only, and can not pair with a following instruction*/
|
||||
#define PAIR_X_BRANCH (2 << 29)
|
||||
#define PAIR_X_BRANCH (2 << 29)
|
||||
/*Instruction pairs in both X and Y pipes*/
|
||||
#define PAIR_XY (3 << 29)
|
||||
#define PAIR_XY (3 << 29)
|
||||
|
||||
#define PAIR_MASK (3 << 29)
|
||||
|
||||
#define INVALID 0
|
||||
#define INVALID 0
|
||||
|
||||
static int prev_full;
|
||||
static uint32_t prev_opcode;
|
||||
static int prev_full;
|
||||
static uint32_t prev_opcode;
|
||||
static uint32_t *prev_timings;
|
||||
static uint32_t prev_op_32;
|
||||
static uint32_t prev_regmask;
|
||||
static uint32_t prev_op_32;
|
||||
static uint32_t prev_regmask;
|
||||
static uint64_t *prev_deps;
|
||||
static uint32_t prev_fetchdat;
|
||||
static uint32_t prev_fetchdat;
|
||||
|
||||
static uint32_t last_regmask_modified;
|
||||
static uint32_t regmask_modified;
|
||||
|
||||
static uint32_t opcode_timings[256] =
|
||||
{
|
||||
static uint32_t opcode_timings[256] = {
|
||||
// clang-format off
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
@@ -196,10 +198,11 @@ static uint32_t opcode_timings[256] =
|
||||
PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7),
|
||||
/* CLD STD INCDEC*/
|
||||
PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_RMW, INVALID
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_mod3[256] =
|
||||
{
|
||||
static uint32_t opcode_timings_mod3[256] = {
|
||||
// clang-format off
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
@@ -333,10 +336,11 @@ static uint32_t opcode_timings_mod3[256] =
|
||||
PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7),
|
||||
/* CLD STD INCDEC*/
|
||||
PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_REG, INVALID
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_0f[256] =
|
||||
{
|
||||
static uint32_t opcode_timings_0f[256] = {
|
||||
// clang-format off
|
||||
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
|
||||
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
|
||||
PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID,
|
||||
@@ -416,9 +420,10 @@ static uint32_t opcode_timings_0f[256] =
|
||||
INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_0f_mod3[256] =
|
||||
{
|
||||
static uint32_t opcode_timings_0f_mod3[256] = {
|
||||
// clang-format off
|
||||
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
|
||||
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
|
||||
PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID,
|
||||
@@ -497,106 +502,122 @@ static uint32_t opcode_timings_0f_mod3[256] =
|
||||
INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_shift[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_shift[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_shift_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_shift_mod3[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_shift_imm[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_shift_imm[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_shift_imm_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_shift_imm_mod3[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_shift_cl[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_shift_cl[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_shift_cl_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_shift_cl_mod3[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_f6[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_f6[8] = {
|
||||
// clang-format off
|
||||
/* TST NOT NEG*/
|
||||
PAIR_XY | CYCLES_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_f6_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_f6_mod3[8] = {
|
||||
// clang-format off
|
||||
/* TST NOT NEG*/
|
||||
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_f7[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_f7[8] = {
|
||||
// clang-format off
|
||||
/* TST NOT NEG*/
|
||||
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_f7_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_f7_mod3[8] = {
|
||||
// clang-format off
|
||||
/* TST NOT NEG*/
|
||||
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_ff[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_ff[8] = {
|
||||
// clang-format off
|
||||
/* INC DEC CALL CALL far*/
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5),
|
||||
/* JMP JMP far PUSH*/
|
||||
PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_ff_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_ff_mod3[8] = {
|
||||
// clang-format off
|
||||
/* INC DEC CALL CALL far*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5),
|
||||
/* JMP JMP far PUSH*/
|
||||
PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), PAIR_XY | CYCLES(2), INVALID
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_d8[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_d8[8] = {
|
||||
// clang-format off
|
||||
/* FADDs FMULs FCOMs FCOMPs*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
|
||||
/* FSUBs FSUBRs FDIVs FDIVRs*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_d8_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_d8_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FADD FMUL FCOM FCOMP*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
|
||||
/* FSUB FSUBR FDIV FDIVR*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_d9[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_d9[8] = {
|
||||
// clang-format off
|
||||
/* FLDs FSTs FSTPs*/
|
||||
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
|
||||
/* FLDENV FLDCW FSTENV FSTCW*/
|
||||
PAIR_X | CYCLES(30), PAIR_X | CYCLES(4), PAIR_X | CYCLES(24), PAIR_X | CYCLES(5)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_d9_mod3[64] =
|
||||
{
|
||||
static uint32_t opcode_timings_d9_mod3[64] = {
|
||||
// clang-format off
|
||||
/*FLD*/
|
||||
PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
|
||||
PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
|
||||
@@ -625,31 +646,34 @@ static uint32_t opcode_timings_d9_mod3[64] =
|
||||
PAIR_X | CYCLES(91), INVALID, PAIR_X | CYCLES(60), PAIR_X | CYCLES(161),
|
||||
/* opFRNDINT opFSCALE opFSIN opFCOS*/
|
||||
PAIR_X | CYCLES(20), PAIR_X | CYCLES(14), PAIR_X | CYCLES(140), PAIR_X | CYCLES(141)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_da[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_da[8] = {
|
||||
// clang-format off
|
||||
/* FIADDl FIMULl FICOMl FICOMPl*/
|
||||
PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10),
|
||||
/* FISUBl FISUBRl FIDIVl FIDIVRl*/
|
||||
PAIR_X | CYCLES(29), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(48)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_da_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_da_mod3[8] = {
|
||||
// clang-format off
|
||||
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
|
||||
INVALID, PAIR_X | CYCLES(5), INVALID, INVALID
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
static uint32_t opcode_timings_db[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_db[8] = {
|
||||
// clang-format off
|
||||
/* FLDil FSTil FSTPil*/
|
||||
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
|
||||
/* FLDe FSTPe*/
|
||||
INVALID, PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_db_mod3[64] =
|
||||
{
|
||||
static uint32_t opcode_timings_db_mod3[64] = {
|
||||
// clang-format off
|
||||
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
|
||||
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
|
||||
|
||||
@@ -675,383 +699,387 @@ static uint32_t opcode_timings_db_mod3[64] =
|
||||
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_dc[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_dc[8] = {
|
||||
// clang-format off
|
||||
/* FADDd FMULd FCOMd FCOMPd*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7),
|
||||
/* FSUBd FSUBRd FDIVd FDIVRd*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_dc_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_dc_mod3[8] = {
|
||||
// clang-format off
|
||||
/* opFADDr opFMULr*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, INVALID,
|
||||
/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_dd[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_dd[8] = {
|
||||
// clang-format off
|
||||
/* FLDd FSTd FSTPd*/
|
||||
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
|
||||
/* FRSTOR FSAVE FSTSW*/
|
||||
PAIR_X | CYCLES(72), INVALID, PAIR_X | CYCLES(67), PAIR_X | CYCLES(2)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_dd_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_dd_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FFFREE FST FSTP*/
|
||||
PAIR_X | CYCLES(3), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
|
||||
/* FUCOM FUCOMP*/
|
||||
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, INVALID
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_de[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_de[8] = {
|
||||
// clang-format off
|
||||
/* FIADDw FIMULw FICOMw FICOMPw*/
|
||||
PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10),
|
||||
/* FISUBw FISUBRw FIDIVw FIDIVRw*/
|
||||
PAIR_X | CYCLES(27), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(38)
|
||||
};
|
||||
static uint32_t opcode_timings_de_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_de_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FADD FMUL FCOMPP*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, PAIR_X | CYCLES(7),
|
||||
/* FSUB FSUBR FDIV FDIVR*/
|
||||
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_df[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_df[8] = {
|
||||
// clang-format off
|
||||
/* FILDiw FISTiw FISTPiw*/
|
||||
PAIR_X | CYCLES(8), INVALID, PAIR_X | CYCLES(10), PAIR_X | CYCLES(13),
|
||||
/* FILDiq FBSTP FISTPiq*/
|
||||
INVALID, PAIR_X | CYCLES(8), PAIR_X | CYCLES(63), PAIR_X | CYCLES(13)
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_df_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_df_mod3[8] = {
|
||||
// clang-format off
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
/* FSTSW AX*/
|
||||
PAIR_X | CYCLES(6), INVALID, INVALID, INVALID
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_8x[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_8x[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_8x_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_8x_mod3[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_81[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_81[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
|
||||
// clang-format on
|
||||
};
|
||||
static uint32_t opcode_timings_81_mod3[8] =
|
||||
{
|
||||
static uint32_t opcode_timings_81_mod3[8] = {
|
||||
// clang-format off
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int decode_delay;
|
||||
static int decode_delay;
|
||||
static uint8_t last_prefix;
|
||||
|
||||
static inline int COUNT(uint32_t c, int op_32)
|
||||
static inline int
|
||||
COUNT(uint32_t c, int op_32)
|
||||
{
|
||||
if (c & CYCLES_HAS_MULTI)
|
||||
{
|
||||
if (op_32 & 0x100)
|
||||
return ((uintptr_t)c >> 8) & 0xff;
|
||||
return (uintptr_t)c & 0xff;
|
||||
}
|
||||
if (!(c & PAIR_MASK))
|
||||
return c & 0xffff;
|
||||
if (c & CYCLES_HAS_MULTI) {
|
||||
if (op_32 & 0x100)
|
||||
return ((uintptr_t) c >> 8) & 0xff;
|
||||
return (uintptr_t) c & 0xff;
|
||||
}
|
||||
if (!(c & PAIR_MASK))
|
||||
return c & 0xffff;
|
||||
|
||||
return c & CYCLES_MASK;
|
||||
return c & CYCLES_MASK;
|
||||
}
|
||||
|
||||
void codegen_timing_686_block_start(void)
|
||||
void
|
||||
codegen_timing_686_block_start(void)
|
||||
{
|
||||
prev_full = decode_delay = 0;
|
||||
regmask_modified = last_regmask_modified = 0;
|
||||
prev_full = decode_delay = 0;
|
||||
regmask_modified = last_regmask_modified = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_686_start(void)
|
||||
void
|
||||
codegen_timing_686_start(void)
|
||||
{
|
||||
decode_delay = 0;
|
||||
last_prefix = 0;
|
||||
decode_delay = 0;
|
||||
last_prefix = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
void
|
||||
codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
{
|
||||
if ((prefix & 0xf8) == 0xd8)
|
||||
{
|
||||
last_prefix = prefix;
|
||||
return;
|
||||
}
|
||||
if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80)
|
||||
{
|
||||
/*0fh prefix is 'free' when used on conditional jumps*/
|
||||
last_prefix = prefix;
|
||||
return;
|
||||
}
|
||||
|
||||
/*6x86 can decode 1 prefix per instruction per clock with no penalty. If
|
||||
either instruction has more than one prefix then decode is delayed by
|
||||
one cycle for each additional prefix*/
|
||||
decode_delay++;
|
||||
if ((prefix & 0xf8) == 0xd8) {
|
||||
last_prefix = prefix;
|
||||
return;
|
||||
}
|
||||
if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) {
|
||||
/*0fh prefix is 'free' when used on conditional jumps*/
|
||||
last_prefix = prefix;
|
||||
return;
|
||||
}
|
||||
|
||||
/*6x86 can decode 1 prefix per instruction per clock with no penalty. If
|
||||
either instruction has more than one prefix then decode is delayed by
|
||||
one cycle for each additional prefix*/
|
||||
decode_delay++;
|
||||
last_prefix = prefix;
|
||||
}
|
||||
|
||||
static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
static int
|
||||
check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32);
|
||||
uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32);
|
||||
|
||||
if (addr_regmask & IMPL_ESP)
|
||||
addr_regmask |= (1 << REG_ESP);
|
||||
if (addr_regmask & IMPL_ESP)
|
||||
addr_regmask |= (1 << REG_ESP);
|
||||
|
||||
if (regmask_modified & addr_regmask)
|
||||
{
|
||||
regmask_modified = 0;
|
||||
return 2;
|
||||
}
|
||||
if (regmask_modified & addr_regmask) {
|
||||
regmask_modified = 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (last_regmask_modified & addr_regmask)
|
||||
return 1;
|
||||
if (last_regmask_modified & addr_regmask)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
|
||||
void
|
||||
codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc))
|
||||
{
|
||||
uint32_t *timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
uint32_t *timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
|
||||
switch (last_prefix)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
switch (last_prefix) {
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode) {
|
||||
case 0x80:
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
case 0xc1:
|
||||
timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xd0:
|
||||
case 0xd1:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xd2:
|
||||
case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl;
|
||||
deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 0xc0: case 0xc1:
|
||||
timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
/*One prefix per instruction is free*/
|
||||
decode_delay--;
|
||||
if (decode_delay < 0)
|
||||
decode_delay = 0;
|
||||
|
||||
case 0xd0: case 0xd1:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
if (prev_full) {
|
||||
uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32);
|
||||
int agi_stall = 0;
|
||||
|
||||
case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl;
|
||||
deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
if (regmask & IMPL_ESP)
|
||||
regmask |= SRCDEP_ESP | DSTDEP_ESP;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32);
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
/*Second instruction in the pair*/
|
||||
if ((timings[opcode] & PAIR_MASK) == PAIR_NP) {
|
||||
/*Instruction can not pair with previous*/
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
|
||||
prev_full = 0;
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = prev_regmask;
|
||||
} else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
|
||||
&& (prev_timings[opcode] & PAIR_MASK) == PAIR_X) {
|
||||
/*Instruction can not pair with previous*/
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
|
||||
prev_full = 0;
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = prev_regmask;
|
||||
} else if (prev_regmask & regmask) {
|
||||
/*Instruction can not pair with previous*/
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
|
||||
prev_full = 0;
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = prev_regmask;
|
||||
} else {
|
||||
int t1 = COUNT(prev_timings[prev_opcode], prev_op_32);
|
||||
int t2 = COUNT(timings[opcode], op_32);
|
||||
int t_pair = (t1 > t2) ? t1 : t2;
|
||||
|
||||
if (!t_pair)
|
||||
fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode);
|
||||
|
||||
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
|
||||
|
||||
codegen_block_cycles += t_pair + agi_stall;
|
||||
decode_delay = (-t_pair) + 1 + agi_stall;
|
||||
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask;
|
||||
prev_full = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*One prefix per instruction is free*/
|
||||
decode_delay--;
|
||||
if (decode_delay < 0)
|
||||
decode_delay = 0;
|
||||
if (!prev_full) {
|
||||
/*First instruction in the pair*/
|
||||
if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) {
|
||||
/*Instruction not pairable*/
|
||||
int agi_stall = 0;
|
||||
|
||||
if (prev_full)
|
||||
{
|
||||
uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32);
|
||||
int agi_stall = 0;
|
||||
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
|
||||
|
||||
if (regmask & IMPL_ESP)
|
||||
regmask |= SRCDEP_ESP | DSTDEP_ESP;
|
||||
|
||||
agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32);
|
||||
|
||||
/*Second instruction in the pair*/
|
||||
if ((timings[opcode] & PAIR_MASK) == PAIR_NP)
|
||||
{
|
||||
/*Instruction can not pair with previous*/
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
|
||||
prev_full = 0;
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = prev_regmask;
|
||||
}
|
||||
else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
|
||||
&& (prev_timings[opcode] & PAIR_MASK) == PAIR_X)
|
||||
{
|
||||
/*Instruction can not pair with previous*/
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
|
||||
prev_full = 0;
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = prev_regmask;
|
||||
}
|
||||
else if (prev_regmask & regmask)
|
||||
{
|
||||
/*Instruction can not pair with previous*/
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
|
||||
prev_full = 0;
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = prev_regmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
int t1 = COUNT(prev_timings[prev_opcode], prev_op_32);
|
||||
int t2 = COUNT(timings[opcode], op_32);
|
||||
int t_pair = (t1 > t2) ? t1 : t2;
|
||||
|
||||
if (!t_pair)
|
||||
fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode);
|
||||
|
||||
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
|
||||
|
||||
codegen_block_cycles += t_pair + agi_stall;
|
||||
decode_delay = (-t_pair) + 1 + agi_stall;
|
||||
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask;
|
||||
prev_full = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!prev_full)
|
||||
{
|
||||
/*First instruction in the pair*/
|
||||
if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
|
||||
{
|
||||
/*Instruction not pairable*/
|
||||
int agi_stall = 0;
|
||||
|
||||
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
|
||||
|
||||
codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall;
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Instruction might pair with next*/
|
||||
prev_full = 1;
|
||||
prev_opcode = opcode;
|
||||
prev_timings = timings;
|
||||
prev_op_32 = op_32;
|
||||
prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
if (prev_regmask & IMPL_ESP)
|
||||
prev_regmask |= SRCDEP_ESP | DSTDEP_ESP;
|
||||
prev_deps = deps;
|
||||
prev_fetchdat = fetchdat;
|
||||
return;
|
||||
}
|
||||
codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall;
|
||||
last_regmask_modified = regmask_modified;
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
} else {
|
||||
/*Instruction might pair with next*/
|
||||
prev_full = 1;
|
||||
prev_opcode = opcode;
|
||||
prev_timings = timings;
|
||||
prev_op_32 = op_32;
|
||||
prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
if (prev_regmask & IMPL_ESP)
|
||||
prev_regmask |= SRCDEP_ESP | DSTDEP_ESP;
|
||||
prev_deps = deps;
|
||||
prev_fetchdat = fetchdat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_timing_686_block_end(void)
|
||||
void
|
||||
codegen_timing_686_block_end(void)
|
||||
{
|
||||
if (prev_full)
|
||||
{
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
|
||||
prev_full = 0;
|
||||
}
|
||||
if (prev_full) {
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
|
||||
prev_full = 0;
|
||||
}
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_686 =
|
||||
{
|
||||
codegen_timing_686_start,
|
||||
codegen_timing_686_prefix,
|
||||
codegen_timing_686_opcode,
|
||||
codegen_timing_686_block_start,
|
||||
codegen_timing_686_block_end,
|
||||
NULL
|
||||
codegen_timing_t codegen_timing_686 = {
|
||||
codegen_timing_686_start,
|
||||
codegen_timing_686_prefix,
|
||||
codegen_timing_686_opcode,
|
||||
codegen_timing_686_block_start,
|
||||
codegen_timing_686_block_end,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
uint64_t opcode_deps[256] =
|
||||
{
|
||||
uint64_t opcode_deps[256] = {
|
||||
// clang-format off
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
@@ -140,10 +140,11 @@ uint64_t opcode_deps[256] =
|
||||
0, 0, 0, 0,
|
||||
/* CLD STD INCDEC*/
|
||||
0, 0, MODRM, 0
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_mod3[256] =
|
||||
{
|
||||
uint64_t opcode_deps_mod3[256] = {
|
||||
// clang-format off
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
@@ -274,10 +275,11 @@ uint64_t opcode_deps_mod3[256] =
|
||||
0, 0, 0, 0,
|
||||
/* CLD STD INCDEC*/
|
||||
0, 0, SRCDEP_RM | DSTDEP_RM | MODRM, 0
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_0f[256] =
|
||||
{
|
||||
uint64_t opcode_deps_0f[256] = {
|
||||
// clang-format off
|
||||
/*00*/ MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
@@ -357,9 +359,10 @@ uint64_t opcode_deps_0f[256] =
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_0f_mod3[256] =
|
||||
{
|
||||
uint64_t opcode_deps_0f_mod3[256] = {
|
||||
// clang-format off
|
||||
/*00*/ MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
@@ -439,10 +442,11 @@ uint64_t opcode_deps_0f_mod3[256] =
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_0f0f[256] =
|
||||
{
|
||||
uint64_t opcode_deps_0f0f[256] = {
|
||||
// clang-format off
|
||||
/*00*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
@@ -522,9 +526,10 @@ uint64_t opcode_deps_0f0f[256] =
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_0f0f_mod3[256] =
|
||||
{
|
||||
uint64_t opcode_deps_0f0f_mod3[256] = {
|
||||
// clang-format off
|
||||
/*00*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
@@ -604,97 +609,111 @@ uint64_t opcode_deps_0f0f_mod3[256] =
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_shift[8] =
|
||||
{
|
||||
uint64_t opcode_deps_shift[8] = {
|
||||
// clang-format off
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_shift_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_shift_mod3[8] = {
|
||||
// clang-format off
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_shift_cl[8] =
|
||||
{
|
||||
uint64_t opcode_deps_shift_cl[8] = {
|
||||
// clang-format off
|
||||
MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX,
|
||||
MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX,
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_shift_cl_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_shift_cl_mod3[8] = {
|
||||
// clang-format off
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_f6[8] =
|
||||
{
|
||||
uint64_t opcode_deps_f6[8] = {
|
||||
// clang-format off
|
||||
/* TST NOT NEG*/
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_f6_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_f6_mod3[8] = {
|
||||
// clang-format off
|
||||
/* TST NOT NEG*/
|
||||
SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_f7[8] =
|
||||
{
|
||||
uint64_t opcode_deps_f7[8] = {
|
||||
// clang-format off
|
||||
/* TST NOT NEG*/
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_f7_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_f7_mod3[8] = {
|
||||
// clang-format off
|
||||
/* TST NOT NEG*/
|
||||
SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_ff[8] =
|
||||
{
|
||||
uint64_t opcode_deps_ff[8] = {
|
||||
// clang-format off
|
||||
/* INC DEC CALL CALL far*/
|
||||
MODRM, MODRM, MODRM | IMPL_ESP, MODRM,
|
||||
/* JMP JMP far PUSH*/
|
||||
MODRM, MODRM, MODRM | IMPL_ESP, 0
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_ff_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_ff_mod3[8] = {
|
||||
// clang-format off
|
||||
/* INC DEC CALL CALL far*/
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM | IMPL_ESP, MODRM,
|
||||
/* JMP JMP far PUSH*/
|
||||
SRCDEP_RM | MODRM, MODRM, SRCDEP_RM | MODRM | IMPL_ESP, 0
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_d8[8] =
|
||||
{
|
||||
uint64_t opcode_deps_d8[8] = {
|
||||
// clang-format off
|
||||
/* FADDs FMULs FCOMs FCOMPs*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_POP | FPU_READ_ST0 | MODRM,
|
||||
/* FSUBs FSUBRs FDIVs FDIVRs*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_d8_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_d8_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FADD FMUL FCOM FCOMP*/
|
||||
FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG, FPU_POP | FPU_READ_ST0 | FPU_READ_STREG,
|
||||
/* FSUB FSUBR FDIV FDIVR*/
|
||||
FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_d9[8] =
|
||||
{
|
||||
uint64_t opcode_deps_d9[8] = {
|
||||
// clang-format off
|
||||
/* FLDs FSTs FSTPs*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_POP | MODRM,
|
||||
/* FLDENV FLDCW FSTENV FSTCW*/
|
||||
MODRM, MODRM, MODRM, MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_d9_mod3[64] =
|
||||
{
|
||||
uint64_t opcode_deps_d9_mod3[64] = {
|
||||
// clang-format off
|
||||
/*FLD*/
|
||||
FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG,
|
||||
FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG,
|
||||
@@ -722,32 +741,35 @@ uint64_t opcode_deps_d9_mod3[64] =
|
||||
0, 0, 0, 0,
|
||||
/* opFRNDINT opFSCALE opFSIN opFCOS*/
|
||||
0, 0, 0, 0
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_da[8] =
|
||||
{
|
||||
uint64_t opcode_deps_da[8] = {
|
||||
// clang-format off
|
||||
/* FIADDl FIMULl FICOMl FICOMPl*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FISUBl FISUBRl FIDIVl FIDIVRl*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_da_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_da_mod3[8] = {
|
||||
// clang-format off
|
||||
0, 0, 0, 0,
|
||||
/* FCOMPP*/
|
||||
0, FPU_POP2, 0, 0
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
uint64_t opcode_deps_db[8] =
|
||||
{
|
||||
uint64_t opcode_deps_db[8] = {
|
||||
// clang-format off
|
||||
/* FLDil FSTil FSTPil*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FLDe FSTPe*/
|
||||
0, FPU_PUSH | MODRM, 0, FPU_READ_ST0 | FPU_POP | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_db_mod3[64] =
|
||||
{
|
||||
uint64_t opcode_deps_db_mod3[64] = {
|
||||
// clang-format off
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -767,84 +789,97 @@ uint64_t opcode_deps_db_mod3[64] =
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_dc[8] =
|
||||
{
|
||||
uint64_t opcode_deps_dc[8] = {
|
||||
// clang-format off
|
||||
/* FADDd FMULd FCOMd FCOMPd*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FSUBd FSUBRd FDIVd FDIVRd*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_dc_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_dc_mod3[8] = {
|
||||
// clang-format off
|
||||
/* opFADDr opFMULr*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, 0, 0,
|
||||
/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_dd[8] =
|
||||
{
|
||||
uint64_t opcode_deps_dd[8] = {
|
||||
// clang-format off
|
||||
/* FLDd FSTd FSTPd*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FRSTOR FSAVE FSTSW*/
|
||||
MODRM, 0, MODRM, MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_dd_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_dd_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FFFREE FST FSTP*/
|
||||
0, 0, FPU_READ_ST0 | FPU_WRITE_STREG, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP,
|
||||
/* FUCOM FUCOMP*/
|
||||
FPU_READ_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG | FPU_POP, 0, 0
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_de[8] =
|
||||
{
|
||||
uint64_t opcode_deps_de[8] = {
|
||||
// clang-format off
|
||||
/* FIADDw FIMULw FICOMw FICOMPw*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FISUBw FISUBRw FIDIVw FIDIVRw*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_de_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_de_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FADDP FMULP FCOMPP*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, 0, FPU_READ_ST0 | FPU_READ_ST1 | FPU_POP2,
|
||||
/* FSUBP FSUBRP FDIVP FDIVRP*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_df[8] =
|
||||
{
|
||||
uint64_t opcode_deps_df[8] = {
|
||||
// clang-format off
|
||||
/* FILDiw FISTiw FISTPiw*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FILDiq FBSTP FISTPiq*/
|
||||
0, FPU_PUSH | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, FPU_READ_ST0 | FPU_POP | MODRM
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_df_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_df_mod3[8] = {
|
||||
// clang-format off
|
||||
0, 0, 0, 0,
|
||||
/* FSTSW AX*/
|
||||
0, 0, 0, 0
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_81[8] =
|
||||
{
|
||||
uint64_t opcode_deps_81[8] = {
|
||||
// clang-format off
|
||||
MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632,
|
||||
MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_81_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_81_mod3[8] = {
|
||||
// clang-format off
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | MODRM | HAS_IMM1632
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_8x[8] =
|
||||
{
|
||||
uint64_t opcode_deps_8x[8] = {
|
||||
// clang-format off
|
||||
MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8,
|
||||
MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8
|
||||
// clang-format on
|
||||
};
|
||||
uint64_t opcode_deps_8x_mod3[8] =
|
||||
{
|
||||
uint64_t opcode_deps_8x_mod3[8] = {
|
||||
// clang-format off
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | MODRM | HAS_IMM8
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -1,79 +1,79 @@
|
||||
#include "codegen_ops.h"
|
||||
|
||||
/*Instruction has input dependency on register in REG field*/
|
||||
#define SRCDEP_REG (1ull << 0)
|
||||
#define SRCDEP_REG (1ULL << 0)
|
||||
/*Instruction has input dependency on register in R/M field*/
|
||||
#define SRCDEP_RM (1ull << 1)
|
||||
#define SRCDEP_RM (1ULL << 1)
|
||||
/*Instruction modifies register in REG field*/
|
||||
#define DSTDEP_REG (1ull << 2)
|
||||
#define DSTDEP_REG (1ULL << 2)
|
||||
/*Instruction modifies register in R/M field*/
|
||||
#define DSTDEP_RM (1ull << 3)
|
||||
#define DSTDEP_RM (1ULL << 3)
|
||||
|
||||
#define SRCDEP_SHIFT 4
|
||||
#define DSTDEP_SHIFT 12
|
||||
|
||||
/*Instruction has input dependency on given register*/
|
||||
#define SRCDEP_EAX (1ull << 4)
|
||||
#define SRCDEP_ECX (1ull << 5)
|
||||
#define SRCDEP_EDX (1ull << 6)
|
||||
#define SRCDEP_EBX (1ull << 7)
|
||||
#define SRCDEP_ESP (1ull << 8)
|
||||
#define SRCDEP_EBP (1ull << 9)
|
||||
#define SRCDEP_ESI (1ull << 10)
|
||||
#define SRCDEP_EDI (1ull << 11)
|
||||
#define SRCDEP_EAX (1ULL << 4)
|
||||
#define SRCDEP_ECX (1ULL << 5)
|
||||
#define SRCDEP_EDX (1ULL << 6)
|
||||
#define SRCDEP_EBX (1ULL << 7)
|
||||
#define SRCDEP_ESP (1ULL << 8)
|
||||
#define SRCDEP_EBP (1ULL << 9)
|
||||
#define SRCDEP_ESI (1ULL << 10)
|
||||
#define SRCDEP_EDI (1ULL << 11)
|
||||
|
||||
/*Instruction modifies given register*/
|
||||
#define DSTDEP_EAX (1ull << 12)
|
||||
#define DSTDEP_ECX (1ull << 13)
|
||||
#define DSTDEP_EDX (1ull << 14)
|
||||
#define DSTDEP_EBX (1ull << 15)
|
||||
#define DSTDEP_ESP (1ull << 16)
|
||||
#define DSTDEP_EBP (1ull << 17)
|
||||
#define DSTDEP_ESI (1ull << 18)
|
||||
#define DSTDEP_EDI (1ull << 19)
|
||||
#define DSTDEP_EAX (1ULL << 12)
|
||||
#define DSTDEP_ECX (1ULL << 13)
|
||||
#define DSTDEP_EDX (1ULL << 14)
|
||||
#define DSTDEP_EBX (1ULL << 15)
|
||||
#define DSTDEP_ESP (1ULL << 16)
|
||||
#define DSTDEP_EBP (1ULL << 17)
|
||||
#define DSTDEP_ESI (1ULL << 18)
|
||||
#define DSTDEP_EDI (1ULL << 19)
|
||||
|
||||
/*Instruction has ModR/M byte*/
|
||||
#define MODRM (1ull << 20)
|
||||
#define MODRM (1ULL << 20)
|
||||
/*Instruction implicitly uses ESP*/
|
||||
#define IMPL_ESP (1ull << 21)
|
||||
#define IMPL_ESP (1ULL << 21)
|
||||
|
||||
/*Instruction is MMX shift or pack/unpack instruction*/
|
||||
#define MMX_SHIFTPACK (1ull << 22)
|
||||
#define MMX_SHIFTPACK (1ULL << 22)
|
||||
/*Instruction is MMX multiply instruction*/
|
||||
#define MMX_MULTIPLY (1ull << 23)
|
||||
#define MMX_MULTIPLY (1ULL << 23)
|
||||
|
||||
/*Instruction pops the FPU stack*/
|
||||
#define FPU_POP (1ull << 24)
|
||||
#define FPU_POP (1ULL << 24)
|
||||
/*Instruction pops the FPU stack twice*/
|
||||
#define FPU_POP2 (1ull << 25)
|
||||
#define FPU_POP2 (1ULL << 25)
|
||||
/*Instruction pushes onto the FPU stack*/
|
||||
#define FPU_PUSH (1ull << 26)
|
||||
#define FPU_PUSH (1ULL << 26)
|
||||
|
||||
/*Instruction writes to ST(0)*/
|
||||
#define FPU_WRITE_ST0 (1ull << 27)
|
||||
#define FPU_WRITE_ST0 (1ULL << 27)
|
||||
/*Instruction reads from ST(0)*/
|
||||
#define FPU_READ_ST0 (1ull << 28)
|
||||
#define FPU_READ_ST0 (1ULL << 28)
|
||||
/*Instruction reads from and writes to ST(0)*/
|
||||
#define FPU_RW_ST0 (3ull << 27)
|
||||
#define FPU_RW_ST0 (3ULL << 27)
|
||||
|
||||
/*Instruction reads from ST(1)*/
|
||||
#define FPU_READ_ST1 (1ull << 29)
|
||||
#define FPU_READ_ST1 (1ULL << 29)
|
||||
/*Instruction writes to ST(1)*/
|
||||
#define FPU_WRITE_ST1 (1ull << 30)
|
||||
#define FPU_WRITE_ST1 (1ULL << 30)
|
||||
/*Instruction reads from and writes to ST(1)*/
|
||||
#define FPU_RW_ST1 (3ull << 29)
|
||||
#define FPU_RW_ST1 (3ULL << 29)
|
||||
|
||||
/*Instruction reads from ST(reg)*/
|
||||
#define FPU_READ_STREG (1ull << 31)
|
||||
#define FPU_READ_STREG (1ULL << 31)
|
||||
/*Instruction writes to ST(reg)*/
|
||||
#define FPU_WRITE_STREG (1ull << 32)
|
||||
#define FPU_WRITE_STREG (1ULL << 32)
|
||||
/*Instruction reads from and writes to ST(reg)*/
|
||||
#define FPU_RW_STREG (3ull << 31)
|
||||
#define FPU_RW_STREG (3ULL << 31)
|
||||
|
||||
#define FPU_FXCH (1ull << 33)
|
||||
#define FPU_FXCH (1ULL << 33)
|
||||
|
||||
#define HAS_IMM8 (1ull << 34)
|
||||
#define HAS_IMM1632 (1ull << 35)
|
||||
#define HAS_IMM8 (1ULL << 34)
|
||||
#define HAS_IMM1632 (1ULL << 35)
|
||||
|
||||
#define REGMASK_IMPL_ESP (1 << 8)
|
||||
#define REGMASK_SHIFTPACK (1 << 9)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,19 +4,21 @@
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include <86box/mem.h>
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
#define CYCLES(c) (int *)c
|
||||
#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8))
|
||||
#define CYCLES(c) (int *) c
|
||||
#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8))
|
||||
|
||||
static int *opcode_timings[256] =
|
||||
{
|
||||
static int *opcode_timings[256] = {
|
||||
// clang-format off
|
||||
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
|
||||
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
|
||||
/*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
|
||||
@@ -36,10 +38,11 @@ static int *opcode_timings[256] =
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_mod3[256] =
|
||||
{
|
||||
static int *opcode_timings_mod3[256] = {
|
||||
// clang-format off
|
||||
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
|
||||
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
|
||||
/*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3),
|
||||
@@ -59,10 +62,11 @@ static int *opcode_timings_mod3[256] =
|
||||
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
|
||||
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_0f[256] =
|
||||
{
|
||||
static int *opcode_timings_0f[256] = {
|
||||
// clang-format off
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -82,9 +86,10 @@ static int *opcode_timings_0f[256] =
|
||||
/*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_0f_mod3[256] =
|
||||
{
|
||||
static int *opcode_timings_0f_mod3[256] = {
|
||||
// clang-format off
|
||||
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -104,60 +109,72 @@ static int *opcode_timings_0f_mod3[256] =
|
||||
/*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_shift[8] =
|
||||
{
|
||||
static int *opcode_timings_shift[8] = {
|
||||
// clang-format off
|
||||
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_shift_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_shift_mod3[8] = {
|
||||
// clang-format off
|
||||
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_f6[8] =
|
||||
{
|
||||
static int *opcode_timings_f6[8] = {
|
||||
// clang-format off
|
||||
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_f6_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_f6_mod3[8] = {
|
||||
// clang-format off
|
||||
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_f7[8] =
|
||||
{
|
||||
static int *opcode_timings_f7[8] = {
|
||||
// clang-format off
|
||||
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_f7_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_f7_mod3[8] = {
|
||||
// clang-format off
|
||||
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_ff[8] =
|
||||
{
|
||||
static int *opcode_timings_ff[8] = {
|
||||
// clang-format off
|
||||
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_ff_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_ff_mod3[8] = {
|
||||
// clang-format off
|
||||
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_d8[8] =
|
||||
{
|
||||
static int *opcode_timings_d8[8] = {
|
||||
// clang-format off
|
||||
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_d8_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_d8_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
|
||||
CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_d9[8] =
|
||||
{
|
||||
static int *opcode_timings_d9[8] = {
|
||||
// clang-format off
|
||||
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
|
||||
CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_d9_mod3[64] =
|
||||
{
|
||||
static int *opcode_timings_d9_mod3[64] = {
|
||||
// clang-format off
|
||||
/*FLD*/
|
||||
CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*FXCH*/
|
||||
@@ -174,26 +191,29 @@ static int *opcode_timings_d9_mod3[64] =
|
||||
CYCLES(300), CYCLES(58), CYCLES(676), CYCLES(355), NULL, NULL, CYCLES(3), CYCLES(3),
|
||||
/* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/
|
||||
CYCLES(70), NULL, CYCLES(72), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(474), CYCLES(474)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_da[8] =
|
||||
{
|
||||
static int *opcode_timings_da[8] = {
|
||||
// clang-format off
|
||||
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_da_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_da_mod3[8] = {
|
||||
// clang-format off
|
||||
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
static int *opcode_timings_db[8] =
|
||||
{
|
||||
static int *opcode_timings_db[8] = {
|
||||
// clang-format off
|
||||
/* FLDil FSTil FSTPil FLDe FSTPe*/
|
||||
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_db_mod3[64] =
|
||||
{
|
||||
static int *opcode_timings_db_mod3[64] = {
|
||||
// clang-format off
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -203,54 +223,63 @@ static int *opcode_timings_db_mod3[64] =
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_dc[8] =
|
||||
{
|
||||
static int *opcode_timings_dc[8] = {
|
||||
// clang-format off
|
||||
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
|
||||
CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_dc_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_dc_mod3[8] = {
|
||||
// clang-format off
|
||||
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
|
||||
CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_dd[8] =
|
||||
{
|
||||
static int *opcode_timings_dd[8] = {
|
||||
// clang-format off
|
||||
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
|
||||
CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_dd_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_dd_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FFFREE FST FSTP FUCOM FUCOMP*/
|
||||
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_de[8] =
|
||||
{
|
||||
static int *opcode_timings_de[8] = {
|
||||
// clang-format off
|
||||
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
|
||||
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_de_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_de_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
|
||||
CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_df[8] =
|
||||
{
|
||||
static int *opcode_timings_df[8] = {
|
||||
// clang-format off
|
||||
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
|
||||
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8)
|
||||
// clang-format on
|
||||
};
|
||||
static int *opcode_timings_df_mod3[8] =
|
||||
{
|
||||
static int *opcode_timings_df_mod3[8] = {
|
||||
// clang-format off
|
||||
/* FFREE FST FSTP FUCOM FUCOMP*/
|
||||
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int *opcode_timings_8x[8] =
|
||||
{
|
||||
static int *opcode_timings_8x[8] = {
|
||||
// clang-format off
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_8x_mod3[8] =
|
||||
@@ -264,158 +293,169 @@ static int *opcode_timings_81[8] =
|
||||
static int *opcode_timings_81_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static uint32_t regmask_modified;
|
||||
|
||||
static inline int COUNT(int *c, int op_32)
|
||||
static inline int
|
||||
COUNT(int *c, int op_32)
|
||||
{
|
||||
if ((uintptr_t)c <= 10000)
|
||||
return (int)(uintptr_t)c;
|
||||
if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff))
|
||||
{
|
||||
if (op_32 & 0x100)
|
||||
return ((uintptr_t)c >> 8) & 0xff;
|
||||
return (uintptr_t)c & 0xff;
|
||||
}
|
||||
return *c;
|
||||
if ((uintptr_t) c <= 10000)
|
||||
return (int) (uintptr_t) c;
|
||||
if (((uintptr_t) c & ~0xffff) == (-1 & ~0xffff)) {
|
||||
if (op_32 & 0x100)
|
||||
return ((uintptr_t) c >> 8) & 0xff;
|
||||
return (uintptr_t) c & 0xff;
|
||||
}
|
||||
return *c;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_block_start(void)
|
||||
void
|
||||
codegen_timing_winchip_block_start(void)
|
||||
{
|
||||
regmask_modified = 0;
|
||||
regmask_modified = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_start(void)
|
||||
void
|
||||
codegen_timing_winchip_start(void)
|
||||
{
|
||||
timing_count = 0;
|
||||
last_prefix = 0;
|
||||
timing_count = 0;
|
||||
last_prefix = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
void
|
||||
codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
{
|
||||
timing_count += COUNT(opcode_timings[prefix], 0);
|
||||
last_prefix = prefix;
|
||||
timing_count += COUNT(opcode_timings[prefix], 0);
|
||||
last_prefix = prefix;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)
|
||||
void
|
||||
codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc))
|
||||
{
|
||||
int **timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
int **timings;
|
||||
const uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
|
||||
switch (last_prefix)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
switch (last_prefix) {
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode) {
|
||||
case 0x80:
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0:
|
||||
case 0xc1:
|
||||
case 0xd0:
|
||||
case 0xd1:
|
||||
case 0xd2:
|
||||
case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
timing_count += COUNT(timings[opcode], op_32);
|
||||
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
|
||||
timing_count++; /*AGI stall*/
|
||||
codegen_block_cycles += timing_count;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timing_count += COUNT(timings[opcode], op_32);
|
||||
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
|
||||
timing_count++; /*AGI stall*/
|
||||
codegen_block_cycles += timing_count;
|
||||
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_block_end(void)
|
||||
void
|
||||
codegen_timing_winchip_block_end(void)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_winchip =
|
||||
{
|
||||
codegen_timing_winchip_start,
|
||||
codegen_timing_winchip_prefix,
|
||||
codegen_timing_winchip_opcode,
|
||||
codegen_timing_winchip_block_start,
|
||||
codegen_timing_winchip_block_end,
|
||||
NULL
|
||||
codegen_timing_t codegen_timing_winchip = {
|
||||
codegen_timing_winchip_start,
|
||||
codegen_timing_winchip_prefix,
|
||||
codegen_timing_winchip_opcode,
|
||||
codegen_timing_winchip_block_start,
|
||||
codegen_timing_winchip_block_end,
|
||||
NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
209
src/cpu/cpu.c
209
src/cpu/cpu.c
@@ -18,6 +18,7 @@
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2018-2021 Fred N. van Kempen.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@@ -37,6 +38,9 @@
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/gdbstub.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
# include "codegen.h"
|
||||
#endif
|
||||
@@ -125,6 +129,27 @@ const OpFn *x86_opcodes_REPE;
|
||||
const OpFn *x86_opcodes_REPNE;
|
||||
const OpFn *x86_opcodes_3DNOW;
|
||||
|
||||
const OpFn *x86_2386_opcodes;
|
||||
const OpFn *x86_2386_opcodes_0f;
|
||||
const OpFn *x86_2386_opcodes_d8_a16;
|
||||
const OpFn *x86_2386_opcodes_d8_a32;
|
||||
const OpFn *x86_2386_opcodes_d9_a16;
|
||||
const OpFn *x86_2386_opcodes_d9_a32;
|
||||
const OpFn *x86_2386_opcodes_da_a16;
|
||||
const OpFn *x86_2386_opcodes_da_a32;
|
||||
const OpFn *x86_2386_opcodes_db_a16;
|
||||
const OpFn *x86_2386_opcodes_db_a32;
|
||||
const OpFn *x86_2386_opcodes_dc_a16;
|
||||
const OpFn *x86_2386_opcodes_dc_a32;
|
||||
const OpFn *x86_2386_opcodes_dd_a16;
|
||||
const OpFn *x86_2386_opcodes_dd_a32;
|
||||
const OpFn *x86_2386_opcodes_de_a16;
|
||||
const OpFn *x86_2386_opcodes_de_a32;
|
||||
const OpFn *x86_2386_opcodes_df_a16;
|
||||
const OpFn *x86_2386_opcodes_df_a32;
|
||||
const OpFn *x86_2386_opcodes_REPE;
|
||||
const OpFn *x86_2386_opcodes_REPNE;
|
||||
|
||||
uint16_t cpu_fast_off_count;
|
||||
uint16_t cpu_fast_off_val;
|
||||
uint16_t temp_seg_data[4] = { 0, 0, 0, 0 };
|
||||
@@ -216,7 +241,7 @@ uint32_t cache_index = 0;
|
||||
uint8_t _cache[2048];
|
||||
|
||||
uint64_t cpu_CR4_mask;
|
||||
uint64_t tsc = 0;
|
||||
uint64_t tsc = 0;
|
||||
uint64_t pmc[2] = { 0, 0 };
|
||||
|
||||
double cpu_dmulti;
|
||||
@@ -229,7 +254,7 @@ cyrix_t cyrix;
|
||||
cpu_family_t *cpu_f;
|
||||
CPU *cpu_s;
|
||||
|
||||
uint8_t do_translate = 0;
|
||||
uint8_t do_translate = 0;
|
||||
uint8_t do_translate2 = 0;
|
||||
|
||||
void (*cpu_exec)(int cycs);
|
||||
@@ -455,7 +480,7 @@ SF_FPU_reset(void)
|
||||
fpu_state.fcs = 0;
|
||||
fpu_state.fds = 0;
|
||||
fpu_state.fdp = 0;
|
||||
memset(fpu_state.st_space, 0, sizeof(floatx80)*8);
|
||||
memset(fpu_state.st_space, 0, sizeof(floatx80) * 8);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,9 +566,12 @@ cpu_set(void)
|
||||
#else
|
||||
x86_setopcodes(ops_386, ops_386_0f);
|
||||
#endif
|
||||
x86_opcodes_REPE = ops_REPE;
|
||||
x86_opcodes_REPNE = ops_REPNE;
|
||||
x86_opcodes_3DNOW = ops_3DNOW;
|
||||
x86_setopcodes_2386(ops_2386_386, ops_2386_386_0f);
|
||||
x86_opcodes_REPE = ops_REPE;
|
||||
x86_opcodes_REPNE = ops_REPNE;
|
||||
x86_2386_opcodes_REPE = ops_2386_REPE;
|
||||
x86_2386_opcodes_REPNE = ops_2386_REPNE;
|
||||
x86_opcodes_3DNOW = ops_3DNOW;
|
||||
#ifdef USE_DYNAREC
|
||||
x86_dynarec_opcodes_REPE = dynarec_ops_REPE;
|
||||
x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE;
|
||||
@@ -605,6 +633,23 @@ cpu_set(void)
|
||||
x86_opcodes_de_a32 = ops_sf_fpu_de_a32;
|
||||
x86_opcodes_df_a16 = ops_sf_fpu_df_a16;
|
||||
x86_opcodes_df_a32 = ops_sf_fpu_df_a32;
|
||||
|
||||
x86_2386_opcodes_d8_a16 = ops_2386_sf_fpu_d8_a16;
|
||||
x86_2386_opcodes_d8_a32 = ops_2386_sf_fpu_d8_a32;
|
||||
x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_d9_a16;
|
||||
x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_d9_a32;
|
||||
x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_da_a16;
|
||||
x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_da_a32;
|
||||
x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_db_a16;
|
||||
x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_db_a32;
|
||||
x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_dc_a16;
|
||||
x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_dc_a32;
|
||||
x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_dd_a16;
|
||||
x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_dd_a32;
|
||||
x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_de_a16;
|
||||
x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_de_a32;
|
||||
x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_df_a16;
|
||||
x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_df_a32;
|
||||
} else {
|
||||
x86_opcodes_d8_a16 = ops_fpu_d8_a16;
|
||||
x86_opcodes_d8_a32 = ops_fpu_d8_a32;
|
||||
@@ -622,6 +667,23 @@ cpu_set(void)
|
||||
x86_opcodes_de_a32 = ops_fpu_de_a32;
|
||||
x86_opcodes_df_a16 = ops_fpu_df_a16;
|
||||
x86_opcodes_df_a32 = ops_fpu_df_a32;
|
||||
|
||||
x86_2386_opcodes_d8_a16 = ops_2386_fpu_d8_a16;
|
||||
x86_2386_opcodes_d8_a32 = ops_2386_fpu_d8_a32;
|
||||
x86_2386_opcodes_d9_a16 = ops_2386_fpu_d9_a16;
|
||||
x86_2386_opcodes_d9_a32 = ops_2386_fpu_d9_a32;
|
||||
x86_2386_opcodes_da_a16 = ops_2386_fpu_da_a16;
|
||||
x86_2386_opcodes_da_a32 = ops_2386_fpu_da_a32;
|
||||
x86_2386_opcodes_db_a16 = ops_2386_fpu_db_a16;
|
||||
x86_2386_opcodes_db_a32 = ops_2386_fpu_db_a32;
|
||||
x86_2386_opcodes_dc_a16 = ops_2386_fpu_dc_a16;
|
||||
x86_2386_opcodes_dc_a32 = ops_2386_fpu_dc_a32;
|
||||
x86_2386_opcodes_dd_a16 = ops_2386_fpu_dd_a16;
|
||||
x86_2386_opcodes_dd_a32 = ops_2386_fpu_dd_a32;
|
||||
x86_2386_opcodes_de_a16 = ops_2386_fpu_de_a16;
|
||||
x86_2386_opcodes_de_a32 = ops_2386_fpu_de_a32;
|
||||
x86_2386_opcodes_df_a16 = ops_2386_fpu_df_a16;
|
||||
x86_2386_opcodes_df_a32 = ops_2386_fpu_df_a32;
|
||||
}
|
||||
} else {
|
||||
#ifdef USE_DYNAREC
|
||||
@@ -658,6 +720,23 @@ cpu_set(void)
|
||||
x86_opcodes_de_a32 = ops_nofpu_a32;
|
||||
x86_opcodes_df_a16 = ops_nofpu_a16;
|
||||
x86_opcodes_df_a32 = ops_nofpu_a32;
|
||||
|
||||
x86_2386_opcodes_d8_a16 = ops_2386_nofpu_a16;
|
||||
x86_2386_opcodes_d8_a32 = ops_2386_nofpu_a32;
|
||||
x86_2386_opcodes_d9_a16 = ops_2386_nofpu_a16;
|
||||
x86_2386_opcodes_d9_a32 = ops_2386_nofpu_a32;
|
||||
x86_2386_opcodes_da_a16 = ops_2386_nofpu_a16;
|
||||
x86_2386_opcodes_da_a32 = ops_2386_nofpu_a32;
|
||||
x86_2386_opcodes_db_a16 = ops_2386_nofpu_a16;
|
||||
x86_2386_opcodes_db_a32 = ops_2386_nofpu_a32;
|
||||
x86_2386_opcodes_dc_a16 = ops_2386_nofpu_a16;
|
||||
x86_2386_opcodes_dc_a32 = ops_2386_nofpu_a32;
|
||||
x86_2386_opcodes_dd_a16 = ops_2386_nofpu_a16;
|
||||
x86_2386_opcodes_dd_a32 = ops_2386_nofpu_a32;
|
||||
x86_2386_opcodes_de_a16 = ops_2386_nofpu_a16;
|
||||
x86_2386_opcodes_de_a32 = ops_2386_nofpu_a32;
|
||||
x86_2386_opcodes_df_a16 = ops_2386_nofpu_a16;
|
||||
x86_2386_opcodes_df_a32 = ops_2386_nofpu_a32;
|
||||
}
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
@@ -684,6 +763,7 @@ cpu_set(void)
|
||||
#else
|
||||
x86_setopcodes(ops_186, ops_186_0f);
|
||||
#endif
|
||||
x86_setopcodes_2386(ops_2386_186, ops_2386_186_0f);
|
||||
break;
|
||||
|
||||
case CPU_286:
|
||||
@@ -692,6 +772,7 @@ cpu_set(void)
|
||||
#else
|
||||
x86_setopcodes(ops_286, ops_286_0f);
|
||||
#endif
|
||||
x86_setopcodes_2386(ops_2386_286, ops_2386_286_0f);
|
||||
|
||||
if (fpu_type == FPU_287) {
|
||||
#ifdef USE_DYNAREC
|
||||
@@ -742,6 +823,21 @@ cpu_set(void)
|
||||
x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32;
|
||||
x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16;
|
||||
x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32;
|
||||
|
||||
x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_287_d9_a16;
|
||||
x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_287_d9_a32;
|
||||
x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_287_da_a16;
|
||||
x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_287_da_a32;
|
||||
x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_287_db_a16;
|
||||
x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_287_db_a32;
|
||||
x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_287_dc_a16;
|
||||
x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_287_dc_a32;
|
||||
x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_287_dd_a16;
|
||||
x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_287_dd_a32;
|
||||
x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_287_de_a16;
|
||||
x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_287_de_a32;
|
||||
x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_287_df_a16;
|
||||
x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_287_df_a32;
|
||||
} else {
|
||||
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
|
||||
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
|
||||
@@ -757,6 +853,21 @@ cpu_set(void)
|
||||
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
|
||||
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
|
||||
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
|
||||
|
||||
x86_2386_opcodes_d9_a16 = ops_2386_fpu_287_d9_a16;
|
||||
x86_2386_opcodes_d9_a32 = ops_2386_fpu_287_d9_a32;
|
||||
x86_2386_opcodes_da_a16 = ops_2386_fpu_287_da_a16;
|
||||
x86_2386_opcodes_da_a32 = ops_2386_fpu_287_da_a32;
|
||||
x86_2386_opcodes_db_a16 = ops_2386_fpu_287_db_a16;
|
||||
x86_2386_opcodes_db_a32 = ops_2386_fpu_287_db_a32;
|
||||
x86_2386_opcodes_dc_a16 = ops_2386_fpu_287_dc_a16;
|
||||
x86_2386_opcodes_dc_a32 = ops_2386_fpu_287_dc_a32;
|
||||
x86_2386_opcodes_dd_a16 = ops_2386_fpu_287_dd_a16;
|
||||
x86_2386_opcodes_dd_a32 = ops_2386_fpu_287_dd_a32;
|
||||
x86_2386_opcodes_de_a16 = ops_2386_fpu_287_de_a16;
|
||||
x86_2386_opcodes_de_a32 = ops_2386_fpu_287_de_a32;
|
||||
x86_2386_opcodes_df_a16 = ops_2386_fpu_287_df_a16;
|
||||
x86_2386_opcodes_df_a32 = ops_2386_fpu_287_df_a32;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -799,11 +910,13 @@ cpu_set(void)
|
||||
#else
|
||||
x86_setopcodes(ops_386, ops_ibm486_0f);
|
||||
#endif
|
||||
x86_setopcodes_2386(ops_2386_386, ops_2386_ibm486_0f);
|
||||
cpu_features = CPU_FEATURE_MSR;
|
||||
/* FALLTHROUGH */
|
||||
fallthrough;
|
||||
case CPU_386SX:
|
||||
case CPU_386DX:
|
||||
if (fpu_type == FPU_287) { /* In case we get Deskpro 386 emulation */
|
||||
/* In case we get Deskpro 386 emulation */
|
||||
if (fpu_type == FPU_287) {
|
||||
#ifdef USE_DYNAREC
|
||||
if (fpu_softfloat) {
|
||||
x86_dynarec_opcodes_d9_a16 = dynarec_ops_sf_fpu_287_d9_a16;
|
||||
@@ -852,6 +965,21 @@ cpu_set(void)
|
||||
x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32;
|
||||
x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16;
|
||||
x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32;
|
||||
|
||||
x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_287_d9_a16;
|
||||
x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_287_d9_a32;
|
||||
x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_287_da_a16;
|
||||
x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_287_da_a32;
|
||||
x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_287_db_a16;
|
||||
x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_287_db_a32;
|
||||
x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_287_dc_a16;
|
||||
x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_287_dc_a32;
|
||||
x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_287_dd_a16;
|
||||
x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_287_dd_a32;
|
||||
x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_287_de_a16;
|
||||
x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_287_de_a32;
|
||||
x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_287_df_a16;
|
||||
x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_287_df_a32;
|
||||
} else {
|
||||
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
|
||||
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
|
||||
@@ -867,6 +995,21 @@ cpu_set(void)
|
||||
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
|
||||
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
|
||||
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
|
||||
|
||||
x86_2386_opcodes_d9_a16 = ops_2386_fpu_287_d9_a16;
|
||||
x86_2386_opcodes_d9_a32 = ops_2386_fpu_287_d9_a32;
|
||||
x86_2386_opcodes_da_a16 = ops_2386_fpu_287_da_a16;
|
||||
x86_2386_opcodes_da_a32 = ops_2386_fpu_287_da_a32;
|
||||
x86_2386_opcodes_db_a16 = ops_2386_fpu_287_db_a16;
|
||||
x86_2386_opcodes_db_a32 = ops_2386_fpu_287_db_a32;
|
||||
x86_2386_opcodes_dc_a16 = ops_2386_fpu_287_dc_a16;
|
||||
x86_2386_opcodes_dc_a32 = ops_2386_fpu_287_dc_a32;
|
||||
x86_2386_opcodes_dd_a16 = ops_2386_fpu_287_dd_a16;
|
||||
x86_2386_opcodes_dd_a32 = ops_2386_fpu_287_dd_a32;
|
||||
x86_2386_opcodes_de_a16 = ops_2386_fpu_287_de_a16;
|
||||
x86_2386_opcodes_de_a32 = ops_2386_fpu_287_de_a32;
|
||||
x86_2386_opcodes_df_a16 = ops_2386_fpu_287_df_a16;
|
||||
x86_2386_opcodes_df_a32 = ops_2386_fpu_287_df_a32;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -913,6 +1056,7 @@ cpu_set(void)
|
||||
#else
|
||||
x86_setopcodes(ops_386, ops_486_0f);
|
||||
#endif
|
||||
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
|
||||
|
||||
timing_rr = 1; /* register dest - register src */
|
||||
timing_rm = 3; /* register dest - memory src */
|
||||
@@ -952,6 +1096,7 @@ cpu_set(void)
|
||||
#else
|
||||
x86_setopcodes(ops_386, ops_486_0f);
|
||||
#endif
|
||||
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
|
||||
|
||||
timing_rr = 1; /* register dest - register src */
|
||||
timing_rm = 3; /* register dest - memory src */
|
||||
@@ -990,7 +1135,7 @@ cpu_set(void)
|
||||
case CPU_i486DX_SLENH:
|
||||
cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME;
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME;
|
||||
/* FALLTHROUGH */
|
||||
fallthrough;
|
||||
case CPU_RAPIDCAD:
|
||||
case CPU_i486SX:
|
||||
case CPU_i486DX:
|
||||
@@ -1004,6 +1149,7 @@ cpu_set(void)
|
||||
#else
|
||||
x86_setopcodes(ops_386, ops_486_0f);
|
||||
#endif
|
||||
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
|
||||
|
||||
timing_rr = 1; /* register dest - register src */
|
||||
timing_rm = 2; /* register dest - memory src */
|
||||
@@ -1302,7 +1448,9 @@ cpu_set(void)
|
||||
x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
|
||||
else
|
||||
x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f);
|
||||
// x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f);
|
||||
# if 0
|
||||
x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f);
|
||||
# endif
|
||||
# else
|
||||
if (cpu_s->cpu_type == CPU_Cx6x86MX)
|
||||
x86_setopcodes(ops_386, ops_c6x86mx_0f);
|
||||
@@ -1310,7 +1458,9 @@ cpu_set(void)
|
||||
x86_setopcodes(ops_386, ops_pentium_0f);
|
||||
else
|
||||
x86_setopcodes(ops_386, ops_c6x86mx_0f);
|
||||
// x86_setopcodes(ops_386, ops_c6x86_0f);
|
||||
# if 0
|
||||
x86_setopcodes(ops_386, ops_c6x86_0f);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
timing_rr = 1; /* register dest - register src */
|
||||
@@ -1615,7 +1765,7 @@ cpu_set(void)
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("cpu_set : unknown CPU type %llu\n", cpu_s->cpu_type);
|
||||
fatal("cpu_set : unknown CPU type %" PRIu64 "\n", cpu_s->cpu_type);
|
||||
}
|
||||
|
||||
switch (fpu_type) {
|
||||
@@ -1647,9 +1797,13 @@ cpu_set(void)
|
||||
cpu_exec = exec386_dynarec;
|
||||
else
|
||||
#endif
|
||||
cpu_exec = exec386;
|
||||
/* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */
|
||||
if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type > CPU_486DLC))
|
||||
cpu_exec = exec386;
|
||||
else
|
||||
cpu_exec = exec386_2386;
|
||||
} else if (cpu_s->cpu_type >= CPU_286)
|
||||
cpu_exec = exec386;
|
||||
cpu_exec = exec386_2386;
|
||||
else
|
||||
cpu_exec = execx86;
|
||||
mmx_init();
|
||||
@@ -2324,7 +2478,7 @@ cpu_ven_reset(void)
|
||||
case CPU_K6_3:
|
||||
case CPU_K6_2C:
|
||||
msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL;
|
||||
/* FALLTHROUGH */
|
||||
fallthrough;
|
||||
case CPU_K6_2:
|
||||
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
|
||||
case CPU_K5:
|
||||
@@ -2338,7 +2492,6 @@ cpu_ven_reset(void)
|
||||
case CPU_PENTIUM2:
|
||||
case CPU_PENTIUM2D:
|
||||
msr.mtrr_cap = 0x00000508ULL;
|
||||
/* FALLTHROUGH */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2741,6 +2894,10 @@ amd_k_invalid_rdmsr:
|
||||
EAX = msr.ecx187 & 0xffffffff;
|
||||
EDX = msr.ecx187 >> 32;
|
||||
break;
|
||||
case 0x1d9:
|
||||
EAX = msr.debug_ctl & 0xffffffff;
|
||||
EDX = msr.debug_ctl >> 32;
|
||||
break;
|
||||
case 0x1e0:
|
||||
EAX = msr.ecx1e0 & 0xffffffff;
|
||||
EDX = msr.ecx1e0 >> 32;
|
||||
@@ -3121,7 +3278,9 @@ amd_k_invalid_wrmsr:
|
||||
break;
|
||||
case 0x1b:
|
||||
cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX);
|
||||
// msr.apic_base = EAX | ((uint64_t) EDX << 32);
|
||||
#if 0
|
||||
msr.apic_base = EAX | ((uint64_t) EDX << 32);
|
||||
#endif
|
||||
break;
|
||||
case 0x2a:
|
||||
break;
|
||||
@@ -3192,6 +3351,9 @@ amd_k_invalid_wrmsr:
|
||||
case 0x187:
|
||||
msr.ecx187 = EAX | ((uint64_t) EDX << 32);
|
||||
break;
|
||||
case 0x1d9:
|
||||
msr.debug_ctl = EAX | ((uint64_t) EDX << 32);
|
||||
break;
|
||||
case 0x1e0:
|
||||
msr.ecx1e0 = EAX | ((uint64_t) EDX << 32);
|
||||
break;
|
||||
@@ -3300,7 +3462,7 @@ i686_invalid_wrmsr:
|
||||
}
|
||||
|
||||
static void
|
||||
cpu_write(uint16_t addr, uint8_t val, void *priv)
|
||||
cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
|
||||
{
|
||||
if (addr == 0xf0) {
|
||||
/* Writes to F0 clear FPU error and deassert the interrupt. */
|
||||
@@ -3382,7 +3544,7 @@ cpu_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
cpu_read(uint16_t addr, void *priv)
|
||||
cpu_read(uint16_t addr, UNUSED(void *priv))
|
||||
{
|
||||
if (addr == 0xf007)
|
||||
return 0x7f;
|
||||
@@ -3438,11 +3600,18 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
|
||||
#else
|
||||
x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f)
|
||||
{
|
||||
x86_opcodes = opcodes;
|
||||
x86_opcodes = opcodes;
|
||||
x86_opcodes_0f = opcodes_0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f)
|
||||
{
|
||||
x86_2386_opcodes = opcodes;
|
||||
x86_2386_opcodes_0f = opcodes_0f;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_update_waitstates(void)
|
||||
{
|
||||
|
||||
@@ -280,11 +280,12 @@ typedef struct {
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */
|
||||
uint64_t ecx186; /* 0x00000186, 0x00000187 */
|
||||
uint64_t ecx187; /* 0x00000186, 0x00000187 */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t ecx186; /* 0x00000186, 0x00000187 */
|
||||
uint64_t ecx187; /* 0x00000186, 0x00000187 */
|
||||
uint64_t ecx1e0; /* 0x000001e0 */
|
||||
uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */
|
||||
uint64_t ecx1e0; /* 0x000001e0 */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also
|
||||
on the VIA Cyrix III */
|
||||
@@ -393,8 +394,13 @@ typedef struct {
|
||||
MMX_REG MM[8];
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# if defined(__APPLE__) && defined(__aarch64__)
|
||||
uint64_t old_fp_control;
|
||||
uint64_t new_fp_control;
|
||||
# else
|
||||
uint32_t old_fp_control;
|
||||
uint32_t new_fp_control;
|
||||
# endif
|
||||
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
|
||||
uint16_t old_fp_control2;
|
||||
uint16_t new_fp_control2;
|
||||
@@ -426,15 +432,15 @@ typedef struct {
|
||||
} cpu_state_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t cwd;
|
||||
uint16_t swd;
|
||||
uint16_t tag;
|
||||
uint16_t foo;
|
||||
uint32_t fip;
|
||||
uint32_t fdp;
|
||||
uint16_t fcs;
|
||||
uint16_t fds;
|
||||
floatx80 st_space[8];
|
||||
uint16_t cwd;
|
||||
uint16_t swd;
|
||||
uint16_t tag;
|
||||
uint16_t foo;
|
||||
uint32_t fip;
|
||||
uint32_t fdp;
|
||||
uint16_t fcs;
|
||||
uint16_t fds;
|
||||
floatx80 st_space[8];
|
||||
unsigned char tos;
|
||||
unsigned char align1;
|
||||
unsigned char align2;
|
||||
@@ -444,7 +450,7 @@ typedef struct {
|
||||
#define in_smm cpu_state._in_smm
|
||||
#define smi_line cpu_state._smi_line
|
||||
|
||||
#define smbase cpu_state._smbase
|
||||
#define smbase cpu_state._smbase
|
||||
|
||||
/*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block
|
||||
to be valid*/
|
||||
@@ -454,9 +460,9 @@ typedef struct {
|
||||
#define CPU_STATUS_V86 (1 << 3)
|
||||
#define CPU_STATUS_SMM (1 << 4)
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#define CPU_STATUS_FLAGS 0xff
|
||||
# define CPU_STATUS_FLAGS 0xff
|
||||
#else
|
||||
#define CPU_STATUS_FLAGS 0xffff
|
||||
# define CPU_STATUS_FLAGS 0xffff
|
||||
#endif
|
||||
|
||||
/*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status.
|
||||
@@ -615,8 +621,8 @@ extern uint64_t star;
|
||||
|
||||
#define FPU_CW_Reserved_Bits (0xe0c0)
|
||||
|
||||
#define cr0 cpu_state.CR0.l
|
||||
#define msw cpu_state.CR0.w
|
||||
#define cr0 cpu_state.CR0.l
|
||||
#define msw cpu_state.CR0.w
|
||||
extern uint32_t cr2;
|
||||
extern uint32_t cr3;
|
||||
extern uint32_t cr4;
|
||||
@@ -720,8 +726,8 @@ extern void loadseg_dynarec(uint16_t seg, x86seg *s);
|
||||
extern int loadseg(uint16_t seg, x86seg *s);
|
||||
extern void loadcs(uint16_t seg);
|
||||
#else
|
||||
extern void loadseg(uint16_t seg, x86seg *s);
|
||||
extern void loadcs(uint16_t seg);
|
||||
extern void loadseg(uint16_t seg, x86seg *s);
|
||||
extern void loadcs(uint16_t seg);
|
||||
#endif
|
||||
|
||||
extern char *cpu_current_pc(char *bufp);
|
||||
@@ -748,6 +754,7 @@ extern void execx86(int cycs);
|
||||
extern void enter_smm(int in_hlt);
|
||||
extern void enter_smm_check(int in_hlt);
|
||||
extern void leave_smm(void);
|
||||
extern void exec386_2386(int cycs);
|
||||
extern void exec386(int cycs);
|
||||
extern void exec386_dynarec(int cycs);
|
||||
extern int idivl(int32_t val);
|
||||
@@ -758,11 +765,11 @@ extern void pmodeint(int num, int soft);
|
||||
extern void pmoderetf(int is32, uint16_t off);
|
||||
extern void pmodeiret(int is32);
|
||||
#else
|
||||
extern void loadcscall(uint16_t seg);
|
||||
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
|
||||
extern void pmodeint(int num, int soft);
|
||||
extern void pmoderetf(int is32, uint16_t off);
|
||||
extern void pmodeiret(int is32);
|
||||
extern void loadcscall(uint16_t seg);
|
||||
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
|
||||
extern void pmodeint(int num, int soft);
|
||||
extern void pmoderetf(int is32, uint16_t off);
|
||||
extern void pmodeiret(int is32);
|
||||
#endif
|
||||
extern void resetmcr(void);
|
||||
extern void resetx86(void);
|
||||
@@ -831,6 +838,8 @@ extern int hlt_reset_pending;
|
||||
|
||||
extern cyrix_t cyrix;
|
||||
|
||||
extern int prefetch_prefixes;
|
||||
|
||||
extern uint8_t use_custom_nmi_vector;
|
||||
extern uint32_t custom_nmi_vector;
|
||||
|
||||
@@ -851,9 +860,12 @@ extern void cpu_fast_off_reset(void);
|
||||
extern void smi_raise(void);
|
||||
extern void nmi_raise(void);
|
||||
|
||||
extern MMX_REG *MMP[8];
|
||||
extern MMX_REG *MMP[8];
|
||||
extern uint16_t *MMEP[8];
|
||||
|
||||
extern void mmx_init(void);
|
||||
extern void prefetch_flush(void);
|
||||
|
||||
extern void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32);
|
||||
|
||||
#endif /*EMU_CPU_H*/
|
||||
|
||||
@@ -59,10 +59,12 @@ uint32_t rmdat;
|
||||
uint64_t xt_cpu_multi;
|
||||
|
||||
/* Variables for handling the non-maskable interrupts. */
|
||||
int nmi = 0, nmi_auto_clear = 0;
|
||||
int nmi = 0;
|
||||
int nmi_auto_clear = 0;
|
||||
|
||||
/* Was the CPU ever reset? */
|
||||
int x86_was_reset = 0, soft_reset_pci = 0;
|
||||
int x86_was_reset = 0;
|
||||
int soft_reset_pci = 0;
|
||||
|
||||
/* Is the TRAP flag on? */
|
||||
int trap = 0;
|
||||
@@ -71,7 +73,8 @@ int trap = 0;
|
||||
uint32_t easeg;
|
||||
|
||||
/* This is for the OPTI 283 special reset handling mode. */
|
||||
int reset_on_hlt, hlt_reset_pending;
|
||||
int reset_on_hlt;
|
||||
int hlt_reset_pending;
|
||||
|
||||
#ifdef ENABLE_X86_LOG
|
||||
void dumpregs(int);
|
||||
@@ -171,7 +174,10 @@ makemod1table(void)
|
||||
static void
|
||||
makeznptable(void)
|
||||
{
|
||||
int c, d, e;
|
||||
int c;
|
||||
int d;
|
||||
int e;
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
d = 0;
|
||||
for (e = 0; e < 8; e++) {
|
||||
@@ -267,7 +273,7 @@ reset_common(int hard)
|
||||
loadcs(0xF000);
|
||||
cpu_state.pc = 0xFFF0;
|
||||
if (hard) {
|
||||
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
||||
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
||||
if (is6117)
|
||||
rammask |= 0x03000000;
|
||||
mem_a20_key = mem_a20_alt = mem_a20_state = 0;
|
||||
|
||||
@@ -9,30 +9,44 @@
|
||||
that we don't end up with an unnecessarily short block*/
|
||||
#define ABRT_EXPECTED 0x80
|
||||
|
||||
extern uint8_t opcode, opcode2;
|
||||
extern uint8_t opcode;
|
||||
extern uint8_t opcode2;
|
||||
extern uint8_t flags_p;
|
||||
extern uint8_t znptable8[256];
|
||||
|
||||
extern uint16_t zero, oldcs;
|
||||
extern uint16_t lastcs, lastpc;
|
||||
extern uint16_t zero;
|
||||
extern uint16_t oldcs;
|
||||
extern uint16_t lastcs;
|
||||
extern uint16_t lastpc;
|
||||
extern uint16_t *mod1add[2][8];
|
||||
extern uint16_t znptable16[65536];
|
||||
|
||||
extern int x86_was_reset, trap;
|
||||
extern int codegen_flat_ss, codegen_flat_ds;
|
||||
extern int timetolive, keyboardtimer, trap;
|
||||
extern int optype, stack32;
|
||||
extern int oldcpl, cgate32, cpl_override;
|
||||
extern int x86_was_reset;
|
||||
extern int trap;
|
||||
extern int codegen_flat_ss;
|
||||
extern int codegen_flat_ds;
|
||||
extern int timetolive;
|
||||
extern int keyboardtimer;
|
||||
extern int trap;
|
||||
extern int optype;
|
||||
extern int stack32;
|
||||
extern int oldcpl;
|
||||
extern int cgate32;
|
||||
extern int cpl_override;
|
||||
extern int nmi_enable;
|
||||
extern int oddeven, inttype;
|
||||
extern int oddeven;
|
||||
extern int inttype;
|
||||
|
||||
extern uint32_t use32;
|
||||
extern uint32_t rmdat, easeg;
|
||||
extern uint32_t oxpc, flags_zn;
|
||||
extern uint32_t rmdat;
|
||||
extern uint32_t easeg;
|
||||
extern uint32_t oxpc;
|
||||
extern uint32_t flags_zn;
|
||||
extern uint32_t abrt_error;
|
||||
extern uint32_t backupregs[16];
|
||||
extern uint32_t *mod1seg[8];
|
||||
extern uint32_t *eal_r, *eal_w;
|
||||
extern uint32_t *eal_r;
|
||||
extern uint32_t *eal_w;
|
||||
|
||||
#define fetchdat rmdat
|
||||
|
||||
@@ -68,13 +82,13 @@ extern uint32_t *eal_r, *eal_w;
|
||||
|
||||
enum {
|
||||
ABRT_NONE = 0,
|
||||
ABRT_GEN,
|
||||
ABRT_TS = 0xA,
|
||||
ABRT_NP = 0xB,
|
||||
ABRT_SS = 0xC,
|
||||
ABRT_GPF = 0xD,
|
||||
ABRT_PF = 0xE,
|
||||
ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */
|
||||
ABRT_GEN = 1,
|
||||
ABRT_TS = 0xA,
|
||||
ABRT_NP = 0xB,
|
||||
ABRT_SS = 0xC,
|
||||
ABRT_GPF = 0xD,
|
||||
ABRT_PF = 0xE,
|
||||
ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */
|
||||
};
|
||||
|
||||
extern void x86_doabrt(int x86_abrt);
|
||||
|
||||
@@ -44,9 +44,9 @@
|
||||
typedef int (*OpFn)(uint32_t fetchdat);
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
|
||||
const OpFn *dynarec_opcodes,
|
||||
const OpFn *dynarec_opcodes_0f);
|
||||
extern void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
|
||||
const OpFn *dynarec_opcodes,
|
||||
const OpFn *dynarec_opcodes_0f);
|
||||
|
||||
extern const OpFn *x86_dynarec_opcodes;
|
||||
extern const OpFn *x86_dynarec_opcodes_0f;
|
||||
@@ -187,10 +187,9 @@ extern const OpFn dynarec_ops_REPNE[1024];
|
||||
extern const OpFn dynarec_ops_3DNOW[256];
|
||||
extern const OpFn dynarec_ops_3DNOWE[256];
|
||||
#else
|
||||
void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f);
|
||||
extern void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f);
|
||||
#endif
|
||||
|
||||
|
||||
extern const OpFn *x86_opcodes;
|
||||
extern const OpFn *x86_opcodes_0f;
|
||||
extern const OpFn *x86_opcodes_d8_a16;
|
||||
@@ -330,6 +329,111 @@ extern const OpFn ops_REPNE[1024];
|
||||
extern const OpFn ops_3DNOW[256];
|
||||
extern const OpFn ops_3DNOWE[256];
|
||||
|
||||
extern void x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f);
|
||||
|
||||
extern const OpFn *x86_2386_opcodes;
|
||||
extern const OpFn *x86_2386_opcodes_0f;
|
||||
extern const OpFn *x86_2386_opcodes_d8_a16;
|
||||
extern const OpFn *x86_2386_opcodes_d8_a32;
|
||||
extern const OpFn *x86_2386_opcodes_d9_a16;
|
||||
extern const OpFn *x86_2386_opcodes_d9_a32;
|
||||
extern const OpFn *x86_2386_opcodes_da_a16;
|
||||
extern const OpFn *x86_2386_opcodes_da_a32;
|
||||
extern const OpFn *x86_2386_opcodes_db_a16;
|
||||
extern const OpFn *x86_2386_opcodes_db_a32;
|
||||
extern const OpFn *x86_2386_opcodes_dc_a16;
|
||||
extern const OpFn *x86_2386_opcodes_dc_a32;
|
||||
extern const OpFn *x86_2386_opcodes_dd_a16;
|
||||
extern const OpFn *x86_2386_opcodes_dd_a32;
|
||||
extern const OpFn *x86_2386_opcodes_de_a16;
|
||||
extern const OpFn *x86_2386_opcodes_de_a32;
|
||||
extern const OpFn *x86_2386_opcodes_df_a16;
|
||||
extern const OpFn *x86_2386_opcodes_df_a32;
|
||||
extern const OpFn *x86_2386_opcodes_REPE;
|
||||
extern const OpFn *x86_2386_opcodes_REPNE;
|
||||
|
||||
extern const OpFn ops_2386_186[1024];
|
||||
extern const OpFn ops_2386_186_0f[1024];
|
||||
|
||||
extern const OpFn ops_2386_286[1024];
|
||||
extern const OpFn ops_2386_286_0f[1024];
|
||||
|
||||
extern const OpFn ops_2386_386[1024];
|
||||
extern const OpFn ops_2386_386_0f[1024];
|
||||
|
||||
extern const OpFn ops_2386_486_0f[1024];
|
||||
extern const OpFn ops_2386_ibm486_0f[1024];
|
||||
|
||||
extern const OpFn ops_2386_sf_fpu_287_d9_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_d9_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_da_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_da_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_db_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_db_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_dc_a16[32];
|
||||
extern const OpFn ops_2386_sf_fpu_287_dc_a32[32];
|
||||
extern const OpFn ops_2386_sf_fpu_287_dd_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_dd_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_de_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_de_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_df_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_287_df_a32[256];
|
||||
|
||||
extern const OpFn ops_2386_sf_fpu_d8_a16[32];
|
||||
extern const OpFn ops_2386_sf_fpu_d8_a32[32];
|
||||
extern const OpFn ops_2386_sf_fpu_d9_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_d9_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_da_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_da_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_db_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_db_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_dc_a16[32];
|
||||
extern const OpFn ops_2386_sf_fpu_dc_a32[32];
|
||||
extern const OpFn ops_2386_sf_fpu_dd_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_dd_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_de_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_de_a32[256];
|
||||
extern const OpFn ops_2386_sf_fpu_df_a16[256];
|
||||
extern const OpFn ops_2386_sf_fpu_df_a32[256];
|
||||
|
||||
extern const OpFn ops_2386_fpu_287_d9_a16[256];
|
||||
extern const OpFn ops_2386_fpu_287_d9_a32[256];
|
||||
extern const OpFn ops_2386_fpu_287_da_a16[256];
|
||||
extern const OpFn ops_2386_fpu_287_da_a32[256];
|
||||
extern const OpFn ops_2386_fpu_287_db_a16[256];
|
||||
extern const OpFn ops_2386_fpu_287_db_a32[256];
|
||||
extern const OpFn ops_2386_fpu_287_dc_a16[32];
|
||||
extern const OpFn ops_2386_fpu_287_dc_a32[32];
|
||||
extern const OpFn ops_2386_fpu_287_dd_a16[256];
|
||||
extern const OpFn ops_2386_fpu_287_dd_a32[256];
|
||||
extern const OpFn ops_2386_fpu_287_de_a16[256];
|
||||
extern const OpFn ops_2386_fpu_287_de_a32[256];
|
||||
extern const OpFn ops_2386_fpu_287_df_a16[256];
|
||||
extern const OpFn ops_2386_fpu_287_df_a32[256];
|
||||
|
||||
extern const OpFn ops_2386_fpu_d8_a16[32];
|
||||
extern const OpFn ops_2386_fpu_d8_a32[32];
|
||||
extern const OpFn ops_2386_fpu_d9_a16[256];
|
||||
extern const OpFn ops_2386_fpu_d9_a32[256];
|
||||
extern const OpFn ops_2386_fpu_da_a16[256];
|
||||
extern const OpFn ops_2386_fpu_da_a32[256];
|
||||
extern const OpFn ops_2386_fpu_db_a16[256];
|
||||
extern const OpFn ops_2386_fpu_db_a32[256];
|
||||
extern const OpFn ops_2386_fpu_dc_a16[32];
|
||||
extern const OpFn ops_2386_fpu_dc_a32[32];
|
||||
extern const OpFn ops_2386_fpu_dd_a16[256];
|
||||
extern const OpFn ops_2386_fpu_dd_a32[256];
|
||||
extern const OpFn ops_2386_fpu_de_a16[256];
|
||||
extern const OpFn ops_2386_fpu_de_a32[256];
|
||||
extern const OpFn ops_2386_fpu_df_a16[256];
|
||||
extern const OpFn ops_2386_fpu_df_a32[256];
|
||||
extern const OpFn ops_2386_nofpu_a16[256];
|
||||
extern const OpFn ops_2386_nofpu_a32[256];
|
||||
|
||||
extern const OpFn ops_2386_REPE[1024];
|
||||
extern const OpFn ops_2386_REPNE[1024];
|
||||
extern const OpFn ops_2386_3DNOW[256];
|
||||
|
||||
#define C0 (1 << 8)
|
||||
#define C1 (1 << 9)
|
||||
#define C2 (1 << 10)
|
||||
|
||||
@@ -35,7 +35,7 @@ opFEMMS(uint32_t fetchdat)
|
||||
static int
|
||||
opPAVGUSB(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -56,7 +56,7 @@ opPAVGUSB(uint32_t fetchdat)
|
||||
static int
|
||||
opPF2ID(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -71,7 +71,7 @@ opPF2ID(uint32_t fetchdat)
|
||||
static int
|
||||
opPF2IW(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -86,9 +86,9 @@ opPF2IW(uint32_t fetchdat)
|
||||
static int
|
||||
opPFACC(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
float tempf;
|
||||
float tempf;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
@@ -103,9 +103,9 @@ opPFACC(uint32_t fetchdat)
|
||||
static int
|
||||
opPFNACC(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
float tempf;
|
||||
float tempf;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
@@ -120,9 +120,9 @@ opPFNACC(uint32_t fetchdat)
|
||||
static int
|
||||
opPFPNACC(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
float tempf;
|
||||
float tempf;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
@@ -137,9 +137,10 @@ opPFPNACC(uint32_t fetchdat)
|
||||
static int
|
||||
opPSWAPD(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
float tempf, tempf2;
|
||||
float tempf;
|
||||
float tempf2;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
@@ -156,7 +157,7 @@ opPSWAPD(uint32_t fetchdat)
|
||||
static int
|
||||
opPFADD(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -171,7 +172,7 @@ opPFADD(uint32_t fetchdat)
|
||||
static int
|
||||
opPFCMPEQ(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -186,7 +187,7 @@ opPFCMPEQ(uint32_t fetchdat)
|
||||
static int
|
||||
opPFCMPGE(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -201,7 +202,7 @@ opPFCMPGE(uint32_t fetchdat)
|
||||
static int
|
||||
opPFCMPGT(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -216,7 +217,7 @@ opPFCMPGT(uint32_t fetchdat)
|
||||
static int
|
||||
opPFMAX(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -233,7 +234,7 @@ opPFMAX(uint32_t fetchdat)
|
||||
static int
|
||||
opPFMIN(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -250,7 +251,7 @@ opPFMIN(uint32_t fetchdat)
|
||||
static int
|
||||
opPFMUL(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -294,7 +295,7 @@ opPFRCP(uint32_t fetchdat)
|
||||
static int
|
||||
opPFRCPIT1(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -309,7 +310,7 @@ opPFRCPIT1(uint32_t fetchdat)
|
||||
static int
|
||||
opPFRCPIT2(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -363,7 +364,7 @@ opPFRSQIT1(uint32_t fetchdat)
|
||||
static int
|
||||
opPFSUB(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -378,7 +379,7 @@ opPFSUB(uint32_t fetchdat)
|
||||
static int
|
||||
opPFSUBR(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -393,7 +394,7 @@ opPFSUBR(uint32_t fetchdat)
|
||||
static int
|
||||
opPI2FD(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -408,7 +409,7 @@ opPI2FD(uint32_t fetchdat)
|
||||
static int
|
||||
opPI2FW(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -423,7 +424,7 @@ opPI2FW(uint32_t fetchdat)
|
||||
static int
|
||||
opPMULHRW(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst = MMX_GETREGP(cpu_reg);
|
||||
|
||||
if (cpu_mod == 3) {
|
||||
|
||||
@@ -340,6 +340,7 @@ static int
|
||||
opCMP_b_rmw_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -359,6 +360,7 @@ static int
|
||||
opCMP_b_rmw_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -379,6 +381,7 @@ static int
|
||||
opCMP_w_rmw_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -398,6 +401,7 @@ static int
|
||||
opCMP_w_rmw_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -418,6 +422,7 @@ static int
|
||||
opCMP_l_rmw_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -437,6 +442,7 @@ static int
|
||||
opCMP_l_rmw_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -457,6 +463,7 @@ static int
|
||||
opCMP_b_rm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -472,6 +479,7 @@ static int
|
||||
opCMP_b_rm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -488,6 +496,7 @@ static int
|
||||
opCMP_w_rm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -503,6 +512,7 @@ static int
|
||||
opCMP_w_rm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -519,6 +529,7 @@ static int
|
||||
opCMP_l_rm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -534,6 +545,7 @@ static int
|
||||
opCMP_l_rm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -550,6 +562,7 @@ static int
|
||||
opCMP_AL_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src = getbytef();
|
||||
|
||||
setsub8(AL, src);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0);
|
||||
@@ -560,6 +573,7 @@ static int
|
||||
opCMP_AX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src = getwordf();
|
||||
|
||||
setsub16(AX, src);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0);
|
||||
@@ -570,6 +584,7 @@ static int
|
||||
opCMP_EAX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src = getlong();
|
||||
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setsub32(EAX, src);
|
||||
@@ -581,7 +596,9 @@ opCMP_EAX_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opTEST_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2;
|
||||
uint8_t temp;
|
||||
uint8_t temp2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -601,7 +618,9 @@ opTEST_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opTEST_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2;
|
||||
uint8_t temp;
|
||||
uint8_t temp2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -622,7 +641,9 @@ opTEST_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opTEST_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2;
|
||||
uint16_t temp;
|
||||
uint16_t temp2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -642,7 +663,9 @@ opTEST_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opTEST_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2;
|
||||
uint16_t temp;
|
||||
uint16_t temp2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -663,7 +686,9 @@ opTEST_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opTEST_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2;
|
||||
uint32_t temp;
|
||||
uint32_t temp2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -683,7 +708,9 @@ opTEST_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opTEST_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2;
|
||||
uint32_t temp;
|
||||
uint32_t temp2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
@@ -803,7 +830,8 @@ opTEST_EAX(uint32_t fetchdat)
|
||||
static int
|
||||
op80_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src, dst;
|
||||
uint8_t src;
|
||||
uint8_t dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -823,7 +851,8 @@ op80_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op80_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src, dst;
|
||||
uint8_t src;
|
||||
uint8_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -843,7 +872,8 @@ op80_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op81_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
uint16_t src;
|
||||
uint16_t dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -863,7 +893,8 @@ op81_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op81_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
uint16_t src;
|
||||
uint16_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -883,7 +914,8 @@ op81_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op81_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
uint32_t src;
|
||||
uint32_t dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -903,7 +935,8 @@ op81_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op81_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
uint32_t src;
|
||||
uint32_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -924,7 +957,8 @@ op81_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op83_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
uint16_t src;
|
||||
uint16_t dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -946,7 +980,8 @@ op83_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op83_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
uint16_t src;
|
||||
uint16_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -969,7 +1004,8 @@ op83_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op83_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
uint32_t src;
|
||||
uint32_t dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -991,7 +1027,8 @@ op83_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op83_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
uint32_t src;
|
||||
uint32_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
static int
|
||||
opCMPXCHG_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2 = AL;
|
||||
uint8_t temp;
|
||||
uint8_t temp2 = AL;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
@@ -20,7 +22,9 @@ opCMPXCHG_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2 = AL;
|
||||
uint8_t temp;
|
||||
uint8_t temp2 = AL;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
@@ -40,7 +44,9 @@ opCMPXCHG_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2 = AX;
|
||||
uint16_t temp;
|
||||
uint16_t temp2 = AX;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
@@ -59,7 +65,9 @@ opCMPXCHG_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2 = AX;
|
||||
uint16_t temp;
|
||||
uint16_t temp2 = AX;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
@@ -79,7 +87,9 @@ opCMPXCHG_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2 = EAX;
|
||||
uint32_t temp;
|
||||
uint32_t temp2 = EAX;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
@@ -98,7 +108,9 @@ opCMPXCHG_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2 = EAX;
|
||||
uint32_t temp;
|
||||
uint32_t temp2 = EAX;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
@@ -115,10 +127,15 @@ opCMPXCHG_l_a32(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPS_286_386
|
||||
static int
|
||||
opCMPXCHG8B_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
|
||||
uint32_t temp;
|
||||
uint32_t temp_hi;
|
||||
uint32_t temp2 = EAX;
|
||||
uint32_t temp2_hi = EDX;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
@@ -145,7 +162,11 @@ opCMPXCHG8B_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG8B_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
|
||||
uint32_t temp;
|
||||
uint32_t temp_hi;
|
||||
uint32_t temp2 = EAX;
|
||||
uint32_t temp2_hi = EDX;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
@@ -169,13 +190,16 @@ opCMPXCHG8B_a32(uint32_t fetchdat)
|
||||
cycles -= (cpu_mod == 3) ? 6 : 10;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* dest = eab, src = r8 */
|
||||
static int
|
||||
opXADD_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t src, dest;
|
||||
uint8_t src;
|
||||
uint8_t dest;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getr8(cpu_reg);
|
||||
@@ -195,7 +219,9 @@ static int
|
||||
opXADD_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t src, dest;
|
||||
uint8_t src;
|
||||
uint8_t dest;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getr8(cpu_reg);
|
||||
@@ -216,7 +242,9 @@ static int
|
||||
opXADD_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t src, dest;
|
||||
uint16_t src;
|
||||
uint16_t dest;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].w;
|
||||
@@ -236,7 +264,9 @@ static int
|
||||
opXADD_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t src, dest;
|
||||
uint16_t src;
|
||||
uint16_t dest;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].w;
|
||||
@@ -257,7 +287,9 @@ static int
|
||||
opXADD_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t src, dest;
|
||||
uint32_t src;
|
||||
uint32_t dest;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].l;
|
||||
@@ -277,7 +309,9 @@ static int
|
||||
opXADD_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t src, dest;
|
||||
uint32_t src;
|
||||
uint32_t dest;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].l;
|
||||
|
||||
@@ -19,6 +19,7 @@ static int
|
||||
opAAD(uint32_t fetchdat)
|
||||
{
|
||||
int base = getbytef();
|
||||
|
||||
if (!cpu_isintel)
|
||||
base = 10;
|
||||
AL = (AH * base) + AL;
|
||||
@@ -33,6 +34,7 @@ static int
|
||||
opAAM(uint32_t fetchdat)
|
||||
{
|
||||
int base = getbytef();
|
||||
|
||||
if (!base || !cpu_isintel)
|
||||
base = 10;
|
||||
AH = AL / base;
|
||||
@@ -63,7 +65,9 @@ opAAS(uint32_t fetchdat)
|
||||
static int
|
||||
opDAA(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw, old_AL, old_CF;
|
||||
uint16_t tempw;
|
||||
uint16_t old_AL;
|
||||
uint16_t old_CF;
|
||||
|
||||
flags_rebuild();
|
||||
old_AL = AL;
|
||||
@@ -98,7 +102,9 @@ opDAA(uint32_t fetchdat)
|
||||
static int
|
||||
opDAS(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw, old_AL, old_CF;
|
||||
uint16_t tempw;
|
||||
uint16_t old_AL;
|
||||
uint16_t old_CF;
|
||||
|
||||
flags_rebuild();
|
||||
old_AL = AL;
|
||||
|
||||
@@ -201,13 +201,17 @@ opBT_l_r_a32(uint32_t fetchdat)
|
||||
return 0; \
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
opBT(C, ^=)
|
||||
opBT(R, &= ~)
|
||||
opBT(S, |=)
|
||||
opBT(R, &= ~)
|
||||
opBT(S, |=)
|
||||
// clang-format on
|
||||
|
||||
static int opBA_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBA_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int tempc, count;
|
||||
int tempc;
|
||||
int count;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
@@ -258,7 +262,8 @@ opBT(C, ^=)
|
||||
static int
|
||||
opBA_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int tempc, count;
|
||||
int tempc;
|
||||
int count;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
@@ -310,7 +315,8 @@ opBA_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBA_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int tempc, count;
|
||||
int tempc;
|
||||
int count;
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
@@ -361,7 +367,8 @@ opBA_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBA_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int tempc, count;
|
||||
int tempc;
|
||||
int count;
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
|
||||
@@ -189,8 +189,10 @@
|
||||
static int
|
||||
opCALL_far_w(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t old_cs, old_pc;
|
||||
uint16_t new_cs, new_pc;
|
||||
uint32_t old_cs;
|
||||
uint32_t old_pc;
|
||||
uint16_t new_cs;
|
||||
uint16_t new_pc;
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
@@ -209,8 +211,10 @@ opCALL_far_w(uint32_t fetchdat)
|
||||
static int
|
||||
opCALL_far_l(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t old_cs, old_pc;
|
||||
uint32_t new_cs, new_pc;
|
||||
uint32_t old_cs;
|
||||
uint32_t old_pc;
|
||||
uint32_t new_cs;
|
||||
uint32_t new_pc;
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
@@ -230,8 +234,10 @@ opCALL_far_l(uint32_t fetchdat)
|
||||
static int
|
||||
opFF_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t old_cs, new_cs;
|
||||
uint32_t old_pc, new_pc;
|
||||
uint16_t old_cs;
|
||||
uint16_t new_cs;
|
||||
uint32_t old_pc;
|
||||
uint32_t new_pc;
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
@@ -392,8 +398,10 @@ opFF_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFF_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t old_cs, new_cs;
|
||||
uint32_t old_pc, new_pc;
|
||||
uint16_t old_cs;
|
||||
uint16_t new_cs;
|
||||
uint32_t old_pc;
|
||||
uint32_t new_pc;
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
@@ -555,8 +563,10 @@ opFF_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFF_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t old_cs, new_cs;
|
||||
uint32_t old_pc, new_pc;
|
||||
uint16_t old_cs;
|
||||
uint16_t new_cs;
|
||||
uint32_t old_pc;
|
||||
uint32_t new_pc;
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
@@ -717,8 +727,10 @@ opFF_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFF_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t old_cs, new_cs;
|
||||
uint32_t old_pc, new_pc;
|
||||
uint16_t old_cs;
|
||||
uint16_t new_cs;
|
||||
uint32_t old_pc;
|
||||
uint32_t new_pc;
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
|
||||
@@ -97,7 +97,9 @@ opWAIT(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if (!cpu_use_dynarec && fpu_softfloat) {
|
||||
#if 0
|
||||
if (!cpu_use_dynarec && fpu_softfloat) {
|
||||
#endif
|
||||
if (fpu_softfloat) {
|
||||
if (fpu_state.swd & FPU_SW_Summary) {
|
||||
if (cr0 & 0x20) {
|
||||
|
||||
@@ -46,10 +46,10 @@ opSYSEXIT(uint32_t fetchdat)
|
||||
static int
|
||||
sf_fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
{
|
||||
uint8_t fxinst = 0;
|
||||
uint32_t tag_byte;
|
||||
unsigned index;
|
||||
floatx80 reg;
|
||||
uint8_t fxinst = 0;
|
||||
uint32_t tag_byte;
|
||||
unsigned index;
|
||||
floatx80 reg;
|
||||
|
||||
if (CPUID < 0x650)
|
||||
return ILLEGAL(fetchdat);
|
||||
@@ -129,33 +129,33 @@ sf_fx_save_stor_common(uint32_t fetchdat, int 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
|
||||
*/
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
/*
|
||||
* 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 */
|
||||
/* store i387 register file */
|
||||
for (index = 0; index < 8; index++) {
|
||||
const floatx80 fp = FPU_read_regi(index);
|
||||
|
||||
@@ -172,70 +172,72 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
static int
|
||||
fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
{
|
||||
uint8_t fxinst = 0;
|
||||
uint16_t twd = x87_gettag();
|
||||
uint32_t old_eaaddr = 0;
|
||||
uint8_t ftwb = 0;
|
||||
uint16_t rec_ftw = 0;
|
||||
uint16_t fpus = 0;
|
||||
int i, mmx_tags = 0;
|
||||
uint16_t exp = 0x0000;
|
||||
uint64_t mant = 0x0000000000000000ULL;
|
||||
uint64_t fraction;
|
||||
uint8_t jm, valid;
|
||||
/* Exp_all_1 Exp_all_0 Frac_all_0 J M FTW_Valid | Ent
|
||||
----------------------------------------------+------ */
|
||||
uint8_t ftw_table_idx;
|
||||
uint8_t ftw_table[48] = { 0x03, /* 0 0 0 0 0 0 | 0x00 */
|
||||
0x02, /* 0 0 0 0 0 1 | 0x01 */
|
||||
0x03, /* 0 0 0 0 0 0 | 0x02 */
|
||||
0x02, /* 0 0 0 0 1 1 | 0x03 */
|
||||
0x03, /* 0 0 0 1 0 0 | 0x04 */
|
||||
0x00, /* 0 0 0 1 0 1 | 0x05 */
|
||||
0x03, /* 0 0 0 1 1 0 | 0x06 */
|
||||
0x00, /* 0 0 0 1 1 1 | 0x07 */
|
||||
0x03, /* 0 0 1 0 0 0 | 0x08 */
|
||||
0x02, /* 0 0 1 0 0 1 | 0x09 */
|
||||
0x03, /* 0 0 1 0 1 0 | 0x0a - Impossible */
|
||||
0x03, /* 0 0 1 0 1 1 | 0x0b - Impossible */
|
||||
0x03, /* 0 0 1 1 0 0 | 0x0c */
|
||||
0x02, /* 0 0 1 1 0 1 | 0x0d */
|
||||
0x03, /* 0 0 1 1 1 0 | 0x0e - Impossible */
|
||||
0x03, /* 0 0 1 1 1 1 | 0x0f - Impossible */
|
||||
0x03, /* 0 1 0 0 0 0 | 0x10 */
|
||||
0x02, /* 0 1 0 0 0 1 | 0x11 */
|
||||
0x03, /* 0 1 0 0 1 0 | 0x12 */
|
||||
0x02, /* 0 1 0 0 1 1 | 0x13 */
|
||||
0x03, /* 0 1 0 1 0 0 | 0x14 */
|
||||
0x02, /* 0 1 0 1 0 1 | 0x15 */
|
||||
0x03, /* 0 1 0 1 1 0 | 0x16 */
|
||||
0x02, /* 0 1 0 1 1 1 | 0x17 */
|
||||
0x03, /* 0 1 1 0 0 0 | 0x18 */
|
||||
0x01, /* 0 1 1 0 0 1 | 0x19 */
|
||||
0x03, /* 0 1 1 0 1 0 | 0x1a - Impossible */
|
||||
0x03, /* 0 1 1 0 1 1 | 0x1b - Impossible */
|
||||
0x03, /* 0 1 1 1 0 0 | 0x1c */
|
||||
0x01, /* 0 1 1 1 0 1 | 0x1d */
|
||||
0x03, /* 0 1 1 1 1 0 | 0x1e - Impossible */
|
||||
0x03, /* 0 1 1 1 1 1 | 0x1f - Impossible */
|
||||
0x03, /* 1 0 0 0 0 0 | 0x20 */
|
||||
0x02, /* 1 0 0 0 0 1 | 0x21 */
|
||||
0x03, /* 1 0 0 0 1 0 | 0x22 */
|
||||
0x02, /* 1 0 0 0 1 1 | 0x23 */
|
||||
0x03, /* 1 0 0 1 0 0 | 0x24 */
|
||||
0x02, /* 1 0 0 1 0 1 | 0x25 */
|
||||
0x03, /* 1 0 0 1 1 0 | 0x26 */
|
||||
0x02, /* 1 0 0 1 1 1 | 0x27 */
|
||||
0x03, /* 1 0 1 0 0 0 | 0x28 */
|
||||
0x02, /* 1 0 1 0 0 1 | 0x29 */
|
||||
0x03, /* 1 0 1 0 1 0 | 0x2a - Impossible */
|
||||
0x03, /* 1 0 1 0 1 1 | 0x2b - Impossible */
|
||||
0x03, /* 1 0 1 1 0 0 | 0x2c */
|
||||
0x02, /* 1 0 1 1 0 1 | 0x2d */
|
||||
0x03, /* 1 0 1 1 1 0 | 0x2e - Impossible */
|
||||
0x03 }; /* 1 0 1 1 1 1 | 0x2f - Impossible */
|
||||
/* M is the most significant bit of the franction, so it is impossible
|
||||
for M to o be 1 when the fraction is all 0's. */
|
||||
uint8_t fxinst = 0;
|
||||
uint16_t twd = x87_gettag();
|
||||
uint32_t old_eaaddr = 0;
|
||||
uint8_t ftwb = 0;
|
||||
uint16_t rec_ftw = 0;
|
||||
uint16_t fpus = 0;
|
||||
int i;
|
||||
int mmx_tags = 0;
|
||||
uint16_t exp = 0x0000;
|
||||
uint64_t mant = 0x0000000000000000ULL;
|
||||
uint64_t fraction;
|
||||
uint8_t jm;
|
||||
uint8_t valid;
|
||||
/* Exp_all_1 Exp_all_0 Frac_all_0 J M FTW_Valid | Ent
|
||||
----------------------------------------------+------ */
|
||||
uint8_t ftw_table_idx;
|
||||
uint8_t ftw_table[48] = { 0x03, /* 0 0 0 0 0 0 | 0x00 */
|
||||
0x02, /* 0 0 0 0 0 1 | 0x01 */
|
||||
0x03, /* 0 0 0 0 0 0 | 0x02 */
|
||||
0x02, /* 0 0 0 0 1 1 | 0x03 */
|
||||
0x03, /* 0 0 0 1 0 0 | 0x04 */
|
||||
0x00, /* 0 0 0 1 0 1 | 0x05 */
|
||||
0x03, /* 0 0 0 1 1 0 | 0x06 */
|
||||
0x00, /* 0 0 0 1 1 1 | 0x07 */
|
||||
0x03, /* 0 0 1 0 0 0 | 0x08 */
|
||||
0x02, /* 0 0 1 0 0 1 | 0x09 */
|
||||
0x03, /* 0 0 1 0 1 0 | 0x0a - Impossible */
|
||||
0x03, /* 0 0 1 0 1 1 | 0x0b - Impossible */
|
||||
0x03, /* 0 0 1 1 0 0 | 0x0c */
|
||||
0x02, /* 0 0 1 1 0 1 | 0x0d */
|
||||
0x03, /* 0 0 1 1 1 0 | 0x0e - Impossible */
|
||||
0x03, /* 0 0 1 1 1 1 | 0x0f - Impossible */
|
||||
0x03, /* 0 1 0 0 0 0 | 0x10 */
|
||||
0x02, /* 0 1 0 0 0 1 | 0x11 */
|
||||
0x03, /* 0 1 0 0 1 0 | 0x12 */
|
||||
0x02, /* 0 1 0 0 1 1 | 0x13 */
|
||||
0x03, /* 0 1 0 1 0 0 | 0x14 */
|
||||
0x02, /* 0 1 0 1 0 1 | 0x15 */
|
||||
0x03, /* 0 1 0 1 1 0 | 0x16 */
|
||||
0x02, /* 0 1 0 1 1 1 | 0x17 */
|
||||
0x03, /* 0 1 1 0 0 0 | 0x18 */
|
||||
0x01, /* 0 1 1 0 0 1 | 0x19 */
|
||||
0x03, /* 0 1 1 0 1 0 | 0x1a - Impossible */
|
||||
0x03, /* 0 1 1 0 1 1 | 0x1b - Impossible */
|
||||
0x03, /* 0 1 1 1 0 0 | 0x1c */
|
||||
0x01, /* 0 1 1 1 0 1 | 0x1d */
|
||||
0x03, /* 0 1 1 1 1 0 | 0x1e - Impossible */
|
||||
0x03, /* 0 1 1 1 1 1 | 0x1f - Impossible */
|
||||
0x03, /* 1 0 0 0 0 0 | 0x20 */
|
||||
0x02, /* 1 0 0 0 0 1 | 0x21 */
|
||||
0x03, /* 1 0 0 0 1 0 | 0x22 */
|
||||
0x02, /* 1 0 0 0 1 1 | 0x23 */
|
||||
0x03, /* 1 0 0 1 0 0 | 0x24 */
|
||||
0x02, /* 1 0 0 1 0 1 | 0x25 */
|
||||
0x03, /* 1 0 0 1 1 0 | 0x26 */
|
||||
0x02, /* 1 0 0 1 1 1 | 0x27 */
|
||||
0x03, /* 1 0 1 0 0 0 | 0x28 */
|
||||
0x02, /* 1 0 1 0 0 1 | 0x29 */
|
||||
0x03, /* 1 0 1 0 1 0 | 0x2a - Impossible */
|
||||
0x03, /* 1 0 1 0 1 1 | 0x2b - Impossible */
|
||||
0x03, /* 1 0 1 1 0 0 | 0x2c */
|
||||
0x02, /* 1 0 1 1 0 1 | 0x2d */
|
||||
0x03, /* 1 0 1 1 1 0 | 0x2e - Impossible */
|
||||
0x03 }; /* 1 0 1 1 1 1 | 0x2f - Impossible */
|
||||
/* M is the most significant bit of the franction, so it is impossible
|
||||
for M to o be 1 when the fraction is all 0's. */
|
||||
|
||||
if (CPUID < 0x650)
|
||||
return ILLEGAL(fetchdat);
|
||||
@@ -285,11 +287,11 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
|
||||
for (i = 0; i <= 7; i++) {
|
||||
cpu_state.eaaddr = old_eaaddr + 32 + (i << 4);
|
||||
mant = readmemq(easeg, cpu_state.eaaddr);
|
||||
fraction = mant & 0x7fffffffffffffffULL;
|
||||
exp = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
jm = (mant >> 62) & 0x03;
|
||||
valid = !(ftwb & (1 << i));
|
||||
mant = readmemq(easeg, cpu_state.eaaddr);
|
||||
fraction = mant & 0x7fffffffffffffffULL;
|
||||
exp = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
jm = (mant >> 62) & 0x03;
|
||||
valid = !(ftwb & (1 << i));
|
||||
|
||||
ftw_table_idx = (!!(exp == 0x1111)) << 5;
|
||||
ftw_table_idx |= (!!(exp == 0x0000)) << 4;
|
||||
@@ -379,7 +381,7 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
static int
|
||||
opFXSAVESTOR_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (fpu_softfloat)
|
||||
if (fpu_softfloat)
|
||||
return sf_fx_save_stor_common(fetchdat, 16);
|
||||
|
||||
return fx_save_stor_common(fetchdat, 16);
|
||||
|
||||
@@ -86,9 +86,10 @@ opJ(L)
|
||||
opJ(NL)
|
||||
opJ(LE)
|
||||
opJ(NLE)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
static int opLOOPNE_w(uint32_t fetchdat)
|
||||
static int
|
||||
opLOOPNE_w(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
CX--;
|
||||
@@ -271,8 +272,10 @@ opJMP_r32(uint32_t fetchdat)
|
||||
static int
|
||||
opJMP_far_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
uint16_t addr;
|
||||
uint16_t seg;
|
||||
uint32_t old_pc;
|
||||
|
||||
addr = getwordf();
|
||||
seg = getword();
|
||||
if (cpu_state.abrt)
|
||||
@@ -289,7 +292,9 @@ static int
|
||||
opJMP_far_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t seg;
|
||||
uint32_t addr, old_pc;
|
||||
uint32_t addr;
|
||||
uint32_t old_pc;
|
||||
|
||||
addr = getlong();
|
||||
seg = getword();
|
||||
if (cpu_state.abrt)
|
||||
@@ -307,6 +312,7 @@ static int
|
||||
opCALL_r16(uint32_t fetchdat)
|
||||
{
|
||||
int16_t addr = (int16_t) getwordf();
|
||||
|
||||
PUSH_W(cpu_state.pc);
|
||||
cpu_state.pc += addr;
|
||||
cpu_state.pc &= 0xffff;
|
||||
@@ -320,6 +326,7 @@ static int
|
||||
opCALL_r32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t addr = getlong();
|
||||
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
PUSH_L(cpu_state.pc);
|
||||
|
||||
@@ -55,7 +55,8 @@ opF6_a16(uint32_t fetchdat)
|
||||
int tempws2 = 0;
|
||||
uint16_t tempw = 0;
|
||||
uint16_t src16;
|
||||
uint8_t src, dst;
|
||||
uint8_t src;
|
||||
uint8_t dst;
|
||||
int8_t temps;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
@@ -173,7 +174,8 @@ opF6_a32(uint32_t fetchdat)
|
||||
int tempws2 = 0;
|
||||
uint16_t tempw = 0;
|
||||
uint16_t src16;
|
||||
uint8_t src, dst;
|
||||
uint8_t src;
|
||||
uint8_t dst;
|
||||
int8_t temps;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
@@ -287,7 +289,7 @@ static int
|
||||
opF7_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t templ;
|
||||
uint32_t templ2 = 0;
|
||||
uint32_t templ2 = 0;
|
||||
int tempws;
|
||||
int tempws2 = 0;
|
||||
int16_t temps16;
|
||||
@@ -400,11 +402,12 @@ static int
|
||||
opF7_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t templ;
|
||||
uint32_t templ2 = 0;
|
||||
uint32_t templ2 = 0;
|
||||
int tempws;
|
||||
int tempws2 = 1;
|
||||
int16_t temps16;
|
||||
uint16_t src, dst;
|
||||
uint16_t src;
|
||||
uint16_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -514,7 +517,8 @@ static int
|
||||
opF7_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint64_t temp64;
|
||||
uint32_t src, dst;
|
||||
uint32_t src;
|
||||
uint32_t dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -606,7 +610,8 @@ static int
|
||||
opF7_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint64_t temp64;
|
||||
uint32_t src, dst;
|
||||
uint32_t src;
|
||||
uint32_t dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -739,7 +744,8 @@ opLOCK(uint32_t fetchdat)
|
||||
static int
|
||||
opBOUND_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int16_t low, high;
|
||||
int16_t low;
|
||||
int16_t high;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
@@ -761,7 +767,8 @@ opBOUND_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBOUND_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int16_t low, high;
|
||||
int16_t low;
|
||||
int16_t high;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
@@ -784,7 +791,8 @@ opBOUND_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBOUND_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int32_t low, high;
|
||||
int32_t low;
|
||||
int32_t high;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
@@ -806,7 +814,8 @@ opBOUND_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBOUND_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t low, high;
|
||||
int32_t low;
|
||||
int32_t high;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg.h"
|
||||
|
||||
MMX_REG *MMP[8];
|
||||
MMX_REG *MMP[8];
|
||||
uint16_t *MMEP[8];
|
||||
|
||||
static uint16_t MME[8];
|
||||
@@ -40,10 +40,10 @@ mmx_init(void)
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (fpu_softfloat) {
|
||||
MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction;
|
||||
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]);
|
||||
MMP[i] = &(cpu_state.MM[i]);
|
||||
MMEP[i] = &(MME[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val)))
|
||||
#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val)))
|
||||
#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val)))
|
||||
#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val)))
|
||||
#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val)))
|
||||
#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val)))
|
||||
#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_GETREG(r) *(MMP[r])
|
||||
|
||||
#define MMX_SETEXP(r) \
|
||||
#define MMX_SETEXP(r) \
|
||||
*(MMEP[r]) = 0xffff
|
||||
|
||||
#define MMX_GETSRC() \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
static int
|
||||
opPADDB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -27,7 +27,7 @@ opPADDB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -54,7 +54,7 @@ opPADDB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -76,7 +76,7 @@ opPADDW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -99,7 +99,7 @@ opPADDW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -119,7 +119,7 @@ opPADDD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -140,7 +140,7 @@ opPADDD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -166,7 +166,7 @@ opPADDSB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -193,7 +193,7 @@ opPADDSB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDUSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -219,7 +219,7 @@ opPADDUSB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDUSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -246,7 +246,7 @@ opPADDUSB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -268,7 +268,7 @@ opPADDSW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -291,7 +291,7 @@ opPADDSW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDUSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -313,7 +313,7 @@ opPADDUSW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPADDUSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -336,7 +336,7 @@ opPADDUSW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPMADDWD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -363,7 +363,7 @@ opPMADDWD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPMADDWD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -391,7 +391,7 @@ opPMADDWD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPMULLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -422,7 +422,7 @@ opPMULLW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPMULLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -454,7 +454,7 @@ opPMULLW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPMULHW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -485,7 +485,7 @@ opPMULHW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPMULHW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -517,7 +517,7 @@ opPMULHW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -543,7 +543,7 @@ opPSUBB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -570,7 +570,7 @@ opPSUBB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -592,7 +592,7 @@ opPSUBW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -615,7 +615,7 @@ opPSUBW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -635,7 +635,7 @@ opPSUBD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -656,7 +656,7 @@ opPSUBD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -682,7 +682,7 @@ opPSUBSB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -709,7 +709,7 @@ opPSUBSB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBUSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -735,7 +735,7 @@ opPSUBUSB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBUSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -762,7 +762,7 @@ opPSUBUSB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -784,7 +784,7 @@ opPSUBSW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -807,7 +807,7 @@ opPSUBSW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBUSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -829,7 +829,7 @@ opPSUBUSW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSUBUSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
static int
|
||||
opPCMPEQB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -27,7 +27,7 @@ opPCMPEQB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -54,7 +54,7 @@ opPCMPEQB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -80,7 +80,7 @@ opPCMPGTB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -107,7 +107,7 @@ opPCMPGTB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -129,7 +129,7 @@ opPCMPEQW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -152,7 +152,7 @@ opPCMPEQW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -174,7 +174,7 @@ opPCMPGTW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -197,7 +197,7 @@ opPCMPGTW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -217,7 +217,7 @@ opPCMPEQD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -238,7 +238,7 @@ opPCMPEQD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -258,7 +258,7 @@ opPCMPGTD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
static int
|
||||
opPAND_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -20,7 +20,7 @@ opPAND_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPAND_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -40,7 +40,7 @@ opPAND_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPANDN_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -59,7 +59,7 @@ opPANDN_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPANDN_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -79,7 +79,7 @@ opPANDN_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPOR_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -98,7 +98,7 @@ opPOR_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPOR_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -118,7 +118,7 @@ opPOR_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPXOR_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -137,7 +137,7 @@ opPXOR_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPXOR_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ opMOVD_mm_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVD_mm_l_a16_cx(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *op;
|
||||
const MMX_REG *op;
|
||||
|
||||
if (in_smm)
|
||||
return opSMINT(fetchdat);
|
||||
@@ -144,7 +144,7 @@ opMOVD_mm_l_a16_cx(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVD_mm_l_a32_cx(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *op;
|
||||
const MMX_REG *op;
|
||||
|
||||
if (in_smm)
|
||||
return opSMINT(fetchdat);
|
||||
@@ -176,14 +176,14 @@ static int
|
||||
opMOVQ_q_mm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint64_t dst;
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *op;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
|
||||
src = MMX_GETREG(cpu_rm);
|
||||
op = MMX_GETREGP(cpu_reg);
|
||||
op = MMX_GETREGP(cpu_reg);
|
||||
|
||||
if (cpu_mod == 3) {
|
||||
op->q = src.q;
|
||||
@@ -206,14 +206,14 @@ static int
|
||||
opMOVQ_q_mm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint64_t dst;
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *op;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
|
||||
src = MMX_GETREG(cpu_rm);
|
||||
op = MMX_GETREGP(cpu_reg);
|
||||
op = MMX_GETREGP(cpu_reg);
|
||||
|
||||
if (cpu_mod == 3) {
|
||||
op->q = src.q;
|
||||
@@ -236,7 +236,7 @@ opMOVQ_q_mm_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVQ_mm_q_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
|
||||
MMX_ENTER();
|
||||
@@ -266,7 +266,7 @@ opMOVQ_mm_q_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVQ_mm_q_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -2,7 +2,7 @@ static int
|
||||
opPUNPCKLDQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t usrc;
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -32,7 +32,7 @@ static int
|
||||
opPUNPCKLDQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t usrc;
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -62,7 +62,7 @@ opPUNPCKLDQ_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHDQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -82,7 +82,7 @@ opPUNPCKHDQ_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHDQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -103,7 +103,7 @@ opPUNPCKHDQ_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLBW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -129,7 +129,7 @@ opPUNPCKLBW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLBW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -156,7 +156,7 @@ opPUNPCKLBW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHBW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -182,7 +182,7 @@ opPUNPCKHBW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHBW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -209,7 +209,7 @@ opPUNPCKHBW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLWD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -231,7 +231,7 @@ opPUNPCKLWD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLWD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -254,7 +254,7 @@ opPUNPCKLWD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHWD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -276,7 +276,7 @@ opPUNPCKHWD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHWD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -299,7 +299,7 @@ opPUNPCKHWD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKSSWB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -325,7 +325,7 @@ opPACKSSWB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKSSWB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -352,7 +352,7 @@ opPACKSSWB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKUSWB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -378,7 +378,7 @@ opPACKUSWB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKUSWB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -405,14 +405,14 @@ opPACKUSWB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKSSDW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_REG dst2;
|
||||
MMX_REG dst2;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
|
||||
dst = MMX_GETREGP(cpu_reg);
|
||||
dst = MMX_GETREGP(cpu_reg);
|
||||
dst2 = *dst;
|
||||
|
||||
MMX_GETSRC();
|
||||
@@ -429,14 +429,14 @@ opPACKSSDW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKSSDW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
MMX_REG *dst;
|
||||
MMX_REG dst2;
|
||||
MMX_REG dst2;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
|
||||
dst = MMX_GETREGP(cpu_reg);
|
||||
dst = MMX_GETREGP(cpu_reg);
|
||||
dst2 = *dst;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
static int
|
||||
opPSxxW_imm(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
MMX_REG *dst;
|
||||
|
||||
cpu_state.pc += 2;
|
||||
@@ -67,7 +67,7 @@ static int
|
||||
opPSLLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -94,7 +94,7 @@ static int
|
||||
opPSLLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -122,7 +122,7 @@ static int
|
||||
opPSRLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -149,7 +149,7 @@ static int
|
||||
opPSRLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -177,7 +177,7 @@ static int
|
||||
opPSRAW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -203,7 +203,7 @@ static int
|
||||
opPSRAW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -229,9 +229,9 @@ opPSRAW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSxxD_imm(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
MMX_REG *dst;
|
||||
|
||||
cpu_state.pc += 2;
|
||||
@@ -278,7 +278,7 @@ static int
|
||||
opPSLLD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -303,7 +303,7 @@ static int
|
||||
opPSLLD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -329,7 +329,7 @@ static int
|
||||
opPSRLD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -354,7 +354,7 @@ static int
|
||||
opPSRLD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -380,7 +380,7 @@ static int
|
||||
opPSRAD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -404,7 +404,7 @@ static int
|
||||
opPSRAD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -428,9 +428,9 @@ opPSRAD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSxxQ_imm(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
MMX_REG *dst;
|
||||
|
||||
cpu_state.pc += 2;
|
||||
@@ -474,7 +474,7 @@ static int
|
||||
opPSLLQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -497,7 +497,7 @@ static int
|
||||
opPSLLQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -521,7 +521,7 @@ static int
|
||||
opPSRLQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
@@ -544,7 +544,7 @@ static int
|
||||
opPSRLQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG *dst;
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
|
||||
@@ -769,83 +769,84 @@ opMOV_r_l_a32(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define opCMOV(condition) \
|
||||
static int opCMOV##condition##_w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cond_##condition) { \
|
||||
if (cpu_mod == 3) \
|
||||
cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \
|
||||
else { \
|
||||
uint16_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
|
||||
temp = geteaw(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].w = temp; \
|
||||
} \
|
||||
} \
|
||||
CLOCK_CYCLES(1); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opCMOV##condition##_w_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cond_##condition) { \
|
||||
if (cpu_mod == 3) \
|
||||
cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \
|
||||
else { \
|
||||
uint16_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
|
||||
temp = geteaw(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].w = temp; \
|
||||
} \
|
||||
} \
|
||||
CLOCK_CYCLES(1); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opCMOV##condition##_l_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cond_##condition) { \
|
||||
if (cpu_mod == 3) \
|
||||
cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \
|
||||
else { \
|
||||
uint32_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
temp = geteal(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].l = temp; \
|
||||
} \
|
||||
} \
|
||||
CLOCK_CYCLES(1); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opCMOV##condition##_l_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cond_##condition) { \
|
||||
if (cpu_mod == 3) \
|
||||
cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \
|
||||
else { \
|
||||
uint32_t temp; \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
temp = geteal(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].l = temp; \
|
||||
} \
|
||||
} \
|
||||
CLOCK_CYCLES(1); \
|
||||
return 0; \
|
||||
}
|
||||
#ifndef OPS_286_386
|
||||
# define opCMOV(condition) \
|
||||
static int opCMOV##condition##_w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cond_##condition) { \
|
||||
if (cpu_mod == 3) \
|
||||
cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \
|
||||
else { \
|
||||
uint16_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
|
||||
temp = geteaw(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].w = temp; \
|
||||
} \
|
||||
} \
|
||||
CLOCK_CYCLES(1); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opCMOV##condition##_w_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cond_##condition) { \
|
||||
if (cpu_mod == 3) \
|
||||
cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \
|
||||
else { \
|
||||
uint16_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
|
||||
temp = geteaw(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].w = temp; \
|
||||
} \
|
||||
} \
|
||||
CLOCK_CYCLES(1); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opCMOV##condition##_l_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cond_##condition) { \
|
||||
if (cpu_mod == 3) \
|
||||
cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \
|
||||
else { \
|
||||
uint32_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
temp = geteal(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].l = temp; \
|
||||
} \
|
||||
} \
|
||||
CLOCK_CYCLES(1); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opCMOV##condition##_l_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cond_##condition) { \
|
||||
if (cpu_mod == 3) \
|
||||
cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \
|
||||
else { \
|
||||
uint32_t temp; \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
temp = geteal(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].l = temp; \
|
||||
} \
|
||||
} \
|
||||
CLOCK_CYCLES(1); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
opCMOV(O)
|
||||
@@ -865,3 +866,4 @@ opCMOV(NL)
|
||||
opCMOV(LE)
|
||||
opCMOV(NLE)
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
@@ -251,12 +251,17 @@ opMOV_DRx_r_a32(uint32_t fetchdat)
|
||||
static void
|
||||
opMOV_r_TRx(void)
|
||||
{
|
||||
// uint32_t base;
|
||||
#if 0
|
||||
uint32_t base;
|
||||
|
||||
base = _tr[4] & 0xfffff800;
|
||||
#endif
|
||||
|
||||
// base = _tr[4] & 0xfffff800;
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
// pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
#if 0
|
||||
pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
#endif
|
||||
_tr[3] = *(uint32_t *) &(_cache[cache_index]);
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
@@ -293,42 +298,57 @@ static void
|
||||
opMOV_TRx_r(void)
|
||||
{
|
||||
uint32_t base;
|
||||
int i, ctl;
|
||||
int i;
|
||||
int ctl;
|
||||
|
||||
_tr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
base = _tr[4] & 0xfffff800;
|
||||
ctl = _tr[5] & 3;
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
// pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
#if 0
|
||||
pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
#endif
|
||||
*(uint32_t *) &(_cache[cache_index]) = _tr[3];
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
case 4:
|
||||
// if (!(cr0 & 1) && !(_tr[5] & (1 << 19)))
|
||||
// pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16);
|
||||
#if 0
|
||||
if (!(cr0 & 1) && !(_tr[5] & (1 << 19)))
|
||||
pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16);
|
||||
#endif
|
||||
break;
|
||||
case 5:
|
||||
// pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0);
|
||||
#if 0
|
||||
pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0);
|
||||
#endif
|
||||
if (!(_tr[5] & (1 << 19))) {
|
||||
switch (ctl) {
|
||||
case 0:
|
||||
// pclog(" Cache fill or read...\n", base);
|
||||
#if 0
|
||||
pclog(" Cache fill or read...\n", base);
|
||||
#endif
|
||||
break;
|
||||
case 1:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
// pclog(" Writing 16 bytes to %08X...\n", base);
|
||||
#if 0
|
||||
pclog(" Writing 16 bytes to %08X...\n", base);
|
||||
#endif
|
||||
for (i = 0; i < 16; i += 4)
|
||||
mem_writel_phys(base + i, *(uint32_t *) &(_cache[i]));
|
||||
break;
|
||||
case 2:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
// pclog(" Reading 16 bytes from %08X...\n", base);
|
||||
#if 0
|
||||
pclog(" Reading 16 bytes from %08X...\n", base);
|
||||
#endif
|
||||
for (i = 0; i < 16; i += 4)
|
||||
*(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i);
|
||||
break;
|
||||
case 3:
|
||||
// pclog(" Cache invalidate/flush...\n", base);
|
||||
#if 0
|
||||
pclog(" Cache invalidate/flush...\n", base);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +258,8 @@ opMOV_seg_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opLDS_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
uint16_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
@@ -280,7 +281,8 @@ opLDS_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opLDS_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
uint16_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
@@ -349,7 +351,8 @@ opLDS_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opLSS_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
uint16_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
@@ -371,7 +374,8 @@ opLSS_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opLSS_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
uint16_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
@@ -532,4 +536,4 @@ opLSS_l_a32(uint32_t fetchdat)
|
||||
opLsel(ES, cpu_state.seg_es)
|
||||
opLsel(FS, cpu_state.seg_fs)
|
||||
opLsel(GS, cpu_state.seg_gs)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
@@ -2,7 +2,8 @@ static int
|
||||
opIMUL_w_iw_a16(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
int16_t tempw;
|
||||
int16_t tempw2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -31,7 +32,8 @@ static int
|
||||
opIMUL_w_iw_a32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
int16_t tempw;
|
||||
int16_t tempw2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -61,7 +63,8 @@ static int
|
||||
opIMUL_l_il_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
int32_t templ;
|
||||
int32_t templ2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -90,7 +93,8 @@ static int
|
||||
opIMUL_l_il_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
int32_t templ;
|
||||
int32_t templ2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -120,7 +124,8 @@ static int
|
||||
opIMUL_w_ib_a16(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
int16_t tempw;
|
||||
int16_t tempw2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -151,7 +156,8 @@ static int
|
||||
opIMUL_w_ib_a32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
int16_t tempw;
|
||||
int16_t tempw2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -183,7 +189,8 @@ static int
|
||||
opIMUL_l_ib_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
int32_t templ;
|
||||
int32_t templ2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -214,7 +221,8 @@ static int
|
||||
opIMUL_l_ib_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
int32_t templ;
|
||||
int32_t templ2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
|
||||
@@ -179,10 +179,16 @@ opLAR(w_a16, fetch_ea_16, 0, 0)
|
||||
|
||||
static int op0F00_common(uint32_t fetchdat, int ea32)
|
||||
{
|
||||
int dpl, valid, granularity;
|
||||
uint32_t addr, base, limit;
|
||||
uint16_t desc, sel;
|
||||
uint8_t access, ar_high;
|
||||
int dpl;
|
||||
int valid;
|
||||
int granularity;
|
||||
uint32_t addr;
|
||||
uint32_t base;
|
||||
uint32_t limit;
|
||||
uint16_t desc;
|
||||
uint16_t sel;
|
||||
uint8_t access;
|
||||
uint8_t ar_high;
|
||||
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*SLDT*/
|
||||
@@ -356,7 +362,9 @@ static int
|
||||
op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
{
|
||||
uint32_t base;
|
||||
uint16_t limit, tempw;
|
||||
uint16_t limit;
|
||||
uint16_t tempw;
|
||||
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*SGDT*/
|
||||
if (cpu_mod != 3)
|
||||
|
||||
@@ -88,9 +88,10 @@ op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
static int op_66(uint32_t fetchdat) /*Data size select*/
|
||||
static int
|
||||
op_66(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
|
||||
863
src/cpu/x86_ops_rep_2386.h
Normal file
863
src/cpu/x86_ops_rep_2386.h
Normal file
@@ -0,0 +1,863 @@
|
||||
#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \
|
||||
static int opREP_INSB_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
addr64 = 0x00000000; \
|
||||
\
|
||||
if (CNT_REG > 0) { \
|
||||
uint8_t temp; \
|
||||
\
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX, 1); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
high_page = 0; \
|
||||
do_mmut_wb(es, DEST_REG, &addr64); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
temp = inb(DX); \
|
||||
writememb_n(es, DEST_REG, addr64, temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
DEST_REG--; \
|
||||
else \
|
||||
DEST_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= 15; \
|
||||
reads++; \
|
||||
writes++; \
|
||||
total_cycles += 15; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_INSW_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
addr64a[0] = addr64a[1] = 0x00000000; \
|
||||
\
|
||||
if (CNT_REG > 0) { \
|
||||
uint16_t temp; \
|
||||
\
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX, 2); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
|
||||
high_page = 0; \
|
||||
do_mmut_ww(es, DEST_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
temp = inw(DX); \
|
||||
writememw_n(es, DEST_REG, addr64a, temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
DEST_REG -= 2; \
|
||||
else \
|
||||
DEST_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= 15; \
|
||||
reads++; \
|
||||
writes++; \
|
||||
total_cycles += 15; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_INSL_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \
|
||||
\
|
||||
if (CNT_REG > 0) { \
|
||||
uint32_t temp; \
|
||||
\
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX, 4); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
|
||||
high_page = 0; \
|
||||
do_mmut_wl(es, DEST_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
temp = inl(DX); \
|
||||
writememl_n(es, DEST_REG, addr64a, temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
DEST_REG -= 4; \
|
||||
else \
|
||||
DEST_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= 15; \
|
||||
reads++; \
|
||||
writes++; \
|
||||
total_cycles += 15; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opREP_OUTSB_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
if (CNT_REG > 0) { \
|
||||
uint8_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \
|
||||
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
check_io_perm(DX, 1); \
|
||||
outb(DX, temp); \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG--; \
|
||||
else \
|
||||
SRC_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= 14; \
|
||||
reads++; \
|
||||
writes++; \
|
||||
total_cycles += 14; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_OUTSW_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
if (CNT_REG > 0) { \
|
||||
uint16_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \
|
||||
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
check_io_perm(DX, 2); \
|
||||
outw(DX, temp); \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG -= 2; \
|
||||
else \
|
||||
SRC_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= 14; \
|
||||
reads++; \
|
||||
writes++; \
|
||||
total_cycles += 14; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_OUTSL_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
if (CNT_REG > 0) { \
|
||||
uint32_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \
|
||||
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
check_io_perm(DX, 4); \
|
||||
outl(DX, temp); \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG -= 4; \
|
||||
else \
|
||||
SRC_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= 14; \
|
||||
reads++; \
|
||||
writes++; \
|
||||
total_cycles += 14; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opREP_MOVSB_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
addr64 = addr64_2 = 0x00000000; \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) { \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
} \
|
||||
while (CNT_REG > 0) { \
|
||||
uint8_t temp; \
|
||||
\
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
high_page = 0; \
|
||||
do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
do_mmut_wb(es, DEST_REG, &addr64_2); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
writememb_n(es, DEST_REG, addr64_2, temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
if (cpu_state.flags & D_FLAG) { \
|
||||
DEST_REG--; \
|
||||
SRC_REG--; \
|
||||
} else { \
|
||||
DEST_REG++; \
|
||||
SRC_REG++; \
|
||||
} \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
reads++; \
|
||||
writes++; \
|
||||
total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_MOVSW_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
addr64a[0] = addr64a[1] = 0x00000000; \
|
||||
addr64a_2[0] = addr64a_2[1] = 0x00000000; \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) { \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
} \
|
||||
while (CNT_REG > 0) { \
|
||||
uint16_t temp; \
|
||||
\
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
|
||||
high_page = 0; \
|
||||
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
do_mmut_ww(es, DEST_REG, addr64a_2); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
writememw_n(es, DEST_REG, addr64a_2, temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
if (cpu_state.flags & D_FLAG) { \
|
||||
DEST_REG -= 2; \
|
||||
SRC_REG -= 2; \
|
||||
} else { \
|
||||
DEST_REG += 2; \
|
||||
SRC_REG += 2; \
|
||||
} \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
reads++; \
|
||||
writes++; \
|
||||
total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_MOVSL_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \
|
||||
addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) { \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
} \
|
||||
while (CNT_REG > 0) { \
|
||||
uint32_t temp; \
|
||||
\
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
|
||||
high_page = 0; \
|
||||
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
do_mmut_wl(es, DEST_REG, addr64a_2); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
writememl_n(es, DEST_REG, addr64a_2, temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
if (cpu_state.flags & D_FLAG) { \
|
||||
DEST_REG -= 4; \
|
||||
SRC_REG -= 4; \
|
||||
} else { \
|
||||
DEST_REG += 4; \
|
||||
SRC_REG += 4; \
|
||||
} \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
reads++; \
|
||||
writes++; \
|
||||
total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opREP_STOSB_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
while (CNT_REG > 0) { \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
writememb(es, DEST_REG, AL); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
DEST_REG--; \
|
||||
else \
|
||||
DEST_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; \
|
||||
total_cycles += is486 ? 4 : 5; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_STOSW_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
while (CNT_REG > 0) { \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
|
||||
writememw(es, DEST_REG, AX); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
DEST_REG -= 2; \
|
||||
else \
|
||||
DEST_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; \
|
||||
total_cycles += is486 ? 4 : 5; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_STOSL_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
while (CNT_REG > 0) { \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
|
||||
writememl(es, DEST_REG, EAX); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
DEST_REG -= 4; \
|
||||
else \
|
||||
DEST_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; \
|
||||
total_cycles += is486 ? 4 : 5; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opREP_LODSB_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
while (CNT_REG > 0) { \
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \
|
||||
AL = readmemb(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG--; \
|
||||
else \
|
||||
SRC_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; \
|
||||
total_cycles += is486 ? 4 : 5; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_LODSW_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
while (CNT_REG > 0) { \
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \
|
||||
AX = readmemw(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG -= 2; \
|
||||
else \
|
||||
SRC_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; \
|
||||
total_cycles += is486 ? 4 : 5; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_LODSL_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
while (CNT_REG > 0) { \
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \
|
||||
EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG -= 4; \
|
||||
else \
|
||||
SRC_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; \
|
||||
total_cycles += is486 ? 4 : 5; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \
|
||||
if (CNT_REG > 0) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
#define CHEK_READ(a, b, c)
|
||||
|
||||
#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \
|
||||
static int opREP_CMPSB_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
\
|
||||
addr64 = addr64_2 = 0x00000000; \
|
||||
\
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
uint8_t temp, temp2; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \
|
||||
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
high_page = uncached = 0; \
|
||||
do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
do_mmut_rb2(es, DEST_REG, &addr64_2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
temp2 = readmemb_n(es, DEST_REG, addr64_2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
if (cpu_state.flags & D_FLAG) { \
|
||||
DEST_REG--; \
|
||||
SRC_REG--; \
|
||||
} else { \
|
||||
DEST_REG++; \
|
||||
SRC_REG++; \
|
||||
} \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 7 : 9; \
|
||||
reads += 2; \
|
||||
total_cycles += is486 ? 7 : 9; \
|
||||
setsub8(temp, temp2); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_CMPSW_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
\
|
||||
addr64a[0] = addr64a[1] = 0x00000000; \
|
||||
addr64a_2[0] = addr64a_2[1] = 0x00000000; \
|
||||
\
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
uint16_t temp, temp2; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \
|
||||
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
|
||||
high_page = uncached = 0; \
|
||||
do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
do_mmut_rw2(es, DEST_REG, addr64a_2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
temp2 = readmemw_n(es, DEST_REG, addr64a_2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
if (cpu_state.flags & D_FLAG) { \
|
||||
DEST_REG -= 2; \
|
||||
SRC_REG -= 2; \
|
||||
} else { \
|
||||
DEST_REG += 2; \
|
||||
SRC_REG += 2; \
|
||||
} \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 7 : 9; \
|
||||
reads += 2; \
|
||||
total_cycles += is486 ? 7 : 9; \
|
||||
setsub16(temp, temp2); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_CMPSL_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
\
|
||||
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \
|
||||
addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \
|
||||
\
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
uint32_t temp, temp2; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \
|
||||
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
|
||||
high_page = uncached = 0; \
|
||||
do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
do_mmut_rl2(es, DEST_REG, addr64a_2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
temp2 = readmeml_n(es, DEST_REG, addr64a_2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
if (cpu_state.flags & D_FLAG) { \
|
||||
DEST_REG -= 4; \
|
||||
SRC_REG -= 4; \
|
||||
} else { \
|
||||
DEST_REG += 4; \
|
||||
SRC_REG += 4; \
|
||||
} \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 7 : 9; \
|
||||
reads += 2; \
|
||||
total_cycles += is486 ? 7 : 9; \
|
||||
setsub32(temp, temp2); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opREP_SCASB_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
while ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
uint8_t temp = readmemb(es, DEST_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
setsub8(AL, temp); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
DEST_REG--; \
|
||||
else \
|
||||
DEST_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; \
|
||||
total_cycles += is486 ? 5 : 8; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_SCASW_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
while ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
|
||||
uint16_t temp = readmemw(es, DEST_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
setsub16(AX, temp); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
DEST_REG -= 2; \
|
||||
else \
|
||||
DEST_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; \
|
||||
total_cycles += is486 ? 5 : 8; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_SCASL_##size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
while ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
|
||||
uint32_t temp = readmeml(es, DEST_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
setsub32(EAX, temp); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
DEST_REG -= 4; \
|
||||
else \
|
||||
DEST_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; \
|
||||
total_cycles += is486 ? 5 : 8; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) { \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
REP_OPS(a16, CX, SI, DI)
|
||||
REP_OPS(a32, ECX, ESI, EDI)
|
||||
REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0)
|
||||
REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1)
|
||||
REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0)
|
||||
REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1)
|
||||
|
||||
static int
|
||||
opREPNE(uint32_t fetchdat)
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int
|
||||
opREPE(uint32_t fetchdat)
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
@@ -190,7 +190,9 @@ opIRET(uint32_t fetchdat)
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
if (cr4 & CR4_VME) {
|
||||
uint16_t new_pc, new_cs, new_flags;
|
||||
uint16_t new_pc;
|
||||
uint16_t new_cs;
|
||||
uint16_t new_flags;
|
||||
|
||||
new_pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
|
||||
@@ -36,4 +36,4 @@ opSET(L)
|
||||
opSET(NL)
|
||||
opSET(LE)
|
||||
opSET(NLE)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
@@ -605,7 +605,8 @@ opC0_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
uint8_t temp;
|
||||
uint8_t temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -624,7 +625,8 @@ opC0_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
uint8_t temp;
|
||||
uint8_t temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -643,7 +645,8 @@ opC1_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
uint16_t temp;
|
||||
uint16_t temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -662,7 +665,8 @@ opC1_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
uint16_t temp;
|
||||
uint16_t temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -681,7 +685,8 @@ opC1_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
uint32_t temp;
|
||||
uint32_t temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -700,7 +705,8 @@ opC1_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
uint32_t temp;
|
||||
uint32_t temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -720,7 +726,8 @@ opD0_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
uint8_t temp;
|
||||
uint8_t temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -736,7 +743,8 @@ opD0_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
uint8_t temp;
|
||||
uint8_t temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -752,7 +760,8 @@ opD1_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
uint16_t temp;
|
||||
uint16_t temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -768,7 +777,8 @@ opD1_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
uint16_t temp;
|
||||
uint16_t temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -784,7 +794,8 @@ opD1_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
uint32_t temp;
|
||||
uint32_t temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -800,7 +811,8 @@ opD1_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c = 1;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
uint32_t temp;
|
||||
uint32_t temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -817,7 +829,8 @@ opD2_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
uint8_t temp;
|
||||
uint8_t temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -834,7 +847,8 @@ opD2_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint8_t temp, temp2 = 0;
|
||||
uint8_t temp;
|
||||
uint8_t temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -851,7 +865,8 @@ opD3_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
uint16_t temp;
|
||||
uint16_t temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -868,7 +883,8 @@ opD3_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint16_t temp, temp2 = 0;
|
||||
uint16_t temp;
|
||||
uint16_t temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -885,7 +901,8 @@ opD3_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
uint32_t temp;
|
||||
uint32_t temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -902,7 +919,8 @@ opD3_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int c;
|
||||
int tempc;
|
||||
uint32_t temp, temp2 = 0;
|
||||
uint32_t temp;
|
||||
uint32_t temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
@@ -1053,4 +1071,4 @@ opSHxD(SHLD_w)
|
||||
opSHxD(SHLD_l)
|
||||
opSHxD(SHRD_w)
|
||||
opSHxD(SHRD_l)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
@@ -189,22 +189,50 @@ static int
|
||||
opPOPA_l(uint32_t fetchdat)
|
||||
{
|
||||
if (stack32) {
|
||||
EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1;
|
||||
ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1;
|
||||
EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1;
|
||||
EBX = readmeml(ss, ESP + 16); if (cpu_state.abrt) return 1;
|
||||
EDX = readmeml(ss, ESP + 20); if (cpu_state.abrt) return 1;
|
||||
ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1;
|
||||
EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1;
|
||||
EDI = readmeml(ss, ESP);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
ESI = readmeml(ss, ESP + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
EBP = readmeml(ss, ESP + 8);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
EBX = readmeml(ss, ESP + 16);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
EDX = readmeml(ss, ESP + 20);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
ECX = readmeml(ss, ESP + 24);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
EAX = readmeml(ss, ESP + 28);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
ESP += 32;
|
||||
} else {
|
||||
EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
EDI = readmeml(ss, ((SP) &0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
ESI = readmeml(ss, ((SP + 4) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
EBP = readmeml(ss, ((SP + 8) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
EBX = readmeml(ss, ((SP + 16) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
EDX = readmeml(ss, ((SP + 20) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
ECX = readmeml(ss, ((SP + 24) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
EAX = readmeml(ss, ((SP + 28) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
SP += 32;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 9 : 24);
|
||||
@@ -379,9 +407,13 @@ opENTER_w(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t offset;
|
||||
int count;
|
||||
uint32_t tempEBP, tempESP, frame_ptr;
|
||||
uint32_t tempEBP;
|
||||
uint32_t tempESP;
|
||||
uint32_t frame_ptr;
|
||||
#ifndef IS_DYNAREC
|
||||
int reads = 0, writes = 1, instr_cycles = 0;
|
||||
int reads = 0;
|
||||
int writes = 1;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
uint16_t tempw;
|
||||
|
||||
@@ -448,9 +480,13 @@ opENTER_l(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t offset;
|
||||
int count;
|
||||
uint32_t tempEBP, tempESP, frame_ptr;
|
||||
uint32_t tempEBP;
|
||||
uint32_t tempESP;
|
||||
uint32_t frame_ptr;
|
||||
#ifndef IS_DYNAREC
|
||||
int reads = 0, writes = 1, instr_cycles = 0;
|
||||
int reads = 0;
|
||||
int writes = 1;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
uint32_t templ;
|
||||
|
||||
|
||||
@@ -219,7 +219,8 @@ opMOVSL_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src, dst;
|
||||
uint8_t src;
|
||||
uint8_t dst;
|
||||
|
||||
addr64 = addr64_2 = 0x00000000;
|
||||
|
||||
@@ -259,7 +260,8 @@ opCMPSB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src, dst;
|
||||
uint8_t src;
|
||||
uint8_t dst;
|
||||
|
||||
addr64 = addr64_2 = 0x00000000;
|
||||
|
||||
@@ -300,7 +302,8 @@ opCMPSB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
uint16_t src;
|
||||
uint16_t dst;
|
||||
|
||||
addr64a[0] = addr64a[1] = 0x00000000;
|
||||
addr64a_2[0] = addr64a_2[1] = 0x00000000;
|
||||
@@ -341,7 +344,8 @@ opCMPSW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
uint16_t src;
|
||||
uint16_t dst;
|
||||
|
||||
addr64a[0] = addr64a[1] = 0x00000000;
|
||||
addr64a_2[0] = addr64a_2[1] = 0x00000000;
|
||||
@@ -383,7 +387,8 @@ opCMPSW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
uint32_t src;
|
||||
uint32_t dst;
|
||||
|
||||
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000;
|
||||
addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000;
|
||||
@@ -424,7 +429,8 @@ opCMPSL_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
uint32_t src;
|
||||
uint32_t dst;
|
||||
|
||||
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000;
|
||||
addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000;
|
||||
|
||||
1061
src/cpu/x86_ops_string_2386.h
Normal file
1061
src/cpu/x86_ops_string_2386.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -275,4 +275,4 @@ opBSWAP(ESI)
|
||||
opBSWAP(EDI)
|
||||
opBSWAP(EBP)
|
||||
opBSWAP(ESP)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
194
src/cpu/x86seg.c
194
src/cpu/x86seg.c
@@ -31,13 +31,17 @@
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "386_common.h"
|
||||
|
||||
uint8_t opcode2;
|
||||
|
||||
int cgate16, cgate32;
|
||||
int cgate16;
|
||||
int cgate32;
|
||||
int intgatesize;
|
||||
|
||||
void taskswitch286(uint16_t seg, uint16_t *segdat, int is32);
|
||||
@@ -157,7 +161,7 @@ x86_doabrt(int x86_abrt)
|
||||
}
|
||||
|
||||
void
|
||||
x86de(char *s, uint16_t error)
|
||||
x86de(UNUSED(char *s), UNUSED(uint16_t error))
|
||||
{
|
||||
#ifdef BAD_CODE
|
||||
cpu_state.abrt = ABRT_DE;
|
||||
@@ -168,35 +172,35 @@ x86de(char *s, uint16_t error)
|
||||
}
|
||||
|
||||
void
|
||||
x86gpf(char *s, uint16_t error)
|
||||
x86gpf(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_GPF;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86gpf_expected(char *s, uint16_t error)
|
||||
x86gpf_expected(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86ss(char *s, uint16_t error)
|
||||
x86ss(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_SS;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86ts(char *s, uint16_t error)
|
||||
x86ts(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_TS;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86np(char *s, uint16_t error)
|
||||
x86np(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_NP;
|
||||
abrt_error = error;
|
||||
@@ -272,9 +276,9 @@ do_seg_v86_init(x86seg *s)
|
||||
static void
|
||||
check_seg_valid(x86seg *s)
|
||||
{
|
||||
int dpl = (s->access >> 5) & 3;
|
||||
int valid = 1;
|
||||
x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt;
|
||||
int dpl = (s->access >> 5) & 3;
|
||||
int valid = 1;
|
||||
const x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt;
|
||||
|
||||
if (((s->seg & 0xfff8UL) + 7UL) > dt->limit)
|
||||
valid = 0;
|
||||
@@ -334,10 +338,11 @@ void
|
||||
#endif
|
||||
loadseg(uint16_t seg, x86seg *s)
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr, *segdat32 = (uint32_t *) segdat;
|
||||
int dpl;
|
||||
x86seg *dt;
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
int dpl;
|
||||
const x86seg *dt;
|
||||
|
||||
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) {
|
||||
if (!(seg & 0xfffc)) {
|
||||
@@ -531,9 +536,10 @@ loadseg(uint16_t seg, x86seg *s)
|
||||
void
|
||||
loadcs(uint16_t seg)
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr, *segdat32 = (uint32_t *) segdat;
|
||||
x86seg *dt;
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
const x86seg *dt;
|
||||
|
||||
x86seg_log("Load CS %04X\n", seg);
|
||||
|
||||
@@ -619,11 +625,13 @@ loadcs(uint16_t seg)
|
||||
void
|
||||
loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
{
|
||||
uint16_t type, seg2;
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr, newpc;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
x86seg *dt;
|
||||
uint16_t type;
|
||||
uint16_t seg2;
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
uint32_t newpc;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
const x86seg *dt;
|
||||
|
||||
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) {
|
||||
if (!(seg & 0xfffc)) {
|
||||
@@ -743,7 +751,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc);
|
||||
return;
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
fallthrough;
|
||||
case 0x1c00:
|
||||
case 0x1d00:
|
||||
case 0x1e00:
|
||||
@@ -890,16 +898,24 @@ void
|
||||
loadcscall(uint16_t seg)
|
||||
#endif
|
||||
{
|
||||
uint16_t seg2, newss;
|
||||
uint16_t segdat[4], segdat2[4];
|
||||
uint32_t addr, oldssbase = ss;
|
||||
uint32_t oaddr, newpc;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
int count, type;
|
||||
uint32_t oldss, oldsp, newsp, oldsp2;
|
||||
uint16_t tempw;
|
||||
x86seg *dt;
|
||||
uint16_t seg2;
|
||||
uint16_t newss;
|
||||
uint16_t segdat[4];
|
||||
uint16_t segdat2[4];
|
||||
uint32_t addr;
|
||||
uint32_t oldssbase = ss;
|
||||
uint32_t oaddr;
|
||||
uint32_t newpc;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
int count;
|
||||
int type;
|
||||
uint32_t oldss;
|
||||
uint32_t oldsp;
|
||||
uint32_t newsp;
|
||||
uint32_t oldsp2;
|
||||
uint16_t tempw;
|
||||
const x86seg *dt;
|
||||
|
||||
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) {
|
||||
x86seg_log("Protected mode CS load! %04X\n", seg);
|
||||
@@ -1174,7 +1190,7 @@ loadcscall(uint16_t seg)
|
||||
x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL", seg2 & 0xfffc);
|
||||
return;
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
fallthrough;
|
||||
case 0x1c00:
|
||||
case 0x1d00:
|
||||
case 0x1e00:
|
||||
@@ -1237,12 +1253,18 @@ loadcscall(uint16_t seg)
|
||||
void
|
||||
pmoderetf(int is32, uint16_t off)
|
||||
{
|
||||
uint16_t segdat[4], segdat2[4], seg, newss;
|
||||
uint32_t newpc, newsp, addr, oaddr;
|
||||
uint32_t oldsp = ESP;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
x86seg *dt;
|
||||
uint16_t segdat[4];
|
||||
uint16_t segdat2[4];
|
||||
uint16_t seg;
|
||||
uint16_t newss;
|
||||
uint32_t newpc;
|
||||
uint32_t newsp;
|
||||
uint32_t addr;
|
||||
uint32_t oaddr;
|
||||
uint32_t oldsp = ESP;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
const x86seg *dt;
|
||||
|
||||
x86seg_log("RETF %i %04X:%04X %08X %04X\n", is32, CS, cpu_state.pc, cr0, cpu_state.eflags);
|
||||
if (is32) {
|
||||
@@ -1467,17 +1489,22 @@ pmoderetf(int is32, uint16_t off)
|
||||
void
|
||||
pmodeint(int num, int soft)
|
||||
{
|
||||
uint16_t segdat[4], segdat2[4];
|
||||
uint16_t segdat3[4];
|
||||
uint16_t newss, seg = 0;
|
||||
int type, new_cpl;
|
||||
uint32_t addr, oaddr;
|
||||
uint32_t oldss, oldsp;
|
||||
uint32_t newsp;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
uint32_t *segdat332 = (uint32_t *) segdat3;
|
||||
x86seg *dt;
|
||||
uint16_t segdat[4];
|
||||
uint16_t segdat2[4];
|
||||
uint16_t segdat3[4];
|
||||
uint16_t newss;
|
||||
uint16_t seg = 0;
|
||||
int type;
|
||||
int new_cpl;
|
||||
uint32_t addr;
|
||||
uint32_t oaddr;
|
||||
uint32_t oldss;
|
||||
uint32_t oldsp;
|
||||
uint32_t newsp;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
uint32_t *segdat332 = (uint32_t *) segdat3;
|
||||
const x86seg *dt;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL != 3) && soft) {
|
||||
x86seg_log("V86 banned int\n");
|
||||
@@ -1661,7 +1688,7 @@ pmodeint(int num, int soft)
|
||||
x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
fallthrough;
|
||||
case 0x1c00:
|
||||
case 0x1d00:
|
||||
case 0x1e00:
|
||||
@@ -1750,16 +1777,21 @@ pmodeint(int num, int soft)
|
||||
void
|
||||
pmodeiret(int is32)
|
||||
{
|
||||
uint16_t newss, seg = 0;
|
||||
uint16_t segdat[4], segdat2[4];
|
||||
uint16_t segs[4];
|
||||
uint32_t tempflags, flagmask;
|
||||
uint32_t newpc, newsp;
|
||||
uint32_t addr, oaddr;
|
||||
uint32_t oldsp = ESP;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
x86seg *dt;
|
||||
uint16_t newss;
|
||||
uint16_t seg = 0;
|
||||
uint16_t segdat[4];
|
||||
uint16_t segdat2[4];
|
||||
uint16_t segs[4];
|
||||
uint32_t tempflags;
|
||||
uint32_t flagmask;
|
||||
uint32_t newpc;
|
||||
uint32_t newsp;
|
||||
uint32_t addr;
|
||||
uint32_t oaddr;
|
||||
uint32_t oldsp = ESP;
|
||||
uint32_t *segdat32 = (uint32_t *) segdat;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
const x86seg *dt;
|
||||
|
||||
if (is386 && (cpu_state.eflags & VM_FLAG)) {
|
||||
if (IOPL != 3) {
|
||||
@@ -2058,15 +2090,32 @@ pmodeiret(int is32)
|
||||
void
|
||||
taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
{
|
||||
uint16_t tempw, new_ldt;
|
||||
uint16_t new_es, new_cs, new_ss, new_ds, new_fs, new_gs;
|
||||
uint16_t segdat2[4];
|
||||
uint32_t base, limit;
|
||||
uint32_t templ, new_cr3 = 0;
|
||||
uint32_t new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp;
|
||||
uint32_t new_esi, new_edi, new_pc, new_flags, addr;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
x86seg *dt;
|
||||
uint16_t tempw;
|
||||
uint16_t new_ldt;
|
||||
uint16_t new_es;
|
||||
uint16_t new_cs;
|
||||
uint16_t new_ss;
|
||||
uint16_t new_ds;
|
||||
uint16_t new_fs;
|
||||
uint16_t new_gs;
|
||||
uint16_t segdat2[4];
|
||||
uint32_t base;
|
||||
uint32_t limit;
|
||||
uint32_t templ;
|
||||
uint32_t new_cr3 = 0;
|
||||
uint32_t new_eax;
|
||||
uint32_t new_ebx;
|
||||
uint32_t new_ecx;
|
||||
uint32_t new_edx;
|
||||
uint32_t new_esp;
|
||||
uint32_t new_ebp;
|
||||
uint32_t new_esi;
|
||||
uint32_t new_edi;
|
||||
uint32_t new_pc;
|
||||
uint32_t new_flags;
|
||||
uint32_t addr;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
const x86seg *dt;
|
||||
|
||||
base = segdat[1] | ((segdat[2] & 0x00ff) << 16);
|
||||
limit = segdat[0];
|
||||
@@ -2447,7 +2496,8 @@ cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg)
|
||||
void
|
||||
cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg)
|
||||
{
|
||||
uint16_t segdat[4], selector;
|
||||
uint16_t segdat[4];
|
||||
uint16_t selector;
|
||||
|
||||
segdat[0] = readmemw(0, addr);
|
||||
segdat[1] = readmemw(0, addr + 2);
|
||||
|
||||
207
src/cpu/x87.c
207
src/cpu/x87.c
@@ -17,8 +17,10 @@
|
||||
#include "386_common.h"
|
||||
#include "softfloat/softfloat-specialize.h"
|
||||
|
||||
uint32_t x87_pc_off, x87_op_off;
|
||||
uint16_t x87_pc_seg, x87_op_seg;
|
||||
uint32_t x87_pc_off;
|
||||
uint32_t x87_op_off;
|
||||
uint16_t x87_pc_seg;
|
||||
uint16_t x87_op_seg;
|
||||
|
||||
#ifdef ENABLE_FPU_LOG
|
||||
int fpu_do_log = ENABLE_FPU_LOG;
|
||||
@@ -43,9 +45,8 @@ uint16_t
|
||||
x87_gettag(void)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 8; c++) {
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (cpu_state.tag[c] == TAG_EMPTY)
|
||||
ret |= X87_TAG_EMPTY << (c * 2);
|
||||
else if (cpu_state.tag[c] & TAG_UINT64)
|
||||
@@ -62,9 +63,7 @@ x87_gettag(void)
|
||||
void
|
||||
x87_settag(uint16_t new_tag)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 8; c++) {
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
int tag = (new_tag >> (c * 2)) & 3;
|
||||
|
||||
if (tag == X87_TAG_EMPTY)
|
||||
@@ -106,7 +105,6 @@ x87_settag(uint16_t new_tag)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static floatx80
|
||||
FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct float_status_t *status)
|
||||
{
|
||||
@@ -119,24 +117,27 @@ FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct fl
|
||||
// propagate QNaN to SNaN
|
||||
a = propagateFloatx80NaNOne(a, status);
|
||||
|
||||
if (aIsNaN & !bIsNaN) return a;
|
||||
if (aIsNaN & !bIsNaN)
|
||||
return a;
|
||||
|
||||
// float32 is NaN so conversion will propagate SNaN to QNaN and raise
|
||||
// appropriate exception flags
|
||||
floatx80 b = float32_to_floatx80(b32, status);
|
||||
|
||||
if (aIsSignalingNaN) {
|
||||
if (bIsSignalingNaN) goto returnLargerSignificand;
|
||||
if (bIsSignalingNaN)
|
||||
goto returnLargerSignificand;
|
||||
return bIsNaN ? b : a;
|
||||
}
|
||||
else if (aIsNaN) {
|
||||
if (bIsSignalingNaN) return a;
|
||||
returnLargerSignificand:
|
||||
if (a.fraction < b.fraction) return b;
|
||||
if (b.fraction < a.fraction) return a;
|
||||
} else if (aIsNaN) {
|
||||
if (bIsSignalingNaN)
|
||||
return a;
|
||||
returnLargerSignificand:
|
||||
if (a.fraction < b.fraction)
|
||||
return b;
|
||||
if (b.fraction < a.fraction)
|
||||
return a;
|
||||
return (a.exp < b.exp) ? a : b;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
@@ -152,7 +153,8 @@ FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *stat
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aIsNaN = floatx80_is_nan(a), bIsNaN = float32_is_nan(b);
|
||||
int aIsNaN = floatx80_is_nan(a);
|
||||
int bIsNaN = float32_is_nan(b);
|
||||
if (aIsNaN | bIsNaN) {
|
||||
*r = FPU_handle_NaN32_Func(a, aIsNaN, b, bIsNaN, status);
|
||||
return 1;
|
||||
@@ -172,24 +174,27 @@ FPU_handle_NaN64_Func(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, struct fl
|
||||
// propagate QNaN to SNaN
|
||||
a = propagateFloatx80NaNOne(a, status);
|
||||
|
||||
if (aIsNaN & !bIsNaN) return a;
|
||||
if (aIsNaN & !bIsNaN)
|
||||
return a;
|
||||
|
||||
// float64 is NaN so conversion will propagate SNaN to QNaN and raise
|
||||
// appropriate exception flags
|
||||
floatx80 b = float64_to_floatx80(b64, status);
|
||||
|
||||
if (aIsSignalingNaN) {
|
||||
if (bIsSignalingNaN) goto returnLargerSignificand;
|
||||
if (bIsSignalingNaN)
|
||||
goto returnLargerSignificand;
|
||||
return bIsNaN ? b : a;
|
||||
}
|
||||
else if (aIsNaN) {
|
||||
if (bIsSignalingNaN) return a;
|
||||
returnLargerSignificand:
|
||||
if (a.fraction < b.fraction) return b;
|
||||
if (b.fraction < a.fraction) return a;
|
||||
} else if (aIsNaN) {
|
||||
if (bIsSignalingNaN)
|
||||
return a;
|
||||
returnLargerSignificand:
|
||||
if (a.fraction < b.fraction)
|
||||
return b;
|
||||
if (b.fraction < a.fraction)
|
||||
return a;
|
||||
return (a.exp < b.exp) ? a : b;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
@@ -205,7 +210,8 @@ FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *stat
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aIsNaN = floatx80_is_nan(a), bIsNaN = float64_is_nan(b);
|
||||
int aIsNaN = floatx80_is_nan(a);
|
||||
int bIsNaN = float64_is_nan(b);
|
||||
if (aIsNaN | bIsNaN) {
|
||||
*r = FPU_handle_NaN64_Func(a, aIsNaN, b, bIsNaN, status);
|
||||
return 1;
|
||||
@@ -217,7 +223,7 @@ struct float_status_t
|
||||
i387cw_to_softfloat_status_word(uint16_t control_word)
|
||||
{
|
||||
struct float_status_t status;
|
||||
int precision = control_word & FPU_CW_PC;
|
||||
int precision = control_word & FPU_CW_PC;
|
||||
|
||||
switch (precision) {
|
||||
case FPU_PR_32_BITS:
|
||||
@@ -230,24 +236,23 @@ i387cw_to_softfloat_status_word(uint16_t control_word)
|
||||
status.float_rounding_precision = 80;
|
||||
break;
|
||||
default:
|
||||
/* With the precision control bits set to 01 "(reserved)", a
|
||||
real CPU behaves as if the precision control bits were
|
||||
set to 11 "80 bits" */
|
||||
/* With the precision control bits set to 01 "(reserved)", a
|
||||
real CPU behaves as if the precision control bits were
|
||||
set to 11 "80 bits" */
|
||||
status.float_rounding_precision = 80;
|
||||
break;
|
||||
}
|
||||
|
||||
status.float_exception_flags = 0; // clear exceptions before execution
|
||||
status.float_nan_handling_mode = float_first_operand_nan;
|
||||
status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10;
|
||||
status.flush_underflow_to_zero = 0;
|
||||
status.float_exception_flags = 0; // clear exceptions before execution
|
||||
status.float_nan_handling_mode = float_first_operand_nan;
|
||||
status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10;
|
||||
status.flush_underflow_to_zero = 0;
|
||||
status.float_suppress_exception = 0;
|
||||
status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask;
|
||||
status.denormals_are_zeros = 0;
|
||||
status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask;
|
||||
status.denormals_are_zeros = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FPU_status_word_flags_fpu_compare(int float_relation)
|
||||
{
|
||||
@@ -256,16 +261,16 @@ FPU_status_word_flags_fpu_compare(int float_relation)
|
||||
return (C0 | C2 | C3);
|
||||
|
||||
case float_relation_greater:
|
||||
return (0);
|
||||
return 0;
|
||||
|
||||
case float_relation_less:
|
||||
return (C0);
|
||||
return C0;
|
||||
|
||||
case float_relation_equal:
|
||||
return (C3);
|
||||
return C3;
|
||||
}
|
||||
|
||||
return (-1); // should never get here
|
||||
return (-1); // should never get here
|
||||
}
|
||||
|
||||
void
|
||||
@@ -280,11 +285,11 @@ FPU_write_eflags_fpu_compare(int float_relation)
|
||||
break;
|
||||
|
||||
case float_relation_less:
|
||||
cpu_state.flags |= (C_FLAG);
|
||||
cpu_state.flags |= C_FLAG;
|
||||
break;
|
||||
|
||||
case float_relation_equal:
|
||||
cpu_state.flags |= (Z_FLAG);
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -319,9 +324,9 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store)
|
||||
fpu_state.swd |= exceptions;
|
||||
if (exceptions & FPU_SW_Stack_Fault) {
|
||||
if (!(exceptions & C1)) {
|
||||
/* This bit distinguishes over- from underflow for a stack fault,
|
||||
and roundup from round-down for precision loss. */
|
||||
fpu_state.swd &= ~C1;
|
||||
/* This bit distinguishes over- from underflow for a stack fault,
|
||||
and roundup from round-down for precision loss. */
|
||||
fpu_state.swd &= ~C1;
|
||||
}
|
||||
}
|
||||
return unmasked;
|
||||
@@ -354,8 +359,8 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store)
|
||||
|
||||
if (exceptions & FPU_EX_Precision) {
|
||||
if (!(exceptions & C1)) {
|
||||
/* This bit distinguishes over- from underflow for a stack fault,
|
||||
and roundup from round-down for precision loss. */
|
||||
/* This bit distinguishes over- from underflow for a stack fault,
|
||||
and roundup from round-down for precision loss. */
|
||||
fpu_state.swd &= ~C1;
|
||||
}
|
||||
}
|
||||
@@ -444,14 +449,22 @@ 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;
|
||||
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;
|
||||
}
|
||||
@@ -461,45 +474,45 @@ 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:
|
||||
/* 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 |
|
||||
| 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.
|
||||
*/
|
||||
*
|
||||
* 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) {
|
||||
|
||||
173
src/cpu/x87.h
173
src/cpu/x87.h
@@ -3,8 +3,10 @@
|
||||
#define X87_TAG_INVALID 2
|
||||
#define X87_TAG_EMPTY 3
|
||||
|
||||
extern uint32_t x87_pc_off, x87_op_off;
|
||||
extern uint16_t x87_pc_seg, x87_op_seg;
|
||||
extern uint32_t x87_pc_off;
|
||||
extern uint32_t x87_op_off;
|
||||
extern uint16_t x87_pc_seg;
|
||||
extern uint16_t x87_op_seg;
|
||||
|
||||
static __inline void
|
||||
x87_set_mmx(void)
|
||||
@@ -14,9 +16,9 @@ x87_set_mmx(void)
|
||||
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.TOP = 0;
|
||||
p = (uint64_t *) cpu_state.tag;
|
||||
*p = 0x0101010101010101ULL;
|
||||
}
|
||||
cpu_state.ismmx = 1;
|
||||
}
|
||||
@@ -29,8 +31,8 @@ x87_emms(void)
|
||||
fpu_state.tag = 0xffff;
|
||||
fpu_state.tos = 0; /* reset FPU Top-Of-Stack */
|
||||
} else {
|
||||
p = (uint64_t *) cpu_state.tag;
|
||||
*p = 0;
|
||||
p = (uint64_t *) cpu_state.tag;
|
||||
*p = 0;
|
||||
}
|
||||
cpu_state.ismmx = 0;
|
||||
}
|
||||
@@ -58,81 +60,87 @@ void x87_settag(uint16_t new_tag);
|
||||
void codegen_set_rounding_mode(int mode);
|
||||
|
||||
/* Status Word */
|
||||
#define FPU_SW_Backward (0x8000) /* backward compatibility */
|
||||
#define FPU_SW_C3 (0x4000) /* condition bit 3 */
|
||||
#define FPU_SW_Top (0x3800) /* top of stack */
|
||||
#define FPU_SW_C2 (0x0400) /* condition bit 2 */
|
||||
#define FPU_SW_C1 (0x0200) /* condition bit 1 */
|
||||
#define FPU_SW_C0 (0x0100) /* condition bit 0 */
|
||||
#define FPU_SW_Summary (0x0080) /* exception summary */
|
||||
#define FPU_SW_Stack_Fault (0x0040) /* stack fault */
|
||||
#define FPU_SW_Precision (0x0020) /* loss of precision */
|
||||
#define FPU_SW_Underflow (0x0010) /* underflow */
|
||||
#define FPU_SW_Overflow (0x0008) /* overflow */
|
||||
#define FPU_SW_Zero_Div (0x0004) /* divide by zero */
|
||||
#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */
|
||||
#define FPU_SW_Invalid (0x0001) /* invalid operation */
|
||||
#define FPU_SW_Backward (0x8000) /* backward compatibility */
|
||||
#define FPU_SW_C3 (0x4000) /* condition bit 3 */
|
||||
#define FPU_SW_Top (0x3800) /* top of stack */
|
||||
#define FPU_SW_C2 (0x0400) /* condition bit 2 */
|
||||
#define FPU_SW_C1 (0x0200) /* condition bit 1 */
|
||||
#define FPU_SW_C0 (0x0100) /* condition bit 0 */
|
||||
#define FPU_SW_Summary (0x0080) /* exception summary */
|
||||
#define FPU_SW_Stack_Fault (0x0040) /* stack fault */
|
||||
#define FPU_SW_Precision (0x0020) /* loss of precision */
|
||||
#define FPU_SW_Underflow (0x0010) /* underflow */
|
||||
#define FPU_SW_Overflow (0x0008) /* overflow */
|
||||
#define FPU_SW_Zero_Div (0x0004) /* divide by zero */
|
||||
#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */
|
||||
#define FPU_SW_Invalid (0x0001) /* invalid operation */
|
||||
|
||||
#define C0 (1 << 8)
|
||||
#define C1 (1 << 9)
|
||||
#define C2 (1 << 10)
|
||||
#define C3 (1 << 14)
|
||||
#define C0 (1 << 8)
|
||||
#define C1 (1 << 9)
|
||||
#define C2 (1 << 10)
|
||||
#define C3 (1 << 14)
|
||||
|
||||
#define FPU_SW_CC (C0 | C1 | C2 | C3)
|
||||
#define FPU_SW_CC (C0 | C1 | C2 | C3)
|
||||
|
||||
#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */
|
||||
#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */
|
||||
|
||||
/* Exception flags: */
|
||||
#define FPU_EX_Precision (0x0020) /* loss of precision */
|
||||
#define FPU_EX_Underflow (0x0010) /* underflow */
|
||||
#define FPU_EX_Overflow (0x0008) /* overflow */
|
||||
#define FPU_EX_Zero_Div (0x0004) /* divide by zero */
|
||||
#define FPU_EX_Denormal (0x0002) /* denormalized operand */
|
||||
#define FPU_EX_Invalid (0x0001) /* invalid operation */
|
||||
#define FPU_EX_Precision (0x0020) /* loss of precision */
|
||||
#define FPU_EX_Underflow (0x0010) /* underflow */
|
||||
#define FPU_EX_Overflow (0x0008) /* overflow */
|
||||
#define FPU_EX_Zero_Div (0x0004) /* divide by zero */
|
||||
#define FPU_EX_Denormal (0x0002) /* denormalized operand */
|
||||
#define FPU_EX_Invalid (0x0001) /* invalid operation */
|
||||
|
||||
/* Special exceptions: */
|
||||
#define FPU_EX_Stack_Overflow (0x0041| C1) /* stack overflow */
|
||||
#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */
|
||||
#define FPU_EX_Stack_Overflow (0x0041 | C1) /* stack overflow */
|
||||
#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */
|
||||
|
||||
/* precision control */
|
||||
#define FPU_EX_Precision_Lost_Up (EX_Precision | C1)
|
||||
#define FPU_EX_Precision_Lost_Dn (EX_Precision)
|
||||
#define FPU_EX_Precision_Lost_Up (EX_Precision | C1)
|
||||
#define FPU_EX_Precision_Lost_Dn (EX_Precision)
|
||||
|
||||
#define setcc(cc) \
|
||||
fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) & FPU_SW_CC)
|
||||
#define setcc(cc) \
|
||||
fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) &FPU_SW_CC)
|
||||
|
||||
#define clear_C1() { fpu_state.swd &= ~C1; }
|
||||
#define clear_C2() { fpu_state.swd &= ~C2; }
|
||||
#define clear_C1() \
|
||||
{ \
|
||||
fpu_state.swd &= ~C1; \
|
||||
}
|
||||
#define clear_C2() \
|
||||
{ \
|
||||
fpu_state.swd &= ~C2; \
|
||||
}
|
||||
|
||||
/* ************ */
|
||||
/* Control Word */
|
||||
/* ************ */
|
||||
|
||||
#define FPU_CW_Inf (0x1000) /* infinity control, legacy */
|
||||
#define FPU_CW_Inf (0x1000) /* infinity control, legacy */
|
||||
|
||||
#define FPU_CW_RC (0x0C00) /* rounding control */
|
||||
#define FPU_CW_PC (0x0300) /* precision control */
|
||||
#define FPU_CW_RC (0x0C00) /* rounding control */
|
||||
#define FPU_CW_PC (0x0300) /* precision control */
|
||||
|
||||
#define FPU_RC_RND (0x0000) /* rounding control */
|
||||
#define FPU_RC_DOWN (0x0400)
|
||||
#define FPU_RC_UP (0x0800)
|
||||
#define FPU_RC_CHOP (0x0C00)
|
||||
#define FPU_RC_RND (0x0000) /* rounding control */
|
||||
#define FPU_RC_DOWN (0x0400)
|
||||
#define FPU_RC_UP (0x0800)
|
||||
#define FPU_RC_CHOP (0x0C00)
|
||||
|
||||
#define FPU_CW_Precision (0x0020) /* loss of precision mask */
|
||||
#define FPU_CW_Underflow (0x0010) /* underflow mask */
|
||||
#define FPU_CW_Overflow (0x0008) /* overflow mask */
|
||||
#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */
|
||||
#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */
|
||||
#define FPU_CW_Invalid (0x0001) /* invalid operation mask */
|
||||
#define FPU_CW_Precision (0x0020) /* loss of precision mask */
|
||||
#define FPU_CW_Underflow (0x0010) /* underflow mask */
|
||||
#define FPU_CW_Overflow (0x0008) /* overflow mask */
|
||||
#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */
|
||||
#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */
|
||||
#define FPU_CW_Invalid (0x0001) /* invalid operation mask */
|
||||
|
||||
#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */
|
||||
#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */
|
||||
|
||||
/* Precision control bits affect only the following:
|
||||
ADD, SUB(R), MUL, DIV(R), and SQRT */
|
||||
#define FPU_PR_32_BITS (0x000)
|
||||
#define FPU_PR_RESERVED_BITS (0x100)
|
||||
#define FPU_PR_64_BITS (0x200)
|
||||
#define FPU_PR_80_BITS (0x300)
|
||||
#define FPU_PR_32_BITS (0x000)
|
||||
#define FPU_PR_RESERVED_BITS (0x100)
|
||||
#define FPU_PR_64_BITS (0x200)
|
||||
#define FPU_PR_80_BITS (0x300)
|
||||
|
||||
#include "softfloat/softfloatx80.h"
|
||||
|
||||
@@ -143,16 +151,16 @@ is_IA_masked(void)
|
||||
}
|
||||
|
||||
struct float_status_t i387cw_to_softfloat_status_word(uint16_t control_word);
|
||||
uint16_t FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store);
|
||||
int FPU_status_word_flags_fpu_compare(int float_relation);
|
||||
void FPU_write_eflags_fpu_compare(int float_relation);
|
||||
void FPU_stack_overflow(uint32_t fetchdat);
|
||||
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);
|
||||
uint16_t FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store);
|
||||
int FPU_status_word_flags_fpu_compare(int float_relation);
|
||||
void FPU_write_eflags_fpu_compare(int float_relation);
|
||||
void FPU_stack_overflow(uint32_t fetchdat);
|
||||
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)
|
||||
@@ -179,7 +187,7 @@ static __inline void
|
||||
FPU_settagi_valid(int stnr)
|
||||
{
|
||||
int regnr = (stnr + fpu_state.tos) & 7;
|
||||
fpu_state.tag &= ~(3 << (regnr * 2)); // FPU_Tag_Valid == '00
|
||||
fpu_state.tag &= ~(3 << (regnr * 2)); // FPU_Tag_Valid == '00
|
||||
}
|
||||
|
||||
static __inline void
|
||||
@@ -226,16 +234,15 @@ FPU_save_regi_tag(floatx80 reg, int tag, int stnr)
|
||||
FPU_settagi(tag, stnr);
|
||||
}
|
||||
|
||||
|
||||
#define FPU_check_pending_exceptions() \
|
||||
do { \
|
||||
if (fpu_state.swd & FPU_SW_Summary) { \
|
||||
if (cr0 & 0x20) { \
|
||||
x86_int(16); \
|
||||
return 1; \
|
||||
} else { \
|
||||
picint(1 << 13); \
|
||||
return 1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define FPU_check_pending_exceptions() \
|
||||
do { \
|
||||
if (fpu_state.swd & FPU_SW_Summary) { \
|
||||
if (cr0 & 0x20) { \
|
||||
x86_int(16); \
|
||||
return 1; \
|
||||
} else { \
|
||||
picint(1 << 13); \
|
||||
return 1; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user