mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 09:58:19 -07:00
Merge remote-tracking branch 'upstream/master' into feature/ich2
This commit is contained in:
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: >-
|
||||
|
||||
70
src/86box.c
70
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,26 @@ 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();
|
||||
|
||||
if (joystick_type)
|
||||
gameport_update_joystick_type();
|
||||
/* Reset any ISA RTC cards. */
|
||||
isartc_reset();
|
||||
|
||||
ui_sb_update_panes();
|
||||
|
||||
@@ -1119,6 +1124,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 +1283,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();
|
||||
|
||||
29
src/acpi.c
29
src/acpi.c
@@ -138,29 +138,29 @@ 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));
|
||||
}
|
||||
|
||||
void
|
||||
acpi_raise_smi(void *priv, int do_smi)
|
||||
static void
|
||||
acpi_do_raise_smi(void *priv, int do_smi, int is_apm)
|
||||
{
|
||||
acpi_t *dev = (acpi_t *) priv;
|
||||
|
||||
if (dev->regs.glbctl & 0x01) {
|
||||
if (is_apm || (dev->regs.glbctl & 0x01)) {
|
||||
if ((dev->vendor == VEN_VIA) || (dev->vendor == VEN_VIA_596B)) {
|
||||
if (!dev->regs.smi_lock || !dev->regs.smi_active) {
|
||||
if (do_smi)
|
||||
@@ -183,6 +183,12 @@ acpi_raise_smi(void *priv, int do_smi)
|
||||
smi_raise();
|
||||
}
|
||||
|
||||
void
|
||||
acpi_raise_smi(void *priv, int do_smi)
|
||||
{
|
||||
acpi_do_raise_smi(priv, do_smi, 0);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
acpi_reg_read_common_regs(UNUSED(int size), uint16_t addr, void *priv)
|
||||
{
|
||||
@@ -1841,7 +1847,7 @@ acpi_apm_out(uint16_t port, uint8_t val, void *priv)
|
||||
else if (dev->vendor == VEN_INTEL_ICH2)
|
||||
if (dev->apm->do_smi)
|
||||
dev->regs.smi_sts |= 0x00000020;
|
||||
acpi_raise_smi(dev, dev->apm->do_smi);
|
||||
acpi_do_raise_smi(dev, dev->apm->do_smi, 1);
|
||||
} else
|
||||
dev->apm->stat = val;
|
||||
}
|
||||
@@ -1916,6 +1922,9 @@ acpi_reset(void *priv)
|
||||
dev->regs.pmsts |= 0x8000;
|
||||
|
||||
acpi_rtc_status = 0;
|
||||
|
||||
acpi_update_irq(dev);
|
||||
dev->irq_state = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -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];
|
||||
@@ -671,7 +676,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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -1620,6 +1622,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 +1641,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 +1673,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 +1702,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"
|
||||
@@ -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 %08llx\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) {
|
||||
|
||||
206
src/cpu/386.c
206
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,11 +73,141 @@ 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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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) { \
|
||||
@@ -137,18 +222,13 @@ x386_log(const char *fmt, ...)
|
||||
|
||||
# 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)
|
||||
#endif
|
||||
|
||||
#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;
|
||||
@@ -184,7 +264,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;
|
||||
|
||||
@@ -67,6 +67,38 @@ int soft_reset_mask = 0;
|
||||
int smi_latched = 0;
|
||||
int smm_in_hlt = 0, smi_block = 0;
|
||||
|
||||
int prefetch_prefixes = 0;
|
||||
|
||||
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;
|
||||
|
||||
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, addr64_2;
|
||||
uint32_t addr64a[8], addr64a_2[8];
|
||||
|
||||
@@ -321,6 +353,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)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,34 @@
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#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) 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) 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) 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))))
|
||||
@@ -97,6 +125,7 @@
|
||||
#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,6 +220,23 @@ 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)
|
||||
{
|
||||
@@ -266,6 +312,7 @@ fastreadl(uint32_t a)
|
||||
val |= (fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline void *
|
||||
get_ram_ptr(uint32_t a)
|
||||
@@ -288,6 +335,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)
|
||||
{
|
||||
@@ -342,6 +420,7 @@ fastreadl_fetch(uint32_t a)
|
||||
val |= (fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline uint8_t
|
||||
getbyte(void)
|
||||
@@ -371,6 +450,67 @@ 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)
|
||||
{
|
||||
@@ -489,6 +629,7 @@ seteaq(uint64_t v)
|
||||
*eal_w = v; \
|
||||
else \
|
||||
writememll(easeg + cpu_state.eaaddr, v);
|
||||
#endif
|
||||
|
||||
#define getbytef() \
|
||||
((uint8_t) (fetchdat)); \
|
||||
|
||||
@@ -183,78 +183,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) \
|
||||
@@ -556,7 +484,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 +570,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 */
|
||||
@@ -858,3 +790,156 @@ exec386_dynarec(int cycs)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
exec386(int cycs)
|
||||
{
|
||||
int vector, tempi, cycdiff, oldcyc;
|
||||
int cycle_period, 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
#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,6 +190,7 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#include "x86_ops_jump.h"
|
||||
#include "x86_ops_misc.h"
|
||||
#include "x87_ops.h"
|
||||
#ifndef OPS_286_386
|
||||
#include "x86_ops_i686.h"
|
||||
#include "x86_ops_mmx.h"
|
||||
#include "x86_ops_mmx_arith.h"
|
||||
@@ -196,30 +199,44 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#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"
|
||||
#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
|
||||
#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"
|
||||
#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"
|
||||
#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,50 @@ 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 +436,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 +806,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 +990,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 +1084,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*/
|
||||
@@ -2036,6 +2100,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
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* Copyright 2023 gloriouscow.
|
||||
* Copyright 2023 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@@ -76,7 +77,11 @@ void
|
||||
queue_set_size(size_t size)
|
||||
{
|
||||
if (size > QUEUE_MAX)
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
fatal("Requested prefetch queue of %zu bytes is too big\n", size);
|
||||
#else
|
||||
fatal("Requested prefetch queue of %i bytes is too big\n", size);
|
||||
#endif
|
||||
|
||||
queue.size = size;
|
||||
}
|
||||
|
||||
175
src/cpu/cpu.c
175
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>
|
||||
@@ -125,6 +126,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 };
|
||||
@@ -535,9 +557,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;
|
||||
@@ -599,6 +624,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;
|
||||
@@ -616,6 +658,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
|
||||
@@ -652,6 +711,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
|
||||
@@ -678,6 +754,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:
|
||||
@@ -686,6 +763,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
|
||||
@@ -736,6 +814,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;
|
||||
@@ -751,6 +844,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -793,11 +901,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 */
|
||||
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;
|
||||
@@ -846,6 +956,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;
|
||||
@@ -861,6 +986,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -907,6 +1047,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 */
|
||||
@@ -946,6 +1087,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 */
|
||||
@@ -998,6 +1140,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 */
|
||||
@@ -1611,7 +1754,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) {
|
||||
@@ -1643,9 +1786,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();
|
||||
@@ -2753,6 +2900,10 @@ amd_k_invalid_rdmsr:
|
||||
EAX = msr.ecx1a0 & 0xffffffff;
|
||||
EDX = msr.ecx1a0 >> 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;
|
||||
@@ -3202,6 +3353,9 @@ amd_k_invalid_wrmsr:
|
||||
case 0x1a0:
|
||||
msr.ecx1a0 = 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;
|
||||
@@ -3440,6 +3594,13 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *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,10 +280,11 @@ typedef struct {
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t ecx186; /* 0x00000186, 0x00000187 */
|
||||
uint64_t ecx187; /* 0x00000186, 0x00000187 */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
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
|
||||
@@ -399,8 +400,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;
|
||||
@@ -753,6 +759,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);
|
||||
@@ -836,6 +843,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;
|
||||
|
||||
@@ -860,5 +869,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*/
|
||||
|
||||
@@ -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,7 +187,7 @@ 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
|
||||
|
||||
|
||||
@@ -330,6 +330,113 @@ 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)
|
||||
|
||||
@@ -115,6 +115,7 @@ opCMPXCHG_l_a32(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPS_286_386
|
||||
static int
|
||||
opCMPXCHG8B_a16(uint32_t fetchdat)
|
||||
{
|
||||
@@ -169,6 +170,7 @@ opCMPXCHG8B_a32(uint32_t fetchdat)
|
||||
cycles -= (cpu_mod == 3) ? 6 : 10;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* dest = eab, src = r8 */
|
||||
static int
|
||||
|
||||
@@ -769,6 +769,7 @@ opMOV_r_l_a32(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPS_286_386
|
||||
#define opCMOV(condition) \
|
||||
static int opCMOV##condition##_w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
@@ -865,3 +866,4 @@ opCMOV(NL)
|
||||
opCMOV(LE)
|
||||
opCMOV(NLE)
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
1055
src/cpu/x86_ops_string_2386.h
Normal file
1055
src/cpu/x86_ops_string_2386.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1408,6 +1408,7 @@ const OpFn OP_TABLE(sf_fpu_da_a32)[256] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#ifndef OPS_286_386
|
||||
const OpFn OP_TABLE(sf_fpu_686_da_a16)[256] = {
|
||||
// clang-format off
|
||||
sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16, sf_FADDil_a16,
|
||||
@@ -1487,6 +1488,7 @@ const OpFn OP_TABLE(sf_fpu_686_da_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(sf_fpu_287_db_a16)[256] = {
|
||||
// clang-format off
|
||||
@@ -1648,6 +1650,7 @@ const OpFn OP_TABLE(sf_fpu_db_a32)[256] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#ifndef OPS_286_386
|
||||
const OpFn OP_TABLE(sf_fpu_686_db_a16)[256] = {
|
||||
// clang-format off
|
||||
sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16, sf_FILDil_a16,
|
||||
@@ -1726,6 +1729,7 @@ const OpFn OP_TABLE(sf_fpu_686_db_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(sf_fpu_287_dc_a16)[32] = {
|
||||
// clang-format off
|
||||
@@ -2243,6 +2247,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#ifndef OPS_286_386
|
||||
const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = {
|
||||
// clang-format off
|
||||
sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16, sf_FILDiw_a16,
|
||||
@@ -2322,6 +2327,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(fpu_d8_a16)[32] = {
|
||||
// clang-format off
|
||||
@@ -2661,6 +2667,7 @@ const OpFn OP_TABLE(fpu_da_a32)[256] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#ifndef OPS_286_386
|
||||
const OpFn OP_TABLE(fpu_686_da_a16)[256] = {
|
||||
// clang-format off
|
||||
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
|
||||
@@ -2740,6 +2747,7 @@ const OpFn OP_TABLE(fpu_686_da_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(fpu_287_db_a16)[256] = {
|
||||
// clang-format off
|
||||
@@ -2901,6 +2909,7 @@ const OpFn OP_TABLE(fpu_db_a32)[256] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#ifndef OPS_286_386
|
||||
const OpFn OP_TABLE(fpu_686_db_a16)[256] = {
|
||||
// clang-format off
|
||||
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
|
||||
@@ -2979,6 +2988,7 @@ const OpFn OP_TABLE(fpu_686_db_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(fpu_287_dc_a16)[32] = {
|
||||
// clang-format off
|
||||
@@ -3496,6 +3506,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#ifndef OPS_286_386
|
||||
const OpFn OP_TABLE(fpu_686_df_a16)[256] = {
|
||||
// clang-format off
|
||||
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
|
||||
@@ -3575,6 +3586,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(nofpu_a16)[256] = {
|
||||
// clang-format off
|
||||
|
||||
@@ -242,6 +242,7 @@ opFUCOMPP(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPS_286_386
|
||||
static int
|
||||
opFCOMI(uint32_t fetchdat)
|
||||
{
|
||||
@@ -274,6 +275,7 @@ opFCOMIP(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int
|
||||
opFDIV(uint32_t fetchdat)
|
||||
@@ -476,6 +478,7 @@ opFUCOMP(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPS_286_386
|
||||
static int
|
||||
opFUCOMI(uint32_t fetchdat)
|
||||
{
|
||||
@@ -508,3 +511,4 @@ opFUCOMIP(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1045,6 +1045,7 @@ opFSTCW_a32(uint32_t fetchdat)
|
||||
#endif
|
||||
|
||||
#ifndef FPU_8087
|
||||
#ifndef OPS_286_386
|
||||
# define opFCMOV(condition) \
|
||||
static int opFCMOV##condition(uint32_t fetchdat) \
|
||||
{ \
|
||||
@@ -1073,3 +1074,4 @@ opFCMOV(NBE)
|
||||
opFCMOV(NU)
|
||||
// clang-format on
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -224,6 +224,7 @@ next_ins:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPS_286_386
|
||||
static int
|
||||
sf_FCOMI_st0_stj(uint32_t fetchdat)
|
||||
{
|
||||
@@ -285,6 +286,7 @@ next_ins:
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
sf_FUCOM_sti(uint32_t fetchdat)
|
||||
@@ -346,6 +348,7 @@ next_ins:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPS_286_386
|
||||
static int
|
||||
sf_FUCOMI_st0_stj(uint32_t fetchdat)
|
||||
{
|
||||
@@ -407,6 +410,7 @@ next_ins:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int
|
||||
sf_FTST(uint32_t fetchdat)
|
||||
|
||||
@@ -1279,6 +1279,7 @@ sf_FSTP_sti(uint32_t fetchdat)
|
||||
}
|
||||
|
||||
#ifndef FPU_8087
|
||||
#ifndef OPS_286_386
|
||||
# define sf_FCMOV(condition) \
|
||||
static int sf_FCMOV##condition(uint32_t fetchdat) \
|
||||
{ \
|
||||
@@ -1310,3 +1311,4 @@ sf_FCMOV(NBE)
|
||||
sf_FCMOV(NU)
|
||||
// clang-format on
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -128,6 +128,10 @@ typedef struct atkbc_t {
|
||||
uint8_t channel;
|
||||
uint8_t stat_hi;
|
||||
uint8_t pending;
|
||||
uint8_t irq_state;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
|
||||
uint8_t mem[0x100];
|
||||
|
||||
@@ -347,15 +351,15 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
|
||||
dev->status |= STAT_MFULL;
|
||||
|
||||
if (dev->mem[0x20] & 0x02)
|
||||
picint_common(1 << 12, 0, 1);
|
||||
picint_common(1 << 1, 0, 0);
|
||||
picint_common(1 << 12, 0, 1, NULL);
|
||||
picint_common(1 << 1, 0, 0, NULL);
|
||||
} else {
|
||||
if (dev->mem[0x20] & 0x01)
|
||||
picint_common(1 << 1, 0, 1);
|
||||
picint_common(1 << 12, 0, 0);
|
||||
picint_common(1 << 1, 0, 1, NULL);
|
||||
picint_common(1 << 12, 0, 0, NULL);
|
||||
}
|
||||
} else if (dev->mem[0x20] & 0x01)
|
||||
picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
|
||||
picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
|
||||
|
||||
dev->ob = temp;
|
||||
}
|
||||
@@ -720,10 +724,10 @@ write_p2(atkbc_t *dev, uint8_t val)
|
||||
/* PS/2: Handle IRQ's. */
|
||||
if (dev->misc_flags & FLAG_PS2) {
|
||||
/* IRQ 12 */
|
||||
picint_common(1 << 12, 0, val & 0x20);
|
||||
picint_common(1 << 12, 0, val & 0x20, NULL);
|
||||
|
||||
/* IRQ 1 */
|
||||
picint_common(1 << 1, 0, val & 0x10);
|
||||
picint_common(1 << 1, 0, val & 0x10, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -879,6 +883,9 @@ write64_generic(void *priv, uint8_t val)
|
||||
}
|
||||
break;
|
||||
|
||||
/* TODO: Make this command do nothing on the Regional HT6542,
|
||||
or else, Efflixi's Award OPTi 495 BIOS gets a stuck key
|
||||
in Norton Commander 3.0. */
|
||||
case 0xaf: /* read keyboard version */
|
||||
kbc_at_log("ATkbc: read keyboard version\n");
|
||||
kbc_delay_to_ob(dev, kbc_award_revision, 0, 0x00);
|
||||
@@ -1550,7 +1557,8 @@ kbc_at_process_cmd(void *priv)
|
||||
/* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */
|
||||
dev->p1 = dev->p1 & 0xff;
|
||||
write_p2(dev, 0x4b);
|
||||
picintc(0x1002);
|
||||
picintc(0x1000);
|
||||
picintc(0x0002);
|
||||
}
|
||||
|
||||
dev->status = (dev->status & 0x0f) | 0x60;
|
||||
@@ -1569,7 +1577,8 @@ kbc_at_process_cmd(void *priv)
|
||||
/* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */
|
||||
dev->p1 = dev->p1 & 0xff;
|
||||
write_p2(dev, 0xcf);
|
||||
picintc(0x0002);
|
||||
picintclevel(0x0002, &dev->irq_state);
|
||||
dev->irq_state = 0;
|
||||
}
|
||||
|
||||
dev->status = (dev->status & 0x0f) | 0x60;
|
||||
@@ -1852,7 +1861,7 @@ kbc_at_read(uint16_t port, void *priv)
|
||||
/* TODO: IRQ is only tied to OBF on the AT KBC, on the PS/2 KBC, it is controlled by a P2 bit.
|
||||
This also means that in AT mode, the IRQ is level-triggered. */
|
||||
if (!(dev->misc_flags & FLAG_PS2))
|
||||
picintc(1 << 1);
|
||||
picintclevel(1 << 1, &dev->irq_state);
|
||||
break;
|
||||
|
||||
case 0x64:
|
||||
@@ -1901,8 +1910,13 @@ kbc_at_reset(void *priv)
|
||||
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
|
||||
dev->misc_flags |= FLAG_PS2;
|
||||
kbc_at_do_poll = kbc_at_poll_ps2;
|
||||
} else
|
||||
picintc(0x1000);
|
||||
picintc(0x0002);
|
||||
} else {
|
||||
kbc_at_do_poll = kbc_at_poll_at;
|
||||
picintclevel(0x0002, &dev->irq_state);
|
||||
dev->irq_state = 0;
|
||||
}
|
||||
|
||||
dev->misc_flags |= FLAG_CACHE;
|
||||
|
||||
@@ -1924,8 +1938,6 @@ kbc_at_close(void *priv)
|
||||
atkbc_t *dev = (atkbc_t *) priv;
|
||||
int max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1;
|
||||
|
||||
kbc_at_reset(dev);
|
||||
|
||||
/* Stop timers. */
|
||||
timer_disable(&dev->send_delay_timer);
|
||||
|
||||
|
||||
@@ -167,6 +167,12 @@ keyboard_input(int down, uint16_t scan)
|
||||
case 0x138: /* Right Alt */
|
||||
shift |= 0x40;
|
||||
break;
|
||||
case 0x15b: /* Left Windows */
|
||||
shift |= 0x08;
|
||||
break;
|
||||
case 0x15c: /* Right Windows */
|
||||
shift |= 0x80;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -191,6 +197,12 @@ keyboard_input(int down, uint16_t scan)
|
||||
case 0x138: /* Right Alt */
|
||||
shift &= ~0x40;
|
||||
break;
|
||||
case 0x15b: /* Left Windows */
|
||||
shift &= ~0x08;
|
||||
break;
|
||||
case 0x15c: /* Right Windows */
|
||||
shift &= ~0x80;
|
||||
break;
|
||||
case 0x03a: /* Caps Lock */
|
||||
caps_lock ^= 1;
|
||||
break;
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017-2018 Fred N. van Kempen.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -37,17 +39,22 @@ typedef struct mouse_t {
|
||||
} mouse_t;
|
||||
|
||||
int mouse_type = 0;
|
||||
int mouse_x;
|
||||
int mouse_y;
|
||||
int mouse_z;
|
||||
int mouse_buttons;
|
||||
atomic_int mouse_x;
|
||||
atomic_int mouse_y;
|
||||
atomic_int mouse_z;
|
||||
atomic_int mouse_buttons;
|
||||
int mouse_mode;
|
||||
int mouse_timed = 1;
|
||||
int mouse_tablet_in_proximity = 0;
|
||||
int tablet_tool_type = 1; /* 0 = Puck/Cursor, 1 = Pen */
|
||||
|
||||
double mouse_x_abs;
|
||||
double mouse_y_abs;
|
||||
|
||||
double mouse_sensitivity = 1.0;
|
||||
double mouse_x_error = 0.0;
|
||||
double mouse_y_error = 0.0;
|
||||
|
||||
pc_timer_t mouse_timer; /* mouse event timer */
|
||||
|
||||
static const device_t mouse_none_device = {
|
||||
@@ -155,22 +162,80 @@ mouse_close(void)
|
||||
static void
|
||||
mouse_timer_poll(UNUSED(void *priv))
|
||||
{
|
||||
/* Poll at 255 Hz, maximum supported by PS/2 mic. */
|
||||
/* Poll at the specified sample rate. */
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
|
||||
|
||||
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
|
||||
if (gdbstub_step == GDBSTUB_EXEC)
|
||||
if (gdbstub_step == GDBSTUB_EXEC) {
|
||||
#endif
|
||||
mouse_process();
|
||||
if (mouse_timed)
|
||||
mouse_process();
|
||||
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mouse_scale(int x, int y)
|
||||
{
|
||||
double scaled_x = (((double) x) * mouse_sensitivity) + mouse_x_error;
|
||||
double scaled_y = (((double) y) * mouse_sensitivity) + mouse_y_error;
|
||||
|
||||
mouse_x += (int) scaled_x;
|
||||
mouse_y += (int) scaled_y;
|
||||
|
||||
mouse_x_error = scaled_x - floor(scaled_x);
|
||||
mouse_y_error = scaled_y - floor(scaled_y);
|
||||
}
|
||||
|
||||
void
|
||||
mouse_scale_x(int x)
|
||||
{
|
||||
double scaled_x = ((double) x) * mouse_sensitivity + mouse_x_error;
|
||||
|
||||
mouse_x += (int) scaled_x;
|
||||
|
||||
mouse_x_error = scaled_x - ((double) mouse_x);
|
||||
}
|
||||
|
||||
void
|
||||
mouse_scale_y(int y)
|
||||
{
|
||||
double scaled_y = ((double) y) * mouse_sensitivity + mouse_y_error;
|
||||
|
||||
mouse_y += (int) scaled_y;
|
||||
|
||||
mouse_y_error = scaled_y - ((double) mouse_y);
|
||||
}
|
||||
|
||||
void
|
||||
mouse_set_z(int z)
|
||||
{
|
||||
mouse_z += z;
|
||||
}
|
||||
|
||||
void
|
||||
mouse_set_buttons_ex(int b)
|
||||
{
|
||||
mouse_buttons = b;
|
||||
}
|
||||
|
||||
int
|
||||
mouse_get_buttons_ex(void)
|
||||
{
|
||||
return mouse_buttons;
|
||||
}
|
||||
|
||||
void
|
||||
mouse_set_sample_rate(double new_rate)
|
||||
{
|
||||
mouse_timed = (new_rate > 0.0);
|
||||
|
||||
timer_stop(&mouse_timer);
|
||||
|
||||
sample_rate = new_rate;
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
|
||||
if (mouse_timed)
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / sample_rate);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -186,6 +251,9 @@ mouse_reset(void)
|
||||
mouse_x = mouse_y = mouse_z = 0;
|
||||
mouse_buttons = 0x00;
|
||||
mouse_mode = 0;
|
||||
mouse_timed = 1;
|
||||
|
||||
mouse_x_error = mouse_y_error = 0.0;
|
||||
|
||||
/* If no mouse configured, we're done. */
|
||||
if (mouse_type == 0)
|
||||
@@ -222,19 +290,14 @@ mouse_process(void)
|
||||
if (mouse_curr == NULL)
|
||||
return;
|
||||
|
||||
if (mouse_poll_ex)
|
||||
if ((mouse_mode >= 1) && mouse_poll_ex)
|
||||
mouse_poll_ex();
|
||||
else
|
||||
mouse_poll();
|
||||
|
||||
if ((mouse_dev_poll != NULL) || (mouse_curr->poll != NULL)) {
|
||||
if (mouse_curr->poll != NULL)
|
||||
mouse_curr->poll(mouse_x, mouse_y, mouse_z, mouse_buttons, mouse_x_abs, mouse_y_abs, mouse_priv);
|
||||
else
|
||||
mouse_dev_poll(mouse_x, mouse_y, mouse_z, mouse_buttons, mouse_priv);
|
||||
|
||||
/* Reset mouse deltas. */
|
||||
mouse_x = mouse_y = mouse_z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -80,6 +81,7 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mouse.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/random.h>
|
||||
|
||||
@@ -147,8 +149,6 @@ typedef struct mouse {
|
||||
int irq;
|
||||
int bn;
|
||||
int flags;
|
||||
int mouse_delayed_dx;
|
||||
int mouse_delayed_dy;
|
||||
int mouse_buttons;
|
||||
int mouse_buttons_last;
|
||||
int toggle_counter;
|
||||
@@ -480,10 +480,13 @@ bm_poll(int x, int y, UNUSED(int z), int b, UNUSED(double abs_x), UNUSED(double
|
||||
mouse_t *dev = (mouse_t *) priv;
|
||||
int xor ;
|
||||
|
||||
if (!mouse_capture && !video_fullscreen)
|
||||
return 1;
|
||||
|
||||
if (!(dev->flags & FLAG_ENABLED))
|
||||
return 1; /* Mouse is disabled, do nothing. */
|
||||
|
||||
if (!x && !y && !((b ^ dev->mouse_buttons_last) & 0x07)) {
|
||||
if (!mouse_x && !mouse_y && !((b ^ dev->mouse_buttons_last) & 0x07)) {
|
||||
dev->mouse_buttons_last = b;
|
||||
return 1; /* State has not changed, do nothing. */
|
||||
}
|
||||
@@ -498,7 +501,7 @@ bm_poll(int x, int y, UNUSED(int z), int b, UNUSED(double abs_x), UNUSED(double
|
||||
so update bits 6-3 here. */
|
||||
|
||||
/* If the mouse has moved, set bit 6. */
|
||||
if (x || y)
|
||||
if (mouse_x || mouse_y)
|
||||
dev->mouse_buttons |= 0x40;
|
||||
|
||||
/* Set bits 3-5 according to button state changes. */
|
||||
@@ -508,26 +511,30 @@ bm_poll(int x, int y, UNUSED(int z), int b, UNUSED(double abs_x), UNUSED(double
|
||||
|
||||
dev->mouse_buttons_last = b;
|
||||
|
||||
/* Clamp x and y to between -128 and 127 (int8_t range). */
|
||||
if (x > 127)
|
||||
x = 127;
|
||||
if (x < -128)
|
||||
x = -128;
|
||||
|
||||
if (y > 127)
|
||||
y = 127;
|
||||
if (y < -128)
|
||||
y = -128;
|
||||
|
||||
if (dev->timer_enabled) {
|
||||
/* Update delayed coordinates. */
|
||||
dev->mouse_delayed_dx += x;
|
||||
dev->mouse_delayed_dy += y;
|
||||
} else {
|
||||
if (!dev->timer_enabled) {
|
||||
/* If the counters are not frozen, update them. */
|
||||
if (!(dev->flags & FLAG_HOLD)) {
|
||||
dev->current_x = (int8_t) x;
|
||||
dev->current_y = (int8_t) y;
|
||||
if (mouse_x > 127) {
|
||||
dev->current_x = 127;
|
||||
mouse_x -= 127;
|
||||
} else if (mouse_x < 1-128) {
|
||||
dev->current_x = -128;
|
||||
mouse_x += 128;
|
||||
} else {
|
||||
dev->current_x = mouse_x;
|
||||
mouse_x = 0;
|
||||
}
|
||||
|
||||
if (mouse_y > 127) {
|
||||
dev->current_y = 127;
|
||||
mouse_y -= 127;
|
||||
} else if (mouse_y < 1-128) {
|
||||
dev->current_y = -128;
|
||||
mouse_y += 128;
|
||||
} else {
|
||||
dev->current_y = mouse_y;
|
||||
mouse_y = 0;
|
||||
}
|
||||
|
||||
dev->current_b = dev->mouse_buttons;
|
||||
}
|
||||
@@ -538,6 +545,7 @@ bm_poll(int x, int y, UNUSED(int z), int b, UNUSED(double abs_x), UNUSED(double
|
||||
bm_log("DEBUG: Data Interrupt Fired...\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -548,31 +556,31 @@ bm_update_data(mouse_t *dev)
|
||||
{
|
||||
int delta_x;
|
||||
int delta_y;
|
||||
int xor ;
|
||||
int xor;
|
||||
|
||||
/* If the counters are not frozen, update them. */
|
||||
if (!(dev->flags & FLAG_HOLD)) {
|
||||
if ((mouse_capture || video_fullscreen) && !(dev->flags & FLAG_HOLD)) {
|
||||
/* Update the deltas and the delays. */
|
||||
if (dev->mouse_delayed_dx > 127) {
|
||||
if (mouse_x > 127) {
|
||||
delta_x = 127;
|
||||
dev->mouse_delayed_dx -= 127;
|
||||
} else if (dev->mouse_delayed_dx < -128) {
|
||||
mouse_x -= 127;
|
||||
} else if (mouse_x < -128) {
|
||||
delta_x = -128;
|
||||
dev->mouse_delayed_dx += 128;
|
||||
mouse_x += 128;
|
||||
} else {
|
||||
delta_x = dev->mouse_delayed_dx;
|
||||
dev->mouse_delayed_dx = 0;
|
||||
delta_x = mouse_x;
|
||||
mouse_x = 0;
|
||||
}
|
||||
|
||||
if (dev->mouse_delayed_dy > 127) {
|
||||
if (mouse_y > 127) {
|
||||
delta_y = 127;
|
||||
dev->mouse_delayed_dy -= 127;
|
||||
} else if (dev->mouse_delayed_dy < -128) {
|
||||
mouse_y -= 127;
|
||||
} else if (mouse_y < -128) {
|
||||
delta_y = -128;
|
||||
dev->mouse_delayed_dy += 128;
|
||||
mouse_y += 128;
|
||||
} else {
|
||||
delta_y = dev->mouse_delayed_dy;
|
||||
dev->mouse_delayed_dy = 0;
|
||||
delta_y = mouse_y;
|
||||
mouse_y = 0;
|
||||
}
|
||||
|
||||
dev->current_x = (int8_t) delta_x;
|
||||
@@ -659,8 +667,6 @@ bm_init(const device_t *info)
|
||||
}
|
||||
mouse_set_buttons(dev->bn);
|
||||
|
||||
dev->mouse_delayed_dx = 0;
|
||||
dev->mouse_delayed_dy = 0;
|
||||
dev->mouse_buttons = 0;
|
||||
dev->mouse_buttons_last = 0;
|
||||
dev->sig_val = 0; /* the signature port value */
|
||||
@@ -707,6 +713,8 @@ bm_init(const device_t *info)
|
||||
else
|
||||
bm_log("Standard MS/Logitech BusMouse initialized\n");
|
||||
|
||||
mouse_set_sample_rate(0.0);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -23,6 +24,7 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/mouse.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
enum {
|
||||
@@ -75,40 +77,51 @@ ps2_report_coordinates(atkbc_dev_t *dev, int main)
|
||||
uint8_t buff[3] = { 0x08, 0x00, 0x00 };
|
||||
int temp_z;
|
||||
|
||||
if (dev->x > 255) {
|
||||
dev->x = 255;
|
||||
if (mouse_x > 255) {
|
||||
buff[0] |= 0x40;
|
||||
buff[1] = 255;
|
||||
mouse_x -= 255;
|
||||
} else if (mouse_x < -256) {
|
||||
buff[0] |= (0x40 | 0x10);
|
||||
mouse_x += 256;
|
||||
} else {
|
||||
if (mouse_x < 0)
|
||||
buff[0] |= 0x10;
|
||||
buff[1] = mouse_x;
|
||||
mouse_x = 0;
|
||||
}
|
||||
if (dev->x < -256) {
|
||||
dev->x = -256;
|
||||
buff[0] |= 0x40;
|
||||
}
|
||||
if (dev->y > 255) {
|
||||
dev->y = 255;
|
||||
buff[0] |= 0x80;
|
||||
}
|
||||
if (dev->y < -256) {
|
||||
dev->y = -256;
|
||||
buff[0] |= 0x80;
|
||||
}
|
||||
if (dev->z < -8)
|
||||
dev->z = -8;
|
||||
if (dev->z > 7)
|
||||
dev->z = 7;
|
||||
|
||||
if (dev->x < 0)
|
||||
buff[0] |= 0x10;
|
||||
if (dev->y < 0)
|
||||
buff[0] |= 0x20;
|
||||
buff[0] |= (dev->b & ((dev->flags & FLAG_INTELLI) ? 0x07 : 0x03));
|
||||
buff[1] = (dev->x & 0xff);
|
||||
buff[2] = (dev->y & 0xff);
|
||||
if (mouse_y < -255) {
|
||||
buff[0] |= 0x80;
|
||||
buff[2] = 255;
|
||||
mouse_y += 255;
|
||||
} else if (mouse_y > 256) {
|
||||
buff[0] |= (0x80 | 0x20);
|
||||
mouse_y -= 256;
|
||||
} else {
|
||||
if (mouse_y > 0)
|
||||
buff[0] |= 0x20;
|
||||
buff[2] = -mouse_y;
|
||||
mouse_y = 0;
|
||||
}
|
||||
|
||||
if (dev->z < -7) {
|
||||
temp_z = 7;
|
||||
temp_z += 7;
|
||||
} else if (mouse_z > 8) {
|
||||
temp_z = (-8) & 0x0f;
|
||||
mouse_z -= 8;
|
||||
} else {
|
||||
temp_z = (-mouse_y) & 0x0f;
|
||||
mouse_z = 0;
|
||||
}
|
||||
|
||||
buff[0] |= (mouse_buttons & ((dev->flags & FLAG_INTELLI) ? 0x07 : 0x03));
|
||||
|
||||
kbc_at_dev_queue_add(dev, buff[0], main);
|
||||
kbc_at_dev_queue_add(dev, buff[1], main);
|
||||
kbc_at_dev_queue_add(dev, buff[2], main);
|
||||
if (dev->flags & FLAG_INTMODE) {
|
||||
temp_z = dev->z & 0x0f;
|
||||
if (dev->flags & FLAG_5BTN) {
|
||||
if (mouse_buttons & 8)
|
||||
temp_z |= 0x10;
|
||||
@@ -121,8 +134,6 @@ ps2_report_coordinates(atkbc_dev_t *dev, int main)
|
||||
}
|
||||
kbc_at_dev_queue_add(dev, temp_z, main);
|
||||
}
|
||||
|
||||
dev->x = dev->y = dev->z = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -132,7 +143,7 @@ ps2_set_defaults(atkbc_dev_t *dev)
|
||||
dev->rate = 100;
|
||||
mouse_set_sample_rate(100.0);
|
||||
dev->resolution = 2;
|
||||
dev->flags &= 0x88;
|
||||
dev->flags &= 0x188;
|
||||
mouse_scan = 0;
|
||||
}
|
||||
|
||||
@@ -316,25 +327,17 @@ ps2_poll(int x, int y, int z, int b, UNUSED(double abs_x), UNUSED(double abs_y),
|
||||
atkbc_dev_t *dev = (atkbc_dev_t *) priv;
|
||||
int packet_size = (dev->flags & FLAG_INTMODE) ? 4 : 3;
|
||||
|
||||
if (!mouse_scan || (!x && !y && !z && (b == dev->b)))
|
||||
return 0xff;
|
||||
int cond = (!mouse_capture && !video_fullscreen) || (!mouse_scan || (!x && !y && !z && (b == dev->b))) ||
|
||||
((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) >= (FIFO_SIZE - packet_size)));
|
||||
|
||||
if ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size))) {
|
||||
dev->x = x;
|
||||
dev->y = -y;
|
||||
dev->z = -z;
|
||||
dev->b = b;
|
||||
} else {
|
||||
dev->x += x;
|
||||
dev->y -= y;
|
||||
dev->z -= z;
|
||||
if (!cond) {
|
||||
dev->b = b;
|
||||
|
||||
if (dev->mode == MODE_STREAM)
|
||||
ps2_report_coordinates(dev, 1);
|
||||
}
|
||||
|
||||
if ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size)))
|
||||
ps2_report_coordinates(dev, 1);
|
||||
|
||||
return 0;
|
||||
return cond;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,7 +56,7 @@ typedef struct pci_bridge_t {
|
||||
|
||||
uint8_t regs[256];
|
||||
uint8_t bus_index;
|
||||
int slot;
|
||||
uint8_t slot;
|
||||
} pci_bridge_t;
|
||||
|
||||
#ifdef ENABLE_PCI_BRIDGE_LOG
|
||||
@@ -552,7 +552,10 @@ pci_bridge_init(const device_t *info)
|
||||
|
||||
pci_bridge_reset(dev);
|
||||
|
||||
dev->slot = pci_add_card(AGP_BRIDGE(dev->local) ? PCI_ADD_AGPBRIDGE : PCI_ADD_BRIDGE, pci_bridge_read, pci_bridge_write, dev);
|
||||
if (AGP_BRIDGE(dev->local))
|
||||
pci_add_card(PCI_ADD_AGPBRIDGE, pci_bridge_read, pci_bridge_write, dev, &dev->slot);
|
||||
else
|
||||
dev->slot = pci_add_bridge(pci_bridge_read, pci_bridge_write, dev);
|
||||
|
||||
if ((info->local != PCI_BRIDGE_INTEL_ICH2) && (info->local != AGP_BRIDGE_INTEL_815EP)) { /* Let the machine configuration slot handle the absurd interrupt tables */
|
||||
interrupt_count = sizeof(interrupts);
|
||||
|
||||
@@ -29,10 +29,14 @@
|
||||
#include <86box/postcard.h>
|
||||
#include "cpu.h"
|
||||
|
||||
#define POSTCARDS_NUM 4
|
||||
#define POSTCARD_MASK (POSTCARDS_NUM - 1)
|
||||
|
||||
static uint16_t postcard_port;
|
||||
static uint8_t postcard_written;
|
||||
static uint8_t postcard_code;
|
||||
static uint8_t postcard_prev_code;
|
||||
static uint8_t postcard_written[POSTCARDS_NUM];
|
||||
static uint8_t postcard_ports_num = 1;
|
||||
static uint8_t postcard_codes[POSTCARDS_NUM];
|
||||
static uint8_t postcard_prev_codes[POSTCARDS_NUM];
|
||||
#define UISTR_LEN 13
|
||||
static char postcard_str[UISTR_LEN]; /* UI output string */
|
||||
|
||||
@@ -61,12 +65,46 @@ int postcard_do_log = 0;
|
||||
static void
|
||||
postcard_setui(void)
|
||||
{
|
||||
if (!postcard_written)
|
||||
sprintf(postcard_str, "POST: -- --");
|
||||
else if (postcard_written == 1)
|
||||
sprintf(postcard_str, "POST: %02X --", postcard_code);
|
||||
else
|
||||
sprintf(postcard_str, "POST: %02X %02X", postcard_code, postcard_prev_code);
|
||||
if (postcard_ports_num > 1) {
|
||||
char ps[2][POSTCARDS_NUM][64] = { { 0 },
|
||||
{ 0 } };
|
||||
for (uint8_t i = 0; i < POSTCARDS_NUM; i++) {
|
||||
if (!postcard_written[i]) {
|
||||
sprintf(ps[0][i], "--");
|
||||
sprintf(ps[1][i], "--");
|
||||
} else if (postcard_written[i] == 1) {
|
||||
sprintf(ps[0][i], "%02X", postcard_codes[i]);
|
||||
sprintf(ps[1][i], "--");
|
||||
} else {
|
||||
sprintf(ps[0][i], "%02X", postcard_codes[i]);
|
||||
sprintf(ps[1][i], "%02X", postcard_prev_codes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
switch (postcard_ports_num) {
|
||||
default:
|
||||
case 2:
|
||||
sprintf(postcard_str, "POST: %s%s %s%s",
|
||||
ps[0][0], ps[0][1], ps[1][0], ps[1][1]);
|
||||
break;
|
||||
case 3:
|
||||
sprintf(postcard_str, "POST: %s/%s%s %s/%s%s",
|
||||
ps[0][0], ps[0][1], ps[0][2], ps[1][0], ps[1][1], ps[1][2]);
|
||||
break;
|
||||
case 4:
|
||||
sprintf(postcard_str, "POST: %s%s/%s%s %s%s/%s%s",
|
||||
ps[0][0], ps[0][1], ps[0][2], ps[0][3],
|
||||
ps[1][0], ps[1][1], ps[1][2], ps[1][3]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!postcard_written[0])
|
||||
sprintf(postcard_str, "POST: -- --");
|
||||
else if (postcard_written[0] == 1)
|
||||
sprintf(postcard_str, "POST: %02X --", postcard_codes[0]);
|
||||
else
|
||||
sprintf(postcard_str, "POST: %02X %02X", postcard_codes[0], postcard_prev_codes[0]);
|
||||
}
|
||||
|
||||
ui_sb_bugui(postcard_str);
|
||||
|
||||
@@ -79,22 +117,27 @@ postcard_setui(void)
|
||||
static void
|
||||
postcard_reset(void)
|
||||
{
|
||||
postcard_written = 0;
|
||||
postcard_code = postcard_prev_code = 0x00;
|
||||
memset(postcard_written, 0x00, POSTCARDS_NUM * sizeof(uint8_t));
|
||||
|
||||
memset(postcard_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t));
|
||||
memset(postcard_prev_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t));
|
||||
|
||||
postcard_setui();
|
||||
}
|
||||
|
||||
static void
|
||||
postcard_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv))
|
||||
postcard_write(uint16_t port, uint8_t val, UNUSED(void *priv))
|
||||
{
|
||||
if (postcard_written && (val == postcard_code))
|
||||
uint8_t matches = 0;
|
||||
|
||||
if (postcard_written[port & POSTCARD_MASK] &&
|
||||
(val == postcard_codes[port & POSTCARD_MASK]))
|
||||
return;
|
||||
|
||||
postcard_prev_code = postcard_code;
|
||||
postcard_code = val;
|
||||
if (postcard_written < 2)
|
||||
postcard_written++;
|
||||
postcard_prev_codes[port & POSTCARD_MASK] = postcard_codes[port & POSTCARD_MASK];
|
||||
postcard_codes[port & POSTCARD_MASK] = val;
|
||||
if (postcard_written[port & POSTCARD_MASK] < 2)
|
||||
postcard_written[port & POSTCARD_MASK]++;
|
||||
|
||||
postcard_setui();
|
||||
}
|
||||
@@ -102,7 +145,7 @@ postcard_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv))
|
||||
static void *
|
||||
postcard_init(UNUSED(const device_t *info))
|
||||
{
|
||||
postcard_reset();
|
||||
postcard_ports_num = 1;
|
||||
|
||||
if (machine_has_bus(machine, MACHINE_BUS_MCA))
|
||||
postcard_port = 0x680; /* MCA machines */
|
||||
@@ -110,16 +153,21 @@ postcard_init(UNUSED(const device_t *info))
|
||||
postcard_port = 0x190; /* ISA PS/2 machines */
|
||||
else if (strstr(machines[machine].name, " IBM XT "))
|
||||
postcard_port = 0x60; /* IBM XT */
|
||||
else if (strstr(machines[machine].name, " IBM PCjr"))
|
||||
else if (strstr(machines[machine].name, " IBM PCjr")) {
|
||||
postcard_port = 0x10; /* IBM PCjr */
|
||||
else if (strstr(machines[machine].name, " Compaq ") && !machine_has_bus(machine, MACHINE_BUS_PCI))
|
||||
postcard_ports_num = 3; /* IBM PCjr error ports 11h and 12h */
|
||||
} else if (strstr(machines[machine].name, " Compaq ") && !machine_has_bus(machine, MACHINE_BUS_PCI))
|
||||
postcard_port = 0x84; /* ISA Compaq machines */
|
||||
else if (strstr(machines[machine].name, "Olivetti"))
|
||||
postcard_port = 0x378; /* Olivetti machines */
|
||||
else
|
||||
postcard_port = 0x80; /* AT and clone machines */
|
||||
postcard_log("POST card initializing on port %04Xh\n", postcard_port);
|
||||
|
||||
postcard_reset();
|
||||
|
||||
if (postcard_port)
|
||||
io_sethandler(postcard_port, 1,
|
||||
io_sethandler(postcard_port, postcard_ports_num,
|
||||
NULL, NULL, NULL, postcard_write, NULL, NULL, NULL);
|
||||
|
||||
return postcard_write;
|
||||
@@ -129,7 +177,7 @@ static void
|
||||
postcard_close(UNUSED(void *priv))
|
||||
{
|
||||
if (postcard_port)
|
||||
io_removehandler(postcard_port, 1,
|
||||
io_removehandler(postcard_port, postcard_ports_num,
|
||||
NULL, NULL, NULL, postcard_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ enum {
|
||||
SERIAL_INT_TIMEOUT = 16
|
||||
};
|
||||
|
||||
void serial_update_ints(serial_t *dev);
|
||||
|
||||
static int next_inst = 0;
|
||||
static serial_device_t serial_devices[SERIAL_MAX];
|
||||
|
||||
@@ -84,6 +86,8 @@ serial_reset_port(serial_t *dev)
|
||||
dev->out_new = 0xffff;
|
||||
memset(dev->xmit_fifo, 0, 16);
|
||||
memset(dev->rcvr_fifo, 0, 16);
|
||||
serial_update_ints(dev);
|
||||
dev->irq_state = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -102,6 +106,13 @@ serial_transmit_period(serial_t *dev)
|
||||
dev->sd->transmit_period_callback(dev, dev->sd->priv, dev->transmit_period);
|
||||
}
|
||||
|
||||
void
|
||||
serial_do_irq(serial_t *dev, int set)
|
||||
{
|
||||
if (dev->irq != 0xff)
|
||||
picint_common(1 << dev->irq, !!(dev->type >= SERIAL_16450), set, &dev->irq_state);
|
||||
}
|
||||
|
||||
void
|
||||
serial_update_ints(serial_t *dev)
|
||||
{
|
||||
@@ -131,13 +142,7 @@ serial_update_ints(serial_t *dev)
|
||||
dev->iir = 0;
|
||||
}
|
||||
|
||||
if (stat && (dev->irq != 0xff) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR))) {
|
||||
if (dev->type >= SERIAL_16450)
|
||||
picintlevel(1 << dev->irq);
|
||||
else
|
||||
picint(1 << dev->irq);
|
||||
} else
|
||||
picintc(1 << dev->irq);
|
||||
serial_do_irq(dev, stat && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -595,7 +600,7 @@ serial_write(uint16_t addr, uint8_t val, void *p)
|
||||
dev->sd->rcr_callback(dev, dev->sd->priv);
|
||||
}
|
||||
if (!(val & 8) && (dev->mctrl & 8))
|
||||
picintc(1 << dev->irq);
|
||||
serial_do_irq(dev, 0);
|
||||
if ((val ^ dev->mctrl) & 0x10)
|
||||
serial_reset_fifo(dev);
|
||||
dev->mctrl = val;
|
||||
@@ -792,23 +797,6 @@ serial_setup(serial_t *dev, uint16_t addr, uint8_t irq)
|
||||
dev->irq = irq;
|
||||
}
|
||||
|
||||
serial_t *
|
||||
serial_attach(int port,
|
||||
void (*rcr_callback)(struct serial_s *serial, void *p),
|
||||
void (*dev_write)(struct serial_s *serial, void *p, uint8_t data),
|
||||
void *priv)
|
||||
{
|
||||
serial_device_t *sd = &serial_devices[port];
|
||||
|
||||
sd->rcr_callback = rcr_callback;
|
||||
sd->dev_write = dev_write;
|
||||
sd->transmit_period_callback = NULL;
|
||||
sd->lcr_callback = NULL;
|
||||
sd->priv = priv;
|
||||
|
||||
return sd->serial;
|
||||
}
|
||||
|
||||
serial_t *
|
||||
serial_attach_ex(int port,
|
||||
void (*rcr_callback)(struct serial_s *serial, void *p),
|
||||
|
||||
@@ -42,9 +42,12 @@ typedef struct cmd640_t {
|
||||
uint8_t id;
|
||||
uint8_t in_cfg;
|
||||
uint8_t channels;
|
||||
uint8_t pci, regs[256];
|
||||
uint8_t pci;
|
||||
uint8_t irq_state;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad0;
|
||||
uint8_t regs[256];
|
||||
uint32_t local;
|
||||
int slot;
|
||||
int irq_mode[2];
|
||||
int irq_pin;
|
||||
int irq_line;
|
||||
@@ -95,12 +98,12 @@ cmd640_set_irq(int channel, void *priv)
|
||||
|
||||
if (irq) {
|
||||
if (dev->irq_mode[channel] == 1)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state);
|
||||
else
|
||||
picint(1 << (14 + channel));
|
||||
} else {
|
||||
if (dev->irq_mode[channel] == 1)
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state);
|
||||
else
|
||||
picintc(1 << (14 + channel));
|
||||
}
|
||||
@@ -500,7 +503,10 @@ cmd640_init(const device_t *info)
|
||||
if (info->flags & DEVICE_PCI) {
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev);
|
||||
if (info->local & 0x80000)
|
||||
pci_add_card(PCI_ADD_NORMAL, cmd640_pci_read, cmd640_pci_write, dev, &dev->pci_slot);
|
||||
else
|
||||
pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
if (dev->channels & 0x01)
|
||||
ide_set_bus_master(0, NULL, cmd640_set_irq, dev);
|
||||
|
||||
@@ -41,11 +41,16 @@ typedef struct cmd646_t {
|
||||
uint8_t vlb_idx;
|
||||
uint8_t single_channel;
|
||||
uint8_t in_cfg;
|
||||
uint8_t pci_slot;
|
||||
|
||||
uint8_t regs[256];
|
||||
|
||||
uint32_t local;
|
||||
int slot;
|
||||
int irq_mode[2];
|
||||
|
||||
int irq_pin;
|
||||
|
||||
int irq_mode[2];
|
||||
|
||||
sff8038i_t *bm[2];
|
||||
} cmd646_t;
|
||||
|
||||
@@ -102,6 +107,9 @@ cmd646_ide_handlers(cmd646_t *dev)
|
||||
uint16_t side;
|
||||
int irq_mode[2] = { 0, 0 };
|
||||
|
||||
sff_set_slot(dev->bm[0], dev->pci_slot);
|
||||
sff_set_slot(dev->bm[1], dev->pci_slot);
|
||||
|
||||
ide_pri_disable();
|
||||
|
||||
if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) {
|
||||
@@ -382,7 +390,10 @@ cmd646_init(const device_t *info)
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->slot = pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev);
|
||||
if (info->local & 0x80000)
|
||||
pci_add_card(PCI_ADD_NORMAL, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot);
|
||||
else
|
||||
pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->single_channel = !!(info->local & 0x20000);
|
||||
|
||||
|
||||
@@ -409,31 +409,31 @@ sff_bus_master_set_irq(int channel, void *priv)
|
||||
case 1:
|
||||
/* Native PCI IRQ mode with interrupt pin. */
|
||||
if (irq)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
/* MIRQ 0 or 1. */
|
||||
if (irq)
|
||||
pci_set_mirq(dev->irq_mode[channel] & 1, 0);
|
||||
pci_set_mirq((dev->irq_mode[channel] & 1), 0, &dev->irq_state);
|
||||
else
|
||||
pci_clear_mirq(dev->irq_mode[channel] & 1, 0);
|
||||
pci_clear_mirq((dev->irq_mode[channel] & 1), 0, &dev->irq_state);
|
||||
break;
|
||||
case 3:
|
||||
/* Native PCI IRQ mode with specified interrupt line. */
|
||||
if (irq)
|
||||
picintlevel(1 << dev->irq_line);
|
||||
picintlevel(1 << dev->irq_line, &dev->irq_state);
|
||||
else
|
||||
picintc(1 << dev->irq_line);
|
||||
picintclevel(1 << dev->irq_line, &dev->irq_state);
|
||||
break;
|
||||
case 4:
|
||||
/* ALi Aladdin Native PCI INTAJ mode. */
|
||||
if (irq)
|
||||
pci_set_mirq(channel + 2, dev->irq_level[channel]);
|
||||
pci_set_mirq((channel + 2), dev->irq_level[channel], &dev->irq_state);
|
||||
else
|
||||
pci_clear_mirq(channel + 2, dev->irq_level[channel]);
|
||||
pci_clear_mirq((channel + 2), dev->irq_level[channel], &dev->irq_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -456,6 +456,7 @@ sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base)
|
||||
dev->addr = 0x00000000;
|
||||
dev->ptr0 = 0x00;
|
||||
dev->count = dev->eot = 0x00000000;
|
||||
dev->irq_state = 0;
|
||||
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
@@ -570,6 +571,7 @@ sff_init(UNUSED(const device_t *info))
|
||||
dev->irq_pin = PCI_INTA;
|
||||
dev->irq_line = 14;
|
||||
dev->irq_level[0] = dev->irq_level[1] = 0;
|
||||
dev->irq_state = 0;
|
||||
|
||||
next_id++;
|
||||
|
||||
|
||||
@@ -123,7 +123,8 @@ typedef struct acpi_regs_t {
|
||||
typedef struct acpi_t {
|
||||
acpi_regs_t regs;
|
||||
uint8_t gpireg2_default;
|
||||
uint8_t pad[3];
|
||||
uint8_t irq_state;
|
||||
uint8_t pad[2];
|
||||
uint8_t gporeg_default[4];
|
||||
uint8_t suspend_types[8];
|
||||
uint16_t io_base;
|
||||
|
||||
@@ -26,11 +26,11 @@ typedef struct sff8038i_t {
|
||||
uint8_t ptr0;
|
||||
uint8_t enabled;
|
||||
uint8_t dma_mode;
|
||||
uint8_t irq_state;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
uint16_t base;
|
||||
uint16_t pad2;
|
||||
uint16_t pad1;
|
||||
uint32_t ptr;
|
||||
uint32_t ptr_cur;
|
||||
uint32_t addr;
|
||||
|
||||
@@ -83,7 +83,8 @@ extern lpt_port_t lpt_ports[PARALLEL_MAX];
|
||||
extern void lpt_write(uint16_t port, uint8_t val, void *priv);
|
||||
extern uint8_t lpt_read(uint16_t port, void *priv);
|
||||
|
||||
extern void lpt_irq(void *priv, int raise);
|
||||
extern uint8_t lpt_read_status(int port);
|
||||
extern void lpt_irq(void *priv, int raise);
|
||||
|
||||
extern char *lpt_device_get_name(int id);
|
||||
extern char *lpt_device_get_internal_name(int id);
|
||||
|
||||
@@ -331,6 +331,24 @@ extern void writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val);
|
||||
|
||||
extern void do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write);
|
||||
|
||||
extern uint8_t readmembl_2386(uint32_t addr);
|
||||
extern void writemembl_2386(uint32_t addr, uint8_t val);
|
||||
extern uint16_t readmemwl_2386(uint32_t addr);
|
||||
extern void writememwl_2386(uint32_t addr, uint16_t val);
|
||||
extern uint32_t readmemll_2386(uint32_t addr);
|
||||
extern void writememll_2386(uint32_t addr, uint32_t val);
|
||||
extern uint64_t readmemql_2386(uint32_t addr);
|
||||
extern void writememql_2386(uint32_t addr, uint64_t val);
|
||||
|
||||
extern uint8_t readmembl_no_mmut_2386(uint32_t addr, uint32_t a64);
|
||||
extern void writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val);
|
||||
extern uint16_t readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64);
|
||||
extern void writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val);
|
||||
extern uint32_t readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64);
|
||||
extern void writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val);
|
||||
|
||||
extern void do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write);
|
||||
|
||||
extern uint8_t *getpccache(uint32_t a);
|
||||
extern uint64_t mmutranslatereal(uint32_t addr, int rw);
|
||||
extern uint32_t mmutranslatereal32(uint32_t addr, int rw);
|
||||
@@ -429,6 +447,9 @@ extern void mem_close(void);
|
||||
extern void mem_reset(void);
|
||||
extern void mem_remap_top(int kb);
|
||||
|
||||
extern mem_mapping_t *read_mapping[MEM_MAPPINGS_NO];
|
||||
extern mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];
|
||||
|
||||
#ifdef EMU_CPU_H
|
||||
static __inline uint32_t
|
||||
get_phys(uint32_t addr)
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
#ifndef EMU_MOUSE_H
|
||||
#define EMU_MOUSE_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
/* Yes, a big no-no, but I'm saving myself time here. */
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
#define MOUSE_TYPE_NONE 0 /* no mouse configured */
|
||||
#define MOUSE_TYPE_INTERNAL 1 /* machine has internal mouse */
|
||||
#define MOUSE_TYPE_LOGIBUS 2 /* Logitech/ATI Bus Mouse */
|
||||
@@ -39,20 +44,26 @@
|
||||
|
||||
#define MOUSE_TYPE_ONBOARD 0x80 /* Mouse is an on-board version of one of the above. */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#else
|
||||
extern atomic_int mouse_x;
|
||||
extern atomic_int mouse_y;
|
||||
extern atomic_int mouse_z;
|
||||
extern atomic_int mouse_buttons;
|
||||
#endif
|
||||
|
||||
extern int mouse_type;
|
||||
extern int mouse_x;
|
||||
extern int mouse_y;
|
||||
extern int mouse_z;
|
||||
extern int mouse_mode; /* 1 = Absolute, 0 = Relative */
|
||||
extern int mouse_timed; /* 1 = Timed, 0 = Constant */
|
||||
extern int mouse_tablet_in_proximity;
|
||||
extern double mouse_x_abs;
|
||||
extern double mouse_y_abs;
|
||||
extern int mouse_buttons;
|
||||
extern int tablet_tool_type;
|
||||
extern double mouse_sensitivity;
|
||||
extern double mouse_x_error;
|
||||
extern double mouse_y_error;
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t *mouse_get_device(int mouse);
|
||||
@@ -79,11 +90,16 @@ extern void mouse_set_buttons(int buttons);
|
||||
extern void mouse_set_poll_ex(void (*poll_ex)(void));
|
||||
extern void mouse_process(void);
|
||||
extern void mouse_set_poll(int (*f)(int, int, int, int, void *), void *);
|
||||
extern void mouse_poll(void);
|
||||
|
||||
extern void mouse_bus_set_irq(void *priv, int irq);
|
||||
|
||||
extern void mouse_set_sample_rate(double new_rate);
|
||||
extern void mouse_scale(int x, int y);
|
||||
extern void mouse_scale_x(int x);
|
||||
extern void mouse_scale_y(int y);
|
||||
extern void mouse_set_z(int z);
|
||||
extern void mouse_set_buttons_ex(int b);
|
||||
extern int mouse_get_buttons_ex(void);
|
||||
|
||||
extern char *mouse_get_name(int mouse);
|
||||
extern char *mouse_get_internal_name(int mouse);
|
||||
|
||||
@@ -11,146 +11,260 @@
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
*
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2023 Miran Grca.
|
||||
*/
|
||||
|
||||
#ifndef EMU_PCI_H
|
||||
#define EMU_PCI_H
|
||||
|
||||
#define PCI_REG_COMMAND 0x04
|
||||
#define PCI_REG_VENDOR_ID_L 0x00
|
||||
#define PCI_REG_VENDOR_ID_H 0x01
|
||||
#define PCI_REG_DEVICE_ID_L 0x02
|
||||
#define PCI_REG_DEVICE_ID_H 0x03
|
||||
#define PCI_REG_COMMAND_L 0x04
|
||||
#define PCI_REG_COMMAND_H 0x05
|
||||
#define PCI_REG_STATUS_L 0x06
|
||||
#define PCI_REG_STATUS_H 0x07
|
||||
#define PCI_REG_REVISION 0x08
|
||||
#define PCI_REG_PROG_IF 0x09
|
||||
#define PCI_REG_SUBCLASS 0x0a
|
||||
#define PCI_REG_CLASS 0x0b
|
||||
#define PCI_REG_CACHELINE_SIZE 0x0c
|
||||
#define PCI_REG_LATENCY_TIMER 0x0d
|
||||
#define PCI_REG_HEADER_TYPE 0x0e
|
||||
#define PCI_REG_BIST 0x0f
|
||||
|
||||
#define PCI_COMMAND_IO 0x01
|
||||
#define PCI_COMMAND_MEM 0x02
|
||||
#define PCI_COMMAND_L_IO 0x01
|
||||
#define PCI_COMMAND_L_MEM 0x02
|
||||
#define PCI_COMMAND_L_BM 0x04
|
||||
#define PCI_COMMAND_L_SPECIAL 0x08
|
||||
#define PCI_COMMAND_L_MEM_WIEN 0x10
|
||||
#define PCI_COMMAND_L_VGASNOOP 0x20
|
||||
#define PCI_COMMAND_L_PARITY 0x40
|
||||
|
||||
#define PCI_NO_IRQ_STEERING 0x8000
|
||||
#define PCI_CAN_SWITCH_TYPE 0x10000
|
||||
#define PCI_NO_BRIDGES 0x20000
|
||||
#define PCI_ALWAYS_EXPOSE_DEV0 0x40000
|
||||
#define PCI_COMMAND_H_SERR 0x01
|
||||
#define PCI_COMMAND_H_FAST_B2B 0x02
|
||||
#define PCI_COMMAND_H_INT_DIS 0x04
|
||||
|
||||
#define PCI_CONFIG_TYPE_1 1
|
||||
#define PCI_CONFIG_TYPE_2 2
|
||||
#define PCI_STATUS_L_INT 0x08
|
||||
#define PCI_STATUS_L_CAPAB 0x10
|
||||
#define PCI_STATUS_L_66MHZ 0x20
|
||||
#define PCI_STATUS_L_FAST_B2B 0x80
|
||||
|
||||
#define PCI_CONFIG_TYPE_MASK 0x7fff
|
||||
#define PCI_STATUS_H_MDPERR 0x01 /* Master Data Parity Error */
|
||||
#define PCI_STATUS_H_DEVSEL 0x06
|
||||
#define PCI_STATUS_H_STA 0x08 /* Signaled Target Abort */
|
||||
#define PCI_STATUS_H_RTA 0x10 /* Received Target Abort */
|
||||
#define PCI_STATUS_H_RMA 0x20 /* Received Master Abort */
|
||||
#define PCI_STATUS_H_SSE 0x40 /* Signaled System Error */
|
||||
#define PCI_STATUS_H_DPERR 0x80 /* Detected Parity Error */
|
||||
|
||||
#define PCI_INTA 1
|
||||
#define PCI_INTB 2
|
||||
#define PCI_INTC 3
|
||||
#define PCI_INTD 4
|
||||
#define PCI_DEVSEL_FAST 0x00
|
||||
#define PCI_DEVSEL_MEDIUM 0x02
|
||||
#define PCI_DEVSEL_SLOW 0x04
|
||||
|
||||
#define PCI_MIRQ0 0
|
||||
#define PCI_MIRQ1 1
|
||||
#define PCI_MIRQ2 2
|
||||
#define PCI_MIRQ3 3
|
||||
#define PCI_MIRQ4 4
|
||||
#define PCI_MIRQ5 5
|
||||
#define PCI_MIRQ6 6
|
||||
#define PCI_MIRQ7 7
|
||||
#define FLAG_MECHANISM_1 0x00000001
|
||||
#define FLAG_MECHANISM_2 0x00000002
|
||||
#define FLAG_MECHANISM_SWITCH 0x00000004
|
||||
#define FLAG_CONFIG_IO_ON 0x00000008
|
||||
#define FLAG_CONFIG_DEV0_IO_ON 0x00000010
|
||||
#define FLAG_CONFIG_M1_IO_ON 0x00000020
|
||||
#define FLAG_NO_IRQ_STEERING 0x00000040
|
||||
#define FLAG_NO_BRIDGES 0x00000080
|
||||
|
||||
#define PCI_IRQ_DISABLED -1
|
||||
#define FLAG_MECHANISM_MASK FLAG_MECHANISM_1 | FLAG_MECHANISM_2
|
||||
#define FLAG_MASK 0x0000007f
|
||||
|
||||
#define PCI_ADD_STRICT 0x80
|
||||
#define PCI_INTA 1
|
||||
#define PCI_INTB 2
|
||||
#define PCI_INTC 3
|
||||
#define PCI_INTD 4
|
||||
|
||||
#define PCI_MIRQ0 0
|
||||
#define PCI_MIRQ1 1
|
||||
#define PCI_MIRQ2 2
|
||||
#define PCI_MIRQ3 3
|
||||
#define PCI_MIRQ4 4
|
||||
#define PCI_MIRQ5 5
|
||||
#define PCI_MIRQ6 6
|
||||
#define PCI_MIRQ7 7
|
||||
|
||||
#define PCI_IRQ_DISABLED -1
|
||||
|
||||
#define PCI_ADD_STRICT 0x40
|
||||
#define PCI_ADD_MASK (PCI_ADD_STRICT - 1)
|
||||
#define PCI_ADD_VFIO 0x80
|
||||
#define PCI_ADD_VFIO_MASK (PCI_ADD_VFIO - 1)
|
||||
|
||||
#define PCI_CARD_VFIO PCI_ADD_VFIO
|
||||
|
||||
#define PCI_BUS_INVALID 0xff
|
||||
|
||||
#define PCI_IGNORE_NO_SLOT 0xff
|
||||
|
||||
/* The number of an invalid PCI card. */
|
||||
#define PCI_CARD_INVALID 0xef
|
||||
/* PCI cards (currently 32). */
|
||||
#define PCI_CARDS_NUM 0x20
|
||||
#define PCI_CARD_MAX (PCI_CARDS_NUM - 1)
|
||||
/* The number of PCI card INT pins - always at 4 per the PCI specification. */
|
||||
#define PCI_INT_PINS_NUM 4
|
||||
/* The base for MIRQ lines accepted by pci_irq(). */
|
||||
#define PCI_MIRQ_BASE PCI_CARDS_NUM
|
||||
/* PCI MIRQ lines (currently 8, this many are needed by the ALi M1543(C). */
|
||||
#define PCI_MIRQS_NUM 8
|
||||
#define PCI_MIRQ_MAX (PCI_MIRQS_NUM - 1)
|
||||
/* The base for direct IRQ lines accepted by pci_irq(). */
|
||||
#define PCI_DIRQ_BASE 0xf0
|
||||
/* PCI direct IRQ lines (currently 16 because we only emulate the legacy PIC). */
|
||||
#define PCI_DIRQS_NUM 16
|
||||
#define PCI_DIRQ_MAX (PCI_DIRQS_NUM - 1)
|
||||
/* PCI IRQ routings (currently 16, this many are needed by the OPTi 822). */
|
||||
#define PCI_IRQS_NUM 16
|
||||
#define PCI_IRQ_MAX (PCI_IRQS_NUM - 1)
|
||||
|
||||
/* Legacy flags. */
|
||||
#define PCI_REG_COMMAND PCI_REG_COMMAND_L
|
||||
|
||||
#define PCI_COMMAND_IO PCI_COMMAND_L_IO
|
||||
#define PCI_COMMAND_MEM PCI_COMMAND_L_MEM
|
||||
|
||||
#define PCI_CONFIG_TYPE_1 FLAG_MECHANISM_1
|
||||
#define PCI_CONFIG_TYPE_2 FLAG_MECHANISM_2
|
||||
|
||||
#define PCI_CAN_SWITCH_TYPE FLAG_MECHANISM_SWITCH
|
||||
#define PCI_ALWAYS_EXPOSE_DEV0 FLAG_CONFIG_DEV0_IO_ON
|
||||
#define PCI_NO_IRQ_STEERING FLAG_NO_IRQ_STEERING
|
||||
#define PCI_NO_BRIDGES FLAG_NO_BRIDGES
|
||||
|
||||
#define PCI_CONFIG_TYPE_MASK FLAG_MECHANISM_MASK
|
||||
|
||||
#define bar_t pci_bar_t
|
||||
#define trc_init pci_trc_init
|
||||
|
||||
#define pci_register_slot(card, type, inta, intb, intc, intd) \
|
||||
pci_register_bus_slot(0, card, type, inta, intb, intc, intd)
|
||||
|
||||
#define pci_set_mirq(mirq, level, irq_state) \
|
||||
pci_irq(PCI_MIRQ_BASE | mirq, 0, level, 1, irq_state)
|
||||
#define pci_set_irq(slot, pci_int, irq_state) \
|
||||
pci_irq(slot, pci_int, 0, 1, irq_state)
|
||||
#define pci_clear_mirq(mirq, level, irq_state) \
|
||||
pci_irq(PCI_MIRQ_BASE | mirq, 0, level, 0, irq_state)
|
||||
#define pci_clear_irq(slot, pci_int, irq_state) \
|
||||
pci_irq(slot, pci_int, 0, 0, irq_state)
|
||||
|
||||
enum {
|
||||
PCI_CARD_NORTHBRIDGE = 0,
|
||||
PCI_CARD_AGPBRIDGE = 1,
|
||||
PCI_CARD_SOUTHBRIDGE = 2,
|
||||
PCI_CARD_SOUTHBRIDGE_IDE = 3,
|
||||
PCI_CARD_SOUTHBRIDGE_PMU = 4,
|
||||
PCI_CARD_SOUTHBRIDGE_USB = 5,
|
||||
PCI_CARD_NORTHBRIDGE_SEC = 1,
|
||||
PCI_CARD_AGPBRIDGE = 2,
|
||||
PCI_CARD_SOUTHBRIDGE = 3,
|
||||
PCI_CARD_SOUTHBRIDGE_IDE = 4,
|
||||
PCI_CARD_SOUTHBRIDGE_PMU = 5,
|
||||
PCI_CARD_SOUTHBRIDGE_USB = 6,
|
||||
PCI_CARD_AGP = 0x0f,
|
||||
PCI_CARD_NORMAL = 0x10,
|
||||
PCI_CARD_VIDEO = 0x11,
|
||||
PCI_CARD_SCSI = 0x12,
|
||||
PCI_CARD_SOUND = 0x13,
|
||||
PCI_CARD_IDE = 0x14,
|
||||
PCI_CARD_NETWORK = 0x15,
|
||||
PCI_CARD_BRIDGE = 0x16
|
||||
PCI_CARD_HANGUL = 0x12,
|
||||
PCI_CARD_IDE = 0x13,
|
||||
PCI_CARD_SCSI = 0x14,
|
||||
PCI_CARD_SOUND = 0x15,
|
||||
PCI_CARD_MODEM = 0x16,
|
||||
PCI_CARD_NETWORK = 0x17,
|
||||
PCI_CARD_UART = 0x18,
|
||||
PCI_CARD_USB = 0x19,
|
||||
PCI_CARD_BRIDGE = 0x1a
|
||||
};
|
||||
|
||||
enum {
|
||||
PCI_ADD_NORTHBRIDGE = 0,
|
||||
PCI_ADD_AGPBRIDGE = 1,
|
||||
PCI_ADD_SOUTHBRIDGE = 2,
|
||||
PCI_ADD_SOUTHBRIDGE_IDE = 3,
|
||||
PCI_ADD_SOUTHBRIDGE_PMU = 4,
|
||||
PCI_ADD_SOUTHBRIDGE_USB = 5,
|
||||
PCI_ADD_NORTHBRIDGE_SEC = 1,
|
||||
PCI_ADD_AGPBRIDGE = 2,
|
||||
PCI_ADD_SOUTHBRIDGE = 3,
|
||||
PCI_ADD_SOUTHBRIDGE_IDE = 4,
|
||||
PCI_ADD_SOUTHBRIDGE_PMU = 5,
|
||||
PCI_ADD_SOUTHBRIDGE_USB = 6,
|
||||
PCI_ADD_AGP = 0x0f,
|
||||
PCI_ADD_NORMAL = 0x10,
|
||||
PCI_ADD_VIDEO = 0x11,
|
||||
PCI_ADD_SCSI = 0x12,
|
||||
PCI_ADD_SOUND = 0x13,
|
||||
PCI_ADD_IDE = 0x14,
|
||||
PCI_ADD_NETWORK = 0x15,
|
||||
PCI_ADD_BRIDGE = 0x16
|
||||
PCI_ADD_HANGUL = 0x12,
|
||||
PCI_ADD_IDE = 0x13,
|
||||
PCI_ADD_SCSI = 0x14,
|
||||
PCI_ADD_SOUND = 0x15,
|
||||
PCI_ADD_MODEM = 0x16,
|
||||
PCI_ADD_NETWORK = 0x17,
|
||||
PCI_ADD_UART = 0x18,
|
||||
PCI_ADD_USB = 0x19,
|
||||
PCI_ADD_BRIDGE = 0x1a
|
||||
};
|
||||
|
||||
typedef union {
|
||||
uint32_t addr;
|
||||
uint8_t addr_regs[4];
|
||||
} bar_t;
|
||||
} pci_bar_t;
|
||||
|
||||
extern int pci_burst_time;
|
||||
extern int agp_burst_time;
|
||||
extern int pci_nonburst_time;
|
||||
extern int agp_nonburst_time;
|
||||
|
||||
#define PCI_IO_ON 0x01
|
||||
#define PCI_IO_DEV0 0x02
|
||||
extern int pci_flags;
|
||||
|
||||
extern uint32_t pci_base;
|
||||
extern uint32_t pci_size;
|
||||
|
||||
extern int pci_burst_time;
|
||||
extern int agp_burst_time;
|
||||
extern int pci_nonburst_time;
|
||||
extern int agp_nonburst_time;
|
||||
extern int pci_take_over_io;
|
||||
extern void pci_set_irq_routing(int pci_int, int irq);
|
||||
extern void pci_set_irq_level(int pci_int, int level);
|
||||
extern void pci_enable_mirq(int mirq);
|
||||
extern void pci_set_mirq_routing(int mirq, int irq);
|
||||
|
||||
extern uint32_t pci_base;
|
||||
extern uint32_t pci_size;
|
||||
/* PCI raise IRQ: the first parameter is slot if < PCI_MIRQ_BASE, MIRQ if >= PCI_MIRQ_BASE
|
||||
and < PCI_DIRQ_BASE, and direct IRQ line if >= PCI_DIRQ_BASE (RichardG's
|
||||
hack that may no longer be needed). */
|
||||
extern void pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state);
|
||||
|
||||
extern uint8_t pci_get_int(uint8_t slot, uint8_t pci_int);
|
||||
|
||||
extern void pci_type2_write(uint16_t port, uint8_t val, void *priv);
|
||||
extern void pci_type2_writew(uint16_t port, uint16_t val, void *priv);
|
||||
extern void pci_type2_writel(uint16_t port, uint32_t val, void *priv);
|
||||
extern uint8_t pci_type2_read(uint16_t port, void *priv);
|
||||
extern uint16_t pci_type2_readw(uint16_t port, void *priv);
|
||||
extern uint32_t pci_type2_readl(uint16_t port, void *priv);
|
||||
/* Relocate a PCI device to a new slot, required for the configurable
|
||||
IDSEL's of ALi M1543(c). */
|
||||
extern void pci_relocate_slot(int type, int new_slot);
|
||||
|
||||
extern void pci_set_irq_routing(int pci_int, int irq);
|
||||
extern void pci_set_irq_level(int pci_int, int level);
|
||||
/* Write PCI enable/disable key, split for the ALi M1435. */
|
||||
extern void pci_key_write(uint8_t val);
|
||||
|
||||
extern void pci_enable_mirq(int mirq);
|
||||
extern void pci_set_mirq_routing(int mirq, int irq);
|
||||
/* Set PMC (ie. change PCI configuration mechanism), 0 = #2, 1 = #1. */
|
||||
extern void pci_set_pmc(uint8_t pmc);
|
||||
|
||||
extern int pci_irq_is_level(int irq);
|
||||
extern void pci_pic_reset(void);
|
||||
extern void pci_reset(void);
|
||||
|
||||
extern void pci_set_mirq(uint8_t mirq, int level);
|
||||
extern void pci_set_irq(uint8_t card, uint8_t pci_int);
|
||||
extern void pci_clear_mirq(uint8_t mirq, int level);
|
||||
extern void pci_clear_irq(uint8_t card, uint8_t pci_int);
|
||||
extern uint8_t pci_get_int(uint8_t card, uint8_t pci_int);
|
||||
/* Needed for the io.c handling of configuration mechanism #2 ports C000-CFFF. */
|
||||
extern void pci_write(uint16_t port, uint8_t val, void *priv);
|
||||
extern void pci_writew(uint16_t port, uint16_t val, void *priv);
|
||||
extern void pci_writel(uint16_t port, uint32_t val, void *priv);
|
||||
extern uint8_t pci_read(uint16_t port, void *priv);
|
||||
extern uint16_t pci_readw(uint16_t port, void *priv);
|
||||
extern uint32_t pci_readl(uint16_t port, void *priv);
|
||||
|
||||
extern void pci_reset(void);
|
||||
extern void pci_init(int type);
|
||||
extern uint8_t pci_register_bus(void);
|
||||
extern void pci_set_pmc(uint8_t pmc);
|
||||
extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number);
|
||||
extern void pci_relocate_slot(int type, int new_slot);
|
||||
extern void pci_register_slot(int card, int type,
|
||||
int inta, int intb, int intc, int intd);
|
||||
extern void pci_register_bus_slot(int bus, int card, int type,
|
||||
int inta, int intb, int intc, int intd);
|
||||
extern void pci_close(void);
|
||||
extern uint8_t pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
||||
extern uint8_t pci_register_bus(void);
|
||||
extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number);
|
||||
extern void pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc, int intd);
|
||||
|
||||
extern void trc_init(void);
|
||||
/* Add a PCI card. */
|
||||
extern void pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv),
|
||||
void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot);
|
||||
|
||||
extern uint8_t trc_read(uint16_t port, void *priv);
|
||||
extern void trc_write(uint16_t port, uint8_t val, void *priv);
|
||||
/* Add an instance of the PCI bridge. */
|
||||
extern uint8_t pci_add_bridge(uint8_t (*read)(int func, int addr, void *priv),
|
||||
void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
||||
|
||||
extern void pci_bridge_set_ctl(void *priv, uint8_t ctl);
|
||||
/* Register the cards that have been added into slots. */
|
||||
extern void pci_register_cards(void);
|
||||
|
||||
extern void pci_pic_reset(void);
|
||||
extern void pci_init(int flags);
|
||||
|
||||
/* PCI bridge stuff. */
|
||||
extern void pci_bridge_set_ctl(void *priv, uint8_t ctl);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t dec21150_device;
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
#ifndef EMU_PIC_H
|
||||
#define EMU_PIC_H
|
||||
|
||||
typedef struct pic_latch {
|
||||
uint8_t d;
|
||||
uint8_t e;
|
||||
uint8_t q;
|
||||
uint8_t nq;
|
||||
} pic_latch_t;
|
||||
|
||||
typedef struct pic {
|
||||
uint8_t icw1;
|
||||
uint8_t icw2;
|
||||
@@ -38,8 +45,13 @@ typedef struct pic {
|
||||
uint8_t special_mask_mode;
|
||||
uint8_t auto_eoi_rotate;
|
||||
uint8_t interrupt;
|
||||
uint8_t lines;
|
||||
uint8_t data_bus;
|
||||
uint8_t irq_latch;
|
||||
uint8_t has_slaves;
|
||||
uint8_t flags;
|
||||
uint8_t edge_lines;
|
||||
uint8_t pad;
|
||||
uint32_t lines[8];
|
||||
uint32_t at;
|
||||
struct pic *slaves[8];
|
||||
} pic_t;
|
||||
@@ -70,12 +82,22 @@ extern void pic2_init(void);
|
||||
extern void pic_reset(void);
|
||||
|
||||
extern int picint_is_level(int irq);
|
||||
extern void picint_common(uint16_t num, int level, int set);
|
||||
extern void picint(uint16_t num);
|
||||
extern void picintlevel(uint16_t num);
|
||||
extern void picintc(uint16_t num);
|
||||
extern void picint_common(uint16_t num, int level, int set, uint8_t *irq_state);
|
||||
extern int picinterrupt(void);
|
||||
|
||||
#define PIC_IRQ_EDGE 0
|
||||
#define PIC_IRQ_LEVEL 1
|
||||
|
||||
#define PIC_SLAVE_PENDING 0x01
|
||||
#define PIC_FREEZE 0x02
|
||||
#define PIC_MASTER_CLEAR 0x04
|
||||
|
||||
/* Legacy defines. */
|
||||
#define picint(num) picint_common(num, PIC_IRQ_EDGE, 1, NULL)
|
||||
#define picintlevel(num, irq_state) picint_common(num, PIC_IRQ_LEVEL, 1, irq_state)
|
||||
#define picintc(num) picint_common(num, PIC_IRQ_EDGE, 0, NULL)
|
||||
#define picintclevel(num, irq_state) picint_common(num, PIC_IRQ_LEVEL, 0, irq_state)
|
||||
|
||||
extern uint8_t pic_irq_ack(void);
|
||||
|
||||
#endif /*EMU_PIC_H*/
|
||||
|
||||
@@ -396,6 +396,10 @@ typedef struct x54x_t {
|
||||
uint8_t setup_info_len;
|
||||
uint8_t max_id;
|
||||
uint8_t pci_slot;
|
||||
uint8_t irq_state;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
uint8_t temp_cdb[12];
|
||||
|
||||
/* for multi-threading, keep these volatile */
|
||||
@@ -437,7 +441,7 @@ typedef struct x54x_t {
|
||||
volatile int PendingInterrupt;
|
||||
volatile int Lock;
|
||||
volatile int target_data_len;
|
||||
volatile int pad0;
|
||||
volatile int pad2;
|
||||
|
||||
uint32_t Base;
|
||||
uint32_t fdc_address;
|
||||
|
||||
@@ -74,13 +74,13 @@ typedef struct serial_s {
|
||||
uint8_t out;
|
||||
uint8_t msr_set;
|
||||
uint8_t pad;
|
||||
uint8_t irq_state;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
|
||||
uint16_t dlab;
|
||||
uint16_t base_address;
|
||||
uint16_t out_new;
|
||||
uint16_t pad2;
|
||||
uint16_t pad1;
|
||||
|
||||
uint8_t rcvr_fifo_pos;
|
||||
uint8_t xmit_fifo_pos;
|
||||
@@ -113,16 +113,16 @@ typedef struct serial_port_s {
|
||||
|
||||
extern serial_port_t com_ports[SERIAL_MAX];
|
||||
|
||||
extern serial_t *serial_attach(int port,
|
||||
void (*rcr_callback)(struct serial_s *serial, void *p),
|
||||
void (*dev_write)(struct serial_s *serial, void *p, uint8_t data),
|
||||
void *priv);
|
||||
extern serial_t *serial_attach_ex(int port,
|
||||
void (*rcr_callback)(struct serial_s *serial, void *p),
|
||||
void (*dev_write)(struct serial_s *serial, void *p, uint8_t data),
|
||||
void (*transmit_period_callback)(struct serial_s *serial, void *p, double transmit_period),
|
||||
void (*lcr_callback)(struct serial_s *serial, void *p, uint8_t data_bits),
|
||||
void *priv);
|
||||
|
||||
#define serial_attach(port, rcr_callback, dev_write, priv) \
|
||||
serial_attach_ex(port, rcr_callback, dev_write, NULL, NULL, priv);
|
||||
|
||||
extern void serial_remove(serial_t *dev);
|
||||
extern void serial_set_type(serial_t *dev, int type);
|
||||
extern void serial_setup(serial_t *dev, uint16_t addr, uint8_t irq);
|
||||
|
||||
@@ -271,6 +271,8 @@ typedef struct voodoo_t {
|
||||
|
||||
int pci_enable;
|
||||
|
||||
uint8_t pci_slot;
|
||||
|
||||
uint8_t dac_data[8];
|
||||
int dac_reg;
|
||||
int dac_reg_ff;
|
||||
|
||||
110
src/io.c
110
src/io.c
@@ -286,16 +286,22 @@ inb(uint16_t port)
|
||||
io_t *p;
|
||||
io_t *q;
|
||||
int found = 0;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_type2_read(port, NULL);
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_read(port, NULL);
|
||||
found = 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
ret = pci_type2_read(port, NULL);
|
||||
#endif
|
||||
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
ret = pci_read(port, NULL);
|
||||
found = 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
#endif
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
@@ -303,7 +309,9 @@ inb(uint16_t port)
|
||||
if (p->inb) {
|
||||
ret &= p->inb(port, p->priv);
|
||||
found |= 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -338,16 +346,22 @@ outb(uint16_t port, uint8_t val)
|
||||
io_t *p;
|
||||
io_t *q;
|
||||
int found = 0;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_type2_write(port, val, NULL);
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_write(port, val, NULL);
|
||||
found = 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
pci_type2_write(port, val, NULL);
|
||||
#endif
|
||||
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
pci_write(port, val, NULL);
|
||||
found = 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
#endif
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
@@ -355,7 +369,9 @@ outb(uint16_t port, uint8_t val)
|
||||
if (p->outb) {
|
||||
p->outb(port, val, p->priv);
|
||||
found |= 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -381,17 +397,23 @@ inw(uint16_t port)
|
||||
io_t *q;
|
||||
uint16_t ret = 0xffff;
|
||||
int found = 0;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
int qfound = 0;
|
||||
#endif
|
||||
uint8_t ret8[2];
|
||||
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_type2_readw(port, NULL);
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_readw(port, NULL);
|
||||
found = 2;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
ret = pci_type2_readw(port, NULL);
|
||||
#endif
|
||||
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
ret = pci_readw(port, NULL);
|
||||
found = 2;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
#endif
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
@@ -399,7 +421,9 @@ inw(uint16_t port)
|
||||
if (p->inw) {
|
||||
ret &= p->inw(port, p->priv);
|
||||
found |= 2;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -413,7 +437,9 @@ inw(uint16_t port)
|
||||
if (p->inb && !p->inw) {
|
||||
ret8[i] &= p->inb(port + i, p->priv);
|
||||
found |= 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -444,16 +470,22 @@ outw(uint16_t port, uint16_t val)
|
||||
io_t *p;
|
||||
io_t *q;
|
||||
int found = 0;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_type2_writew(port, val, NULL);
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_writew(port, val, NULL);
|
||||
found = 2;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
pci_type2_writew(port, val, NULL);
|
||||
#endif
|
||||
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
pci_writew(port, val, NULL);
|
||||
found = 2;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
#endif
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
@@ -461,7 +493,9 @@ outw(uint16_t port, uint16_t val)
|
||||
if (p->outw) {
|
||||
p->outw(port, val, p->priv);
|
||||
found |= 2;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -473,7 +507,9 @@ outw(uint16_t port, uint16_t val)
|
||||
if (p->outb && !p->outw) {
|
||||
p->outb(port + i, val >> (i << 3), p->priv);
|
||||
found |= 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -502,16 +538,22 @@ inl(uint16_t port)
|
||||
uint16_t ret16[2];
|
||||
uint8_t ret8[4];
|
||||
int found = 0;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_type2_readl(port, NULL);
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_readl(port, NULL);
|
||||
found = 4;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
ret = pci_type2_readl(port, NULL);
|
||||
#endif
|
||||
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
ret = pci_readl(port, NULL);
|
||||
found = 4;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
#endif
|
||||
} else {
|
||||
p = io[port];
|
||||
while (p) {
|
||||
@@ -519,7 +561,9 @@ inl(uint16_t port)
|
||||
if (p->inl) {
|
||||
ret &= p->inl(port, p->priv);
|
||||
found |= 4;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -532,7 +576,9 @@ inl(uint16_t port)
|
||||
if (p->inw && !p->inl) {
|
||||
ret16[0] &= p->inw(port, p->priv);
|
||||
found |= 2;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -543,7 +589,9 @@ inl(uint16_t port)
|
||||
if (p->inw && !p->inl) {
|
||||
ret16[1] &= p->inw(port + 2, p->priv);
|
||||
found |= 2;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -560,7 +608,9 @@ inl(uint16_t port)
|
||||
if (p->inb && !p->inw && !p->inl) {
|
||||
ret8[i] &= p->inb(port + i, p->priv);
|
||||
found |= 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -591,17 +641,23 @@ outl(uint16_t port, uint32_t val)
|
||||
io_t *p;
|
||||
io_t *q;
|
||||
int found = 0;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
int qfound = 0;
|
||||
#endif
|
||||
int i = 0;
|
||||
|
||||
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_type2_writel(port, val, NULL);
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_writel(port, val, NULL);
|
||||
found = 4;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
pci_type2_writel(port, val, NULL);
|
||||
#endif
|
||||
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
|
||||
pci_writel(port, val, NULL);
|
||||
found = 4;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound = 1;
|
||||
#endif
|
||||
} else {
|
||||
p = io[port];
|
||||
if (p) {
|
||||
@@ -610,7 +666,9 @@ outl(uint16_t port, uint32_t val)
|
||||
if (p->outl) {
|
||||
p->outl(port, val, p->priv);
|
||||
found |= 4;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -623,7 +681,9 @@ outl(uint16_t port, uint32_t val)
|
||||
if (p->outw && !p->outl) {
|
||||
p->outw(port + i, val >> (i << 3), p->priv);
|
||||
found |= 2;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
@@ -636,7 +696,9 @@ outl(uint16_t port, uint32_t val)
|
||||
if (p->outb && !p->outw && !p->outl) {
|
||||
p->outb(port + i, val >> (i << 3), p->priv);
|
||||
found |= 1;
|
||||
#ifdef ENABLE_IO_LOG
|
||||
qfound++;
|
||||
#endif
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
|
||||
14
src/lpt.c
14
src/lpt.c
@@ -165,6 +165,20 @@ lpt_read(uint16_t port, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lpt_read_status(int port)
|
||||
{
|
||||
lpt_port_t *dev = &(lpt_ports[port]);
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (dev->dt && dev->dt->read_status && dev->priv)
|
||||
ret = dev->dt->read_status(dev->priv) | 0x07;
|
||||
else
|
||||
ret = 0xdf;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_irq(void *priv, int raise)
|
||||
{
|
||||
|
||||
@@ -633,6 +633,7 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&ide_vlb_2ch_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
@@ -642,8 +643,8 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth
|
||||
|
||||
device_add(&opti802g_pci_device);
|
||||
device_add(&opti822_device);
|
||||
device_add(&keyboard_ps2_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
device_add(&fdc37c665_ide_device);
|
||||
device_add(&ide_opti611_vlb_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
@@ -1527,11 +1528,11 @@ machine_at_pcm5330_init(const machine_t *model)
|
||||
machine_at_common_init(model);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
device_add(&stpc_serial_device);
|
||||
device_add(&w83977f_370_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
@@ -1738,7 +1739,7 @@ machine_at_ms4134_init(const machine_t *model)
|
||||
|
||||
device_add(&fdc37c665_ide_pri_device);
|
||||
|
||||
pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0);
|
||||
pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
|
||||
pci_register_slot(0x0B, PCI_CARD_SCSI, 4, 1, 2, 3);
|
||||
@@ -1772,7 +1773,7 @@ machine_at_tg486gp_init(const machine_t *model)
|
||||
|
||||
device_add(&fdc37c665_ide_pri_device);
|
||||
|
||||
pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0);
|
||||
pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
|
||||
@@ -122,12 +122,20 @@ static int key_queue_end = 0;
|
||||
static void
|
||||
recalc_address(pcjr_t *pcjr)
|
||||
{
|
||||
uint8_t masked_memctrl = pcjr->memctrl;
|
||||
|
||||
/* According to the Technical Reference, bits 2 and 5 are
|
||||
ignored if there is only 64k of RAM and there are only
|
||||
4 pages. */
|
||||
if (mem_size < 128)
|
||||
masked_memctrl &= ~0x24;
|
||||
|
||||
if ((pcjr->memctrl & 0xc0) == 0xc0) {
|
||||
pcjr->vram = &ram[(pcjr->memctrl & 0x06) << 14];
|
||||
pcjr->b8000 = &ram[(pcjr->memctrl & 0x30) << 11];
|
||||
pcjr->vram = &ram[(masked_memctrl & 0x06) << 14];
|
||||
pcjr->b8000 = &ram[(masked_memctrl & 0x30) << 11];
|
||||
} else {
|
||||
pcjr->vram = &ram[(pcjr->memctrl & 0x07) << 14];
|
||||
pcjr->b8000 = &ram[(pcjr->memctrl & 0x38) << 11];
|
||||
pcjr->vram = &ram[(masked_memctrl & 0x07) << 14];
|
||||
pcjr->b8000 = &ram[(masked_memctrl & 0x38) << 11];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,11 +168,17 @@ vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
uint8_t old;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
pcjr->crtcreg = val & 0x1f;
|
||||
return;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
old = pcjr->crtc[pcjr->crtcreg];
|
||||
pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg];
|
||||
if (old != val) {
|
||||
@@ -190,6 +204,10 @@ vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
case 0x3df:
|
||||
pcjr->memctrl = val;
|
||||
pcjr->pa = val; /* The PCjr BIOS expects the value written to 3DF to
|
||||
then be readable from port 60, others it errors out
|
||||
with only 64k RAM set (but somehow, still works with
|
||||
128k or more RAM). */
|
||||
pcjr->addr_mode = val >> 6;
|
||||
recalc_address(pcjr);
|
||||
break;
|
||||
@@ -206,11 +224,17 @@ vid_in(uint16_t addr, void *priv)
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
ret = pcjr->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
case 0x3d7:
|
||||
ret = pcjr->crtc[pcjr->crtcreg];
|
||||
break;
|
||||
|
||||
@@ -591,8 +615,6 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
case 0x61:
|
||||
pcjr->pb = val;
|
||||
|
||||
timer_process();
|
||||
|
||||
if (cassette != NULL)
|
||||
pc_cas_set_motor(cassette, (pcjr->pb & 0x08) == 0);
|
||||
|
||||
@@ -647,7 +669,9 @@ kbd_read(uint16_t port, void *priv)
|
||||
|
||||
case 0x62:
|
||||
ret = (pcjr->latched ? 1 : 0);
|
||||
ret |= 0x02; /*Modem card not installed*/
|
||||
ret |= 0x02; /* Modem card not installed */
|
||||
if (mem_size < 128)
|
||||
ret |= 0x08; /* 64k expansion card not installed */
|
||||
if ((pcjr->pb & 0x08) || (cassette == NULL))
|
||||
ret |= (ppispeakon ? 0x10 : 0);
|
||||
else
|
||||
@@ -810,6 +834,8 @@ machine_pcjr_init(UNUSED(const machine_t *model))
|
||||
pcjr = malloc(sizeof(pcjr_t));
|
||||
memset(pcjr, 0x00, sizeof(pcjr_t));
|
||||
pcjr->memctrl = -1;
|
||||
if (mem_size < 128)
|
||||
pcjr->memctrl &= ~0x24;
|
||||
display_type = machine_get_config_int("display_type");
|
||||
pcjr->composite = (display_type != PCJR_RGB);
|
||||
|
||||
@@ -853,7 +879,10 @@ machine_pcjr_init(UNUSED(const machine_t *model))
|
||||
device_add(&ns8250_pcjr_device);
|
||||
serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */
|
||||
|
||||
/* "All the inputs are 'read' with one 'IN' from address hex 201." - PCjr Technical Reference (Nov. 83), p.2-119 */
|
||||
/* "All the inputs are 'read' with one 'IN' from address hex 201." - PCjr Technical Reference (Nov. 83), p.2-119
|
||||
|
||||
Note by Miran Grca: Meanwhile, the same Technical Reference clearly says that
|
||||
the gameport is on ports 201-207. */
|
||||
standalone_gameport_type = &gameport_201_device;
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -108,7 +108,7 @@ machine_init_ex(int m)
|
||||
/* Reset the fast off stuff. */
|
||||
cpu_fast_off_reset();
|
||||
|
||||
pci_take_over_io = 0x00000000;
|
||||
pci_flags = 0x00000000;
|
||||
}
|
||||
|
||||
/* All good, boot the machine! */
|
||||
|
||||
@@ -303,7 +303,7 @@ const machine_t machines[] = {
|
||||
.bus_flags = MACHINE_PCJR,
|
||||
.flags = MACHINE_VIDEO_FIXED,
|
||||
.ram = {
|
||||
.min = 128,
|
||||
.min = 64,
|
||||
.max = 640,
|
||||
.step = 64
|
||||
},
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(mem OBJECT 815ep_spd_hack.c catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c rom.c
|
||||
row.c smram.c spd.c sst_flash.c)
|
||||
add_library(mem OBJECT 815ep_spd_hack.c catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c mmu_2386.c
|
||||
rom.c row.c smram.c spd.c sst_flash.c)
|
||||
|
||||
@@ -119,14 +119,15 @@ int purgeable_page_count = 0;
|
||||
|
||||
uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */
|
||||
|
||||
mem_mapping_t *read_mapping[MEM_MAPPINGS_NO];
|
||||
mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];
|
||||
|
||||
/* FIXME: re-do this with a 'mem_ops' struct. */
|
||||
static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */
|
||||
static uint8_t *readlookupp;
|
||||
static uint8_t *writelookupp;
|
||||
static mem_mapping_t *base_mapping;
|
||||
static mem_mapping_t *last_mapping;
|
||||
static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO];
|
||||
static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];
|
||||
static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO];
|
||||
static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO];
|
||||
static uint8_t *_mem_exec[MEM_MAPPINGS_NO];
|
||||
|
||||
901
src/mem/mmu_2386.c
Normal file
901
src/mem/mmu_2386.c
Normal file
@@ -0,0 +1,901 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Memory handling and MMU.
|
||||
*
|
||||
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/version.h>
|
||||
#include "cpu.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86.h"
|
||||
#include <86box/machine.h>
|
||||
#include <86box/m_xt_xi8088.h>
|
||||
#include <86box/config.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/gdbstub.h>
|
||||
#ifdef USE_DYNAREC
|
||||
# include "codegen_public.h"
|
||||
#else
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# define PAGE_MASK_SHIFT 6
|
||||
#else
|
||||
# define PAGE_MASK_INDEX_MASK 3
|
||||
# define PAGE_MASK_INDEX_SHIFT 10
|
||||
# define PAGE_MASK_SHIFT 4
|
||||
#endif
|
||||
# define PAGE_MASK_MASK 63
|
||||
#endif
|
||||
#if (!defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
#define BLOCK_PC_INVALID 0xffffffff
|
||||
#define BLOCK_INVALID 0
|
||||
#endif
|
||||
|
||||
|
||||
#define mmutranslate_read_2386(addr) mmutranslatereal_2386(addr,0)
|
||||
#define mmutranslate_write_2386(addr) mmutranslatereal_2386(addr,1)
|
||||
|
||||
|
||||
uint64_t
|
||||
mmutranslatereal_2386(uint32_t addr, int rw)
|
||||
{
|
||||
uint32_t temp, temp2, temp3;
|
||||
uint32_t addr2;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
return 0xffffffffffffffffULL;
|
||||
|
||||
addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
|
||||
temp = temp2 = mem_readl_phys(addr2);
|
||||
if (!(temp & 1)) {
|
||||
cr2 = addr;
|
||||
temp &= 1;
|
||||
if (CPL == 3) temp |= 4;
|
||||
if (rw) temp |= 2;
|
||||
cpu_state.abrt = ABRT_PF;
|
||||
abrt_error = temp;
|
||||
return 0xffffffffffffffffULL;
|
||||
}
|
||||
|
||||
temp = mem_readl_phys((temp & ~0xfff) + ((addr >> 10) & 0xffc));
|
||||
temp3 = temp & temp2;
|
||||
if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) {
|
||||
cr2 = addr;
|
||||
temp &= 1;
|
||||
if (CPL == 3)
|
||||
temp |= 4;
|
||||
if (rw)
|
||||
temp |= 2;
|
||||
cpu_state.abrt = ABRT_PF;
|
||||
abrt_error = temp;
|
||||
return 0xffffffffffffffffULL;
|
||||
}
|
||||
|
||||
mmu_perm = temp & 4;
|
||||
mem_writel_phys(addr2, mem_readl_phys(addr) | 0x20);
|
||||
mem_writel_phys((temp2 & ~0xfff) + ((addr >> 10) & 0xffc), mem_readl_phys((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) | (rw ? 0x60 : 0x20));
|
||||
|
||||
return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff));
|
||||
}
|
||||
|
||||
|
||||
uint64_t
|
||||
mmutranslate_noabrt_2386(uint32_t addr, int rw)
|
||||
{
|
||||
uint32_t temp,temp2,temp3;
|
||||
uint32_t addr2;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
return 0xffffffffffffffffULL;
|
||||
|
||||
addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
|
||||
temp = temp2 = mem_readl_phys(addr2);
|
||||
|
||||
if (! (temp & 1))
|
||||
return 0xffffffffffffffffULL;
|
||||
|
||||
temp = mem_readl_phys((temp & ~0xfff) + ((addr >> 10) & 0xffc));
|
||||
temp3 = temp & temp2;
|
||||
|
||||
if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG))))
|
||||
return 0xffffffffffffffffULL;
|
||||
|
||||
return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff));
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
readmembl_2386(uint32_t addr)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
uint64_t a;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
|
||||
|
||||
addr64 = (uint64_t) addr;
|
||||
mem_logical_addr = addr;
|
||||
|
||||
high_page = 0;
|
||||
|
||||
if (cr0 >> 31) {
|
||||
a = mmutranslate_read_2386(addr);
|
||||
addr64 = (uint32_t) a;
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return 0xff;
|
||||
}
|
||||
addr = (uint32_t) (addr64 & rammask);
|
||||
|
||||
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
if (map && map->read_b)
|
||||
return map->read_b(addr, map->priv);
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
writemembl_2386(uint32_t addr, uint8_t val)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
uint64_t a;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
|
||||
|
||||
addr64 = (uint64_t) addr;
|
||||
mem_logical_addr = addr;
|
||||
|
||||
high_page = 0;
|
||||
|
||||
if (cr0 >> 31) {
|
||||
a = mmutranslate_write_2386(addr);
|
||||
addr64 = (uint32_t) a;
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return;
|
||||
}
|
||||
addr = (uint32_t) (addr64 & rammask);
|
||||
|
||||
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
if (map && map->write_b)
|
||||
map->write_b(addr, val, map->priv);
|
||||
}
|
||||
|
||||
|
||||
/* Read a byte from memory without MMU translation - result of previous MMU translation passed as value. */
|
||||
uint8_t
|
||||
readmembl_no_mmut_2386(uint32_t addr, uint32_t a64)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return 0xff;
|
||||
|
||||
addr = a64 & rammask;
|
||||
} else
|
||||
addr &= rammask;
|
||||
|
||||
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
if (map && map->read_b)
|
||||
return map->read_b(addr, map->priv);
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
/* Write a byte to memory without MMU translation - result of previous MMU translation passed as value. */
|
||||
void
|
||||
writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return;
|
||||
|
||||
addr = a64 & rammask;
|
||||
} else
|
||||
addr &= rammask;
|
||||
|
||||
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
if (map && map->write_b)
|
||||
map->write_b(addr, val, map->priv);
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
readmemwl_2386(uint32_t addr)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
int i;
|
||||
uint64_t a;
|
||||
|
||||
addr64a[0] = addr;
|
||||
addr64a[1] = addr + 1;
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
high_page = 0;
|
||||
|
||||
if (addr & 1) {
|
||||
if (!cpu_cyrix_alignment || (addr & 7) == 7)
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xffe) {
|
||||
if (cr0 >> 31) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
a = mmutranslate_read_2386(addr + i);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
return readmembl_no_mmut(addr, addr64a[0]) |
|
||||
(((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
a = mmutranslate_read_2386(addr);
|
||||
addr64a[0] = (uint32_t) a;
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return 0xffff;
|
||||
} else
|
||||
addr64a[0] = (uint64_t) addr;
|
||||
|
||||
addr = addr64a[0] & rammask;
|
||||
|
||||
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
if (map && map->read_w)
|
||||
return map->read_w(addr, map->priv);
|
||||
|
||||
if (map && map->read_b) {
|
||||
return map->read_b(addr, map->priv) |
|
||||
((uint16_t) (map->read_b(addr + 1, map->priv)) << 8);
|
||||
}
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
writememwl_2386(uint32_t addr, uint16_t val)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
int i;
|
||||
uint64_t a;
|
||||
|
||||
addr64a[0] = addr;
|
||||
addr64a[1] = addr + 1;
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
high_page = 0;
|
||||
|
||||
if (addr & 1) {
|
||||
if (!cpu_cyrix_alignment || (addr & 7) == 7)
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xffe) {
|
||||
if (cr0 >> 31) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
a = mmutranslate_write_2386(addr + i);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
|
||||
their result as a parameter to be used if needed. */
|
||||
writemembl_no_mmut(addr, addr64a[0], val);
|
||||
writemembl_no_mmut(addr + 1, addr64a[1], val >> 8);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
a = mmutranslate_write_2386(addr);
|
||||
addr64a[0] = (uint32_t) a;
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return;
|
||||
}
|
||||
|
||||
addr = addr64a[0] & rammask;
|
||||
|
||||
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
if (map && map->write_w) {
|
||||
map->write_w(addr, val, map->priv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (map && map->write_b) {
|
||||
map->write_b(addr, val, map->priv);
|
||||
map->write_b(addr + 1, val >> 8, map->priv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Read a word from memory without MMU translation - results of previous MMU translation passed as array. */
|
||||
uint16_t
|
||||
readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
if (addr & 1) {
|
||||
if (!cpu_cyrix_alignment || (addr & 7) == 7)
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xffe) {
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
return readmembl_no_mmut(addr, a64[0]) |
|
||||
(((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return 0xffff;
|
||||
|
||||
addr = (uint32_t) (a64[0] & rammask);
|
||||
} else
|
||||
addr &= rammask;
|
||||
|
||||
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
if (map && map->read_w)
|
||||
return map->read_w(addr, map->priv);
|
||||
|
||||
if (map && map->read_b) {
|
||||
return map->read_b(addr, map->priv) |
|
||||
((uint16_t) (map->read_b(addr + 1, map->priv)) << 8);
|
||||
}
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
|
||||
/* Write a word to memory without MMU translation - results of previous MMU translation passed as array. */
|
||||
void
|
||||
writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
if (addr & 1) {
|
||||
if (!cpu_cyrix_alignment || (addr & 7) == 7)
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xffe) {
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return;
|
||||
}
|
||||
|
||||
writemembl_no_mmut(addr, a64[0], val);
|
||||
writemembl_no_mmut(addr + 1, a64[1], val >> 8);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return;
|
||||
|
||||
addr = (uint32_t) (a64[0] & rammask);
|
||||
} else
|
||||
addr &= rammask;
|
||||
|
||||
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
if (map && map->write_w) {
|
||||
map->write_w(addr, val, map->priv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (map && map->write_b) {
|
||||
map->write_b(addr, val, map->priv);
|
||||
map->write_b(addr + 1, val >> 8, map->priv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
readmemll_2386(uint32_t addr)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
high_page = 0;
|
||||
|
||||
if (addr & 3) {
|
||||
if (!cpu_cyrix_alignment || (addr & 7) > 4)
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xffc) {
|
||||
if (cr0 >> 31) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (i == 0) {
|
||||
a = mmutranslate_read_2386(addr + i);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
} else if (!((addr + i) & 0xfff)) {
|
||||
a = mmutranslate_read_2386(addr + 3);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
if (!cpu_state.abrt) {
|
||||
a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff));
|
||||
addr64a[i] = (uint32_t) a;
|
||||
}
|
||||
} else {
|
||||
a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff));
|
||||
addr64a[i] = (uint32_t) a;
|
||||
}
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
|
||||
their result as a parameter to be used if needed. */
|
||||
return readmemwl_no_mmut(addr, addr64a) |
|
||||
(((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16);
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
a = mmutranslate_read_2386(addr);
|
||||
addr64a[0] = (uint32_t) a;
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
addr = addr64a[0] & rammask;
|
||||
|
||||
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
if (map && map->read_l)
|
||||
return map->read_l(addr, map->priv);
|
||||
|
||||
if (map && map->read_w)
|
||||
return map->read_w(addr, map->priv) |
|
||||
((uint32_t) (map->read_w(addr + 2, map->priv)) << 16);
|
||||
|
||||
if (map && map->read_b)
|
||||
return map->read_b(addr, map->priv) |
|
||||
((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) |
|
||||
((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) |
|
||||
((uint32_t) (map->read_b(addr + 3, map->priv)) << 24);
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
writememll_2386(uint32_t addr, uint32_t val)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
high_page = 0;
|
||||
|
||||
if (addr & 3) {
|
||||
if (!cpu_cyrix_alignment || (addr & 7) > 4)
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xffc) {
|
||||
if (cr0 >> 31) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (i == 0) {
|
||||
a = mmutranslate_write_2386(addr + i);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
} else if (!((addr + i) & 0xfff)) {
|
||||
a = mmutranslate_write_2386(addr + 3);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
if (!cpu_state.abrt) {
|
||||
a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff));
|
||||
addr64a[i] = (uint32_t) a;
|
||||
}
|
||||
} else {
|
||||
a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff));
|
||||
addr64a[i] = (uint32_t) a;
|
||||
}
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
|
||||
their result as a parameter to be used if needed. */
|
||||
writememwl_no_mmut(addr, &(addr64a[0]), val);
|
||||
writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
a = mmutranslate_write_2386(addr);
|
||||
addr64a[0] = (uint32_t) a;
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return;
|
||||
}
|
||||
|
||||
addr = addr64a[0] & rammask;
|
||||
|
||||
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
if (map && map->write_l) {
|
||||
map->write_l(addr, val, map->priv);
|
||||
return;
|
||||
}
|
||||
if (map && map->write_w) {
|
||||
map->write_w(addr, val, map->priv);
|
||||
map->write_w(addr + 2, val >> 16, map->priv);
|
||||
return;
|
||||
}
|
||||
if (map && map->write_b) {
|
||||
map->write_b(addr, val, map->priv);
|
||||
map->write_b(addr + 1, val >> 8, map->priv);
|
||||
map->write_b(addr + 2, val >> 16, map->priv);
|
||||
map->write_b(addr + 3, val >> 24, map->priv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Read a long from memory without MMU translation - results of previous MMU translation passed as array. */
|
||||
uint32_t
|
||||
readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
if (addr & 3) {
|
||||
if (!cpu_cyrix_alignment || (addr & 7) > 4)
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xffc) {
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
return readmemwl_no_mmut(addr, a64) |
|
||||
((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16);
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return 0xffffffff;
|
||||
|
||||
addr = (uint32_t) (a64[0] & rammask);
|
||||
} else
|
||||
addr &= rammask;
|
||||
|
||||
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
if (map && map->read_l)
|
||||
return map->read_l(addr, map->priv);
|
||||
|
||||
if (map && map->read_w)
|
||||
return map->read_w(addr, map->priv) |
|
||||
((uint32_t) (map->read_w(addr + 2, map->priv)) << 16);
|
||||
|
||||
if (map && map->read_b)
|
||||
return map->read_b(addr, map->priv) |
|
||||
((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) |
|
||||
((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) |
|
||||
((uint32_t) (map->read_b(addr + 3, map->priv)) << 24);
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
/* Write a long to memory without MMU translation - results of previous MMU translation passed as array. */
|
||||
void
|
||||
writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
if (addr & 3) {
|
||||
if (!cpu_cyrix_alignment || (addr & 7) > 4)
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xffc) {
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return;
|
||||
}
|
||||
|
||||
writememwl_no_mmut(addr, &(a64[0]), val);
|
||||
writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
if (cpu_state.abrt || high_page)
|
||||
return;
|
||||
|
||||
addr = (uint32_t) (a64[0] & rammask);
|
||||
} else
|
||||
addr &= rammask;
|
||||
|
||||
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
if (map && map->write_l) {
|
||||
map->write_l(addr, val, map->priv);
|
||||
return;
|
||||
}
|
||||
if (map && map->write_w) {
|
||||
map->write_w(addr, val, map->priv);
|
||||
map->write_w(addr + 2, val >> 16, map->priv);
|
||||
return;
|
||||
}
|
||||
if (map && map->write_b) {
|
||||
map->write_b(addr, val, map->priv);
|
||||
map->write_b(addr + 1, val >> 8, map->priv);
|
||||
map->write_b(addr + 2, val >> 16, map->priv);
|
||||
map->write_b(addr + 3, val >> 24, map->priv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint64_t
|
||||
readmemql_2386(uint32_t addr)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
high_page = 0;
|
||||
|
||||
if (addr & 7) {
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xff8) {
|
||||
if (cr0 >> 31) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i == 0) {
|
||||
a = mmutranslate_read_2386(addr + i);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
} else if (!((addr + i) & 0xfff)) {
|
||||
a = mmutranslate_read_2386(addr + 7);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
if (!cpu_state.abrt) {
|
||||
a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff));
|
||||
addr64a[i] = (uint32_t) a;
|
||||
}
|
||||
} else {
|
||||
a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff));
|
||||
addr64a[i] = (uint32_t) a;
|
||||
}
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
|
||||
their result as a parameter to be used if needed. */
|
||||
return readmemll_no_mmut(addr, addr64a) |
|
||||
(((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32);
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
a = mmutranslate_read_2386(addr);
|
||||
addr64a[0] = (uint32_t) a;
|
||||
|
||||
if (a > 0xffffffffULL)
|
||||
return 0xffffffffffffffffULL;
|
||||
}
|
||||
|
||||
addr = addr64a[0] & rammask;
|
||||
|
||||
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
if (map && map->read_l)
|
||||
return map->read_l(addr, map->priv) | ((uint64_t)map->read_l(addr + 4, map->priv) << 32);
|
||||
|
||||
return readmemll(addr) | ((uint64_t) readmemll(addr + 4) << 32);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
writememql_2386(uint32_t addr, uint64_t val)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
|
||||
high_page = 0;
|
||||
|
||||
if (addr & 7) {
|
||||
cycles -= timing_misaligned;
|
||||
if ((addr & 0xfff) > 0xff8) {
|
||||
if (cr0 >> 31) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i == 0) {
|
||||
a = mmutranslate_write_2386(addr + i);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
} else if (!((addr + i) & 0xfff)) {
|
||||
a = mmutranslate_write_2386(addr + 7);
|
||||
addr64a[i] = (uint32_t) a;
|
||||
if (!cpu_state.abrt) {
|
||||
a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff));
|
||||
addr64a[i] = (uint32_t) a;
|
||||
}
|
||||
} else {
|
||||
a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff));
|
||||
addr64a[i] = (uint32_t) a;
|
||||
}
|
||||
|
||||
if (addr64a[i] > 0xffffffffULL)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
|
||||
their result as a parameter to be used if needed. */
|
||||
writememll_no_mmut(addr, addr64a, val);
|
||||
writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cr0 >> 31) {
|
||||
addr64a[0] = mmutranslate_write_2386(addr);
|
||||
if (addr64a[0] > 0xffffffffULL)
|
||||
return;
|
||||
}
|
||||
|
||||
addr = addr64a[0] & rammask;
|
||||
|
||||
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
|
||||
if (map && map->write_l) {
|
||||
map->write_l(addr, val, map->priv);
|
||||
map->write_l(addr + 4, val >> 32, map->priv);
|
||||
return;
|
||||
}
|
||||
if (map && map->write_w) {
|
||||
map->write_w(addr, val, map->priv);
|
||||
map->write_w(addr + 2, val >> 16, map->priv);
|
||||
map->write_w(addr + 4, val >> 32, map->priv);
|
||||
map->write_w(addr + 6, val >> 48, map->priv);
|
||||
return;
|
||||
}
|
||||
if (map && map->write_b) {
|
||||
map->write_b(addr, val, map->priv);
|
||||
map->write_b(addr + 1, val >> 8, map->priv);
|
||||
map->write_b(addr + 2, val >> 16, map->priv);
|
||||
map->write_b(addr + 3, val >> 24, map->priv);
|
||||
map->write_b(addr + 4, val >> 32, map->priv);
|
||||
map->write_b(addr + 5, val >> 40, map->priv);
|
||||
map->write_b(addr + 6, val >> 48, map->priv);
|
||||
map->write_b(addr + 7, val >> 56, map->priv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write)
|
||||
{
|
||||
int i;
|
||||
uint32_t last_addr = addr + (num - 1);
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
a64[i] = (uint64_t) addr;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (cr0 >> 31) {
|
||||
/* If we have encountered at least one page fault, mark all subsequent addresses as
|
||||
having page faulted, prevents false negatives in readmem*l_no_mmut. */
|
||||
if ((i > 0) && cpu_state.abrt && !high_page)
|
||||
a64[i] = a64[i - 1];
|
||||
/* If we are on the same page, there is no need to translate again, as we can just
|
||||
reuse the previous result. */
|
||||
else if (i == 0) {
|
||||
a = mmutranslatereal_2386(addr, write);
|
||||
a64[i] = (uint32_t) a;
|
||||
} else if (!(addr & 0xfff)) {
|
||||
a = mmutranslatereal_2386(last_addr, write);
|
||||
a64[i] = (uint32_t) a;
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
|
||||
a64[i] = (uint32_t) a;
|
||||
}
|
||||
} else {
|
||||
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
|
||||
a64[i] = (uint32_t) a;
|
||||
}
|
||||
}
|
||||
|
||||
addr++;
|
||||
}
|
||||
}
|
||||
@@ -97,36 +97,45 @@ static uint8_t rtl8019as_pnp_rom[] = {
|
||||
|
||||
typedef struct nic_t {
|
||||
dp8390_t *dp8390;
|
||||
|
||||
const char *name;
|
||||
|
||||
uint8_t pnp_csnsav;
|
||||
uint8_t pci_slot;
|
||||
uint8_t irq_state;
|
||||
uint8_t pad;
|
||||
|
||||
/* RTL8019AS/RTL8029AS registers */
|
||||
uint8_t config0;
|
||||
uint8_t config2;
|
||||
uint8_t config3;
|
||||
uint8_t _9346cr;
|
||||
|
||||
uint8_t pci_regs[PCI_REGSIZE];
|
||||
uint8_t eeprom[128]; /* for RTL8029AS */
|
||||
|
||||
uint8_t maclocal[6]; /* configured MAC (local) address */
|
||||
|
||||
/* POS registers, MCA boards only */
|
||||
uint8_t pos_regs[8];
|
||||
|
||||
int board;
|
||||
int is_pci;
|
||||
int is_mca;
|
||||
int is_8bit;
|
||||
uint32_t base_address;
|
||||
int base_irq;
|
||||
int has_bios;
|
||||
|
||||
uint32_t base_address;
|
||||
uint32_t bios_addr;
|
||||
uint32_t bios_size;
|
||||
uint32_t bios_mask;
|
||||
int card; /* PCI card slot */
|
||||
int has_bios;
|
||||
int pad;
|
||||
|
||||
bar_t pci_bar[2];
|
||||
uint8_t pci_regs[PCI_REGSIZE];
|
||||
uint8_t eeprom[128]; /* for RTL8029AS */
|
||||
|
||||
rom_t bios_rom;
|
||||
|
||||
void *pnp_card;
|
||||
uint8_t pnp_csnsav;
|
||||
uint8_t maclocal[6]; /* configured MAC (local) address */
|
||||
|
||||
/* RTL8019AS/RTL8029AS registers */
|
||||
uint8_t config0;
|
||||
uint8_t config2;
|
||||
uint8_t config3;
|
||||
uint8_t _9346cr;
|
||||
uint32_t pad0;
|
||||
|
||||
/* POS registers, MCA boards only */
|
||||
uint8_t pos_regs[8];
|
||||
} nic_t;
|
||||
|
||||
#ifdef ENABLE_NE2K_LOG
|
||||
@@ -150,13 +159,13 @@ nelog(int lvl, const char *fmt, ...)
|
||||
static void
|
||||
nic_interrupt(void *priv, int set)
|
||||
{
|
||||
const nic_t *dev = (nic_t *) priv;
|
||||
nic_t *dev = (nic_t *) priv;
|
||||
|
||||
if (dev->is_pci) {
|
||||
if (set)
|
||||
pci_set_irq(dev->card, PCI_INTA);
|
||||
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->card, PCI_INTA);
|
||||
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
|
||||
} else {
|
||||
if (set)
|
||||
picint(1 << dev->base_irq);
|
||||
@@ -1087,8 +1096,7 @@ nic_init(const device_t *info)
|
||||
mem_mapping_disable(&dev->bios_rom.mapping);
|
||||
|
||||
/* Add device to the PCI bus, keep its slot number. */
|
||||
dev->card = pci_add_card(PCI_ADD_NORMAL,
|
||||
nic_pci_read, nic_pci_write, dev);
|
||||
pci_add_card(PCI_ADD_NORMAL, nic_pci_read, nic_pci_write, dev, &dev->pci_slot);
|
||||
}
|
||||
|
||||
/* Initialize the RTL8029 EEPROM. */
|
||||
|
||||
@@ -216,7 +216,8 @@ typedef struct {
|
||||
uint32_t base_address;
|
||||
int base_irq;
|
||||
int dma_channel;
|
||||
int card; /* PCI card slot */
|
||||
uint8_t pci_slot; /* PCI card slot */
|
||||
uint8_t irq_state;
|
||||
int xmit_pos;
|
||||
/** Register Address Pointer */
|
||||
uint32_t u32RAP;
|
||||
@@ -413,9 +414,9 @@ pcnet_do_irq(nic_t *dev, int issue)
|
||||
{
|
||||
if (dev->is_pci) {
|
||||
if (issue)
|
||||
pci_set_irq(dev->card, PCI_INTA);
|
||||
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->card, PCI_INTA);
|
||||
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
|
||||
} else {
|
||||
if (issue)
|
||||
picint(1 << dev->base_irq);
|
||||
@@ -2995,8 +2996,7 @@ pcnet_init(const device_t *info)
|
||||
pcnet_pci_regs[0x04] = 3;
|
||||
|
||||
/* Add device to the PCI bus, keep its slot number. */
|
||||
dev->card = pci_add_card(PCI_ADD_NORMAL,
|
||||
pcnet_pci_read, pcnet_pci_write, dev);
|
||||
pci_add_card(PCI_ADD_NORMAL, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot);
|
||||
} else if (dev->board == DEV_AM79C961) {
|
||||
dev->dma_channel = -1;
|
||||
|
||||
|
||||
108
src/nvr_at.c
108
src/nvr_at.c
@@ -306,7 +306,7 @@ typedef struct local_t {
|
||||
uint8_t read_addr;
|
||||
uint8_t wp_0d;
|
||||
uint8_t wp_32;
|
||||
uint8_t pad;
|
||||
uint8_t irq_state;
|
||||
uint8_t pad0;
|
||||
|
||||
uint8_t addr[8];
|
||||
@@ -434,6 +434,21 @@ check_alarm_via(nvr_t *nvr, int8_t addr, int8_t addr_2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
timer_update_irq(nvr_t *nvr)
|
||||
{
|
||||
local_t *local = (local_t *) nvr->data;
|
||||
uint8_t irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & (REGB_UIE | REGB_AIE | REGB_PIE);
|
||||
|
||||
if (irq) {
|
||||
nvr->regs[RTC_REGC] |= REGC_IRQF;
|
||||
picintlevel(1 << nvr->irq, &local->irq_state);
|
||||
} else {
|
||||
nvr->regs[RTC_REGC] &= ~REGC_IRQF;
|
||||
picintclevel(1 << nvr->irq, &local->irq_state);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the NVR registers from the internal clock. */
|
||||
static void
|
||||
timer_update(void *priv)
|
||||
@@ -442,45 +457,38 @@ timer_update(void *priv)
|
||||
local_t *local = (local_t *) nvr->data;
|
||||
struct tm tm;
|
||||
|
||||
local->ecount = 0LL;
|
||||
if (local->ecount == (244ULL * TIMER_USEC)) {
|
||||
rtc_tick();
|
||||
|
||||
if (!(nvr->regs[RTC_REGB] & REGB_SET)) {
|
||||
/* Get the current time from the internal clock. */
|
||||
nvr_time_get(&tm);
|
||||
|
||||
/* Update registers with current time. */
|
||||
time_set(nvr, &tm);
|
||||
|
||||
/* Clear update status. */
|
||||
local->stat = 0x00;
|
||||
|
||||
/* Check for any alarms we need to handle. */
|
||||
if (check_alarm(nvr, RTC_SECONDS) && check_alarm(nvr, RTC_MINUTES) && check_alarm(nvr, RTC_HOURS) && check_alarm_via(nvr, RTC_DOM, RTC_ALDAY) && check_alarm_via(nvr, RTC_MONTH, RTC_ALMONTH) /* &&
|
||||
check_alarm_via(nvr, RTC_DOM, RTC_ALDAY_SIS) &&
|
||||
check_alarm_via(nvr, RTC_MONTH, RTC_ALMONT_SIS)*/
|
||||
) {
|
||||
if (check_alarm(nvr, RTC_SECONDS) && check_alarm(nvr, RTC_MINUTES) && check_alarm(nvr, RTC_HOURS) &&
|
||||
check_alarm_via(nvr, RTC_DOM, RTC_ALDAY) && check_alarm_via(nvr, RTC_MONTH, RTC_ALMONTH) /* &&
|
||||
check_alarm_via(nvr, RTC_DOM, RTC_ALDAY_SIS) && check_alarm_via(nvr, RTC_MONTH, RTC_ALMONT_SIS) */) {
|
||||
nvr->regs[RTC_REGC] |= REGC_AF;
|
||||
if (nvr->regs[RTC_REGB] & REGB_AIE) {
|
||||
/* Generate an interrupt. */
|
||||
if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) {
|
||||
picintlevel(1 << nvr->irq);
|
||||
nvr->regs[RTC_REGC] |= REGC_IRQF;
|
||||
}
|
||||
}
|
||||
timer_update_irq(nvr);
|
||||
}
|
||||
|
||||
/* Schedule the end of the update. */
|
||||
local->ecount = 1984ULL * TIMER_USEC;
|
||||
timer_set_delay_u64(&local->update_timer, local->ecount);
|
||||
} else {
|
||||
/*
|
||||
* The flag and interrupt should be issued
|
||||
* on update ended, not started.
|
||||
*/
|
||||
nvr->regs[RTC_REGC] |= REGC_UF;
|
||||
if (nvr->regs[RTC_REGB] & REGB_UIE) {
|
||||
/* Generate an interrupt. */
|
||||
if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) {
|
||||
picintlevel(1 << nvr->irq);
|
||||
nvr->regs[RTC_REGC] |= REGC_IRQF;
|
||||
}
|
||||
}
|
||||
timer_update_irq(nvr);
|
||||
|
||||
/* Clear update status. */
|
||||
local->stat = 0x00;
|
||||
|
||||
local->ecount = 0LL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,13 +533,7 @@ timer_intr(void *priv)
|
||||
timer_load_count(nvr);
|
||||
|
||||
nvr->regs[RTC_REGC] |= REGC_PF;
|
||||
if (nvr->regs[RTC_REGB] & REGB_PIE) {
|
||||
/* Generate an interrupt. */
|
||||
if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) {
|
||||
picintlevel(1 << nvr->irq);
|
||||
nvr->regs[RTC_REGC] |= REGC_IRQF;
|
||||
}
|
||||
}
|
||||
timer_update_irq(nvr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,15 +543,14 @@ timer_tick(nvr_t *nvr)
|
||||
{
|
||||
local_t *local = (local_t *) nvr->data;
|
||||
|
||||
/* Only update it there is no SET in progress. */
|
||||
if (!(nvr->regs[RTC_REGB] & REGB_SET)) {
|
||||
/* Only update it there is no SET in progress.
|
||||
Also avoid updating it is DV2-DV0 are not set to 0, 1, 0. */
|
||||
if (((nvr->regs[RTC_REGA] & 0x70) == 0x20) && !(nvr->regs[RTC_REGB] & REGB_SET)) {
|
||||
/* Set the UIP bit, announcing the update. */
|
||||
local->stat = REGA_UIP;
|
||||
|
||||
rtc_tick();
|
||||
|
||||
/* Schedule the actual update. */
|
||||
local->ecount = (244ULL + 1984ULL) * TIMER_USEC;
|
||||
local->ecount = 244ULL * TIMER_USEC;
|
||||
timer_set_delay_u64(&local->update_timer, local->ecount);
|
||||
}
|
||||
}
|
||||
@@ -583,32 +584,29 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv)
|
||||
local_t *local = (local_t *) nvr->data;
|
||||
struct tm tm;
|
||||
uint8_t old;
|
||||
uint8_t irq = 0;
|
||||
uint8_t old_irq = 0;
|
||||
|
||||
old = nvr->regs[reg];
|
||||
switch (reg) {
|
||||
case RTC_SECONDS: /* bit 7 of seconds is read-only */
|
||||
nvr_reg_common_write(reg, val & 0x7f, nvr, local);
|
||||
break;
|
||||
|
||||
case RTC_REGA:
|
||||
nvr->regs[RTC_REGA] = val;
|
||||
timer_load_count(nvr);
|
||||
if ((val & nvr->regs[RTC_REGA]) & ~REGA_UIP) {
|
||||
nvr->regs[RTC_REGA] = (nvr->regs[RTC_REGA] & REGA_UIP) | (val & ~REGA_UIP);
|
||||
timer_load_count(nvr);
|
||||
}
|
||||
break;
|
||||
|
||||
case RTC_REGB:
|
||||
old_irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70;
|
||||
nvr->regs[RTC_REGB] = val;
|
||||
if (((old ^ val) & REGB_SET) && (val & REGB_SET)) {
|
||||
/* According to the datasheet... */
|
||||
nvr->regs[RTC_REGA] &= ~REGA_UIP;
|
||||
nvr->regs[RTC_REGB] &= ~REGB_UIE;
|
||||
}
|
||||
irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70;
|
||||
if (old_irq && !irq) {
|
||||
picintc(1 << nvr->irq);
|
||||
nvr->regs[RTC_REGC] &= ~REGC_IRQF;
|
||||
} else if (!old_irq && irq) {
|
||||
picintlevel(1 << nvr->irq);
|
||||
nvr->regs[RTC_REGC] |= REGC_IRQF;
|
||||
val &= ~REGB_UIE;
|
||||
local->stat &= ~REGA_UIP;
|
||||
}
|
||||
|
||||
nvr->regs[RTC_REGB] = val;
|
||||
timer_update_irq(nvr);
|
||||
break;
|
||||
|
||||
case RTC_REGC: /* R/O */
|
||||
@@ -698,9 +696,9 @@ nvr_read(uint16_t addr, void *priv)
|
||||
break;
|
||||
|
||||
case RTC_REGC:
|
||||
ret = nvr->regs[RTC_REGC];
|
||||
picintc(1 << nvr->irq);
|
||||
nvr->regs[RTC_REGC] = 0x00;
|
||||
ret = nvr->regs[RTC_REGC] & (REGC_IRQF | REGC_PF | REGC_AF | REGC_UF);
|
||||
nvr->regs[RTC_REGC] &= ~(REGC_IRQF | REGC_PF | REGC_AF | REGC_UF);
|
||||
timer_update_irq(nvr);
|
||||
break;
|
||||
|
||||
case RTC_REGD:
|
||||
|
||||
@@ -17,17 +17,24 @@ typedef struct pci_dummy_t {
|
||||
|
||||
bar_t pci_bar[2];
|
||||
|
||||
uint8_t card;
|
||||
uint8_t pci_slot;
|
||||
uint8_t irq_state;
|
||||
uint8_t interrupt_on;
|
||||
|
||||
uint8_t irq_level;
|
||||
} pci_dummy_t;
|
||||
|
||||
static void
|
||||
pci_dummy_interrupt(int set, pci_dummy_t *dev)
|
||||
{
|
||||
if (set)
|
||||
pci_set_irq(dev->card, PCI_INTA);
|
||||
else
|
||||
pci_clear_irq(dev->card, PCI_INTA);
|
||||
if (set != dev->irq_level) {
|
||||
if (set)
|
||||
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
|
||||
}
|
||||
|
||||
dev->irq_level = set;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -160,8 +167,8 @@ pci_dummy_pci_read(int func, int addr, void *priv)
|
||||
ret = dev->pci_regs[addr];
|
||||
break;
|
||||
|
||||
case 0x08: /* Techncially, revision, but we return the card (slot) here. */
|
||||
ret = dev->card;
|
||||
case 0x08: /* Techncially, revision, but we return the slot here. */
|
||||
ret = dev->pci_slot;
|
||||
break;
|
||||
|
||||
case 0x10: /* PCI_BAR 7:5 */
|
||||
@@ -236,7 +243,7 @@ pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x3c: /* PCI_ILR */
|
||||
pclog("AB0B:071A Device %02X: IRQ now: %i\n", dev->card, val);
|
||||
pclog("AB0B:071A Device %02X: IRQ now: %i\n", dev->pci_slot, val);
|
||||
dev->pci_regs[addr] = val;
|
||||
return;
|
||||
|
||||
@@ -273,7 +280,7 @@ pci_dummy_card_init(UNUSED(const device_t *info))
|
||||
{
|
||||
pci_dummy_t *dev = (pci_dummy_t *) calloc(1, sizeof(pci_dummy_t));
|
||||
|
||||
dev->card = pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, dev);
|
||||
pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
368
src/pic.c
368
src/pic.c
@@ -51,20 +51,21 @@ pic_t pic2;
|
||||
|
||||
static pc_timer_t pic_timer;
|
||||
|
||||
static uint16_t smi_irq_mask = 0x0000;
|
||||
static uint16_t smi_irq_status = 0x0000;
|
||||
|
||||
static uint16_t enabled_latches = 0x0000;
|
||||
static uint16_t latched_irqs = 0x0000;
|
||||
|
||||
static int shadow = 0;
|
||||
static int elcr_enabled = 0;
|
||||
static int tmr_inited = 0;
|
||||
static int latched = 0;
|
||||
static int pic_pci = 0;
|
||||
static int kbd_latch = 0;
|
||||
static int mouse_latch = 0;
|
||||
|
||||
static uint16_t smi_irq_mask = 0x0000;
|
||||
static uint16_t smi_irq_status = 0x0000;
|
||||
static void (*update_pending)(void);
|
||||
|
||||
static uint16_t latched_irqs = 0x0000;
|
||||
|
||||
static void (*update_pending)(void);
|
||||
static void pic_update_request(pic_t *dev, int irq);
|
||||
static void pic_cascade(int set);
|
||||
|
||||
#ifdef ENABLE_PIC_LOG
|
||||
int pic_do_log = ENABLE_PIC_LOG;
|
||||
@@ -223,12 +224,7 @@ find_best_interrupt(pic_t *dev)
|
||||
static __inline void
|
||||
pic_update_pending_xt(void)
|
||||
{
|
||||
if (find_best_interrupt(&pic) != -1) {
|
||||
latched++;
|
||||
if (latched == 1)
|
||||
timer_on_auto(&pic_timer, 0.35);
|
||||
} else if (latched == 0)
|
||||
pic.int_pending = 0;
|
||||
pic.int_pending = (find_best_interrupt(&pic) != -1);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
@@ -236,24 +232,15 @@ pic_update_pending_at(void)
|
||||
{
|
||||
pic2.int_pending = (find_best_interrupt(&pic2) != -1);
|
||||
|
||||
if (pic2.int_pending)
|
||||
pic.irr |= (1 << pic2.icw3);
|
||||
else
|
||||
pic.irr &= ~(1 << pic2.icw3);
|
||||
pic_cascade(pic2.int_pending);
|
||||
|
||||
pic.int_pending = (find_best_interrupt(&pic) != -1);
|
||||
}
|
||||
|
||||
static void
|
||||
pic_callback(void *priv)
|
||||
pic_callback(UNUSED(void *priv))
|
||||
{
|
||||
pic_t *dev = (pic_t *) priv;
|
||||
|
||||
dev->int_pending = 1;
|
||||
|
||||
latched--;
|
||||
if (latched > 0)
|
||||
timer_on_auto(&pic_timer, 0.35);
|
||||
update_pending();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -268,8 +255,13 @@ pic_reset(void)
|
||||
pic.is_master = 1;
|
||||
pic.interrupt = pic2.interrupt = 0x17;
|
||||
|
||||
if (is_at)
|
||||
pic.has_slaves = 0;
|
||||
pic2.has_slaves = 0;
|
||||
|
||||
if (is_at) {
|
||||
pic.slaves[2] = &pic2;
|
||||
pic.has_slaves = 1;
|
||||
}
|
||||
|
||||
if (tmr_inited)
|
||||
timer_on_auto(&pic_timer, 0.0);
|
||||
@@ -326,8 +318,16 @@ pic_acknowledge(pic_t *dev)
|
||||
int pic_int_num = 1 << pic_int;
|
||||
|
||||
dev->isr |= pic_int_num;
|
||||
if (!pic_level_triggered(dev, pic_int) || !(dev->lines & pic_int_num))
|
||||
dev->irr &= ~pic_int_num;
|
||||
|
||||
/* Simulate the clearing of the edge pulse. */
|
||||
dev->edge_lines &= ~pic_int_num;
|
||||
/* Clear the edge sense latch. */
|
||||
dev->irq_latch &= ~pic_int_num;
|
||||
|
||||
dev->flags |= PIC_FREEZE; /* Freeze it so it still takes interrupts but they do not
|
||||
override the one currently being processed. */
|
||||
/* Clear the reset latch. */
|
||||
pic_update_request(dev, pic_int);
|
||||
}
|
||||
|
||||
/* Find IRQ for non-specific EOI (either by command or automatic) by finding the highest IRQ
|
||||
@@ -403,12 +403,12 @@ pic_latch_read(UNUSED(uint16_t addr), UNUSED(void *priv))
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
pic_log("pic_latch_read(%i, %i): %02X%02X\n", kbd_latch, mouse_latch, pic2.lines & 0x10, pic.lines & 0x02);
|
||||
pic_log("pic_latch_read(%04X): %02X%02X\n", enabled_latches, latched_irqs & 0x10, latched_irqs & 0x02);
|
||||
|
||||
if (kbd_latch && (latched_irqs & 0x0002))
|
||||
if ((latched_irqs & enabled_latches) & 0x0002)
|
||||
picintc(0x0002);
|
||||
|
||||
if (mouse_latch && (latched_irqs & 0x1000))
|
||||
if ((latched_irqs & enabled_latches) & 0x1000)
|
||||
picintc(0x1000);
|
||||
|
||||
/* Return FF - we just lower IRQ 1 and IRQ 12. */
|
||||
@@ -433,12 +433,8 @@ pic_read(uint16_t addr, void *priv)
|
||||
}
|
||||
} else {
|
||||
/* Standard 8259 PIC read */
|
||||
#ifndef UNDEFINED_READ
|
||||
/* Put the IRR on to the data bus by default until the real PIC is probed. */
|
||||
dev->data_bus = dev->irr;
|
||||
#endif
|
||||
if (dev->ocw3 & 0x04) {
|
||||
dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */
|
||||
dev->flags &= ~PIC_FREEZE; /* Freeze the interrupt until the poll is over. */
|
||||
if (dev->int_pending) {
|
||||
dev->data_bus = 0x80 | (dev->interrupt & 7);
|
||||
pic_acknowledge(dev);
|
||||
@@ -452,10 +448,8 @@ pic_read(uint16_t addr, void *priv)
|
||||
else if (dev->ocw3 & 0x02) {
|
||||
if (dev->ocw3 & 0x01)
|
||||
dev->data_bus = dev->isr;
|
||||
#ifdef UNDEFINED_READ
|
||||
else
|
||||
dev->data_bus = 0x00;
|
||||
#endif
|
||||
dev->data_bus = dev->irr;
|
||||
}
|
||||
/* If A0 = 0, VIA shadow is disabled, and poll mode is disabled,
|
||||
simply read whatever is currently on the data bus. */
|
||||
@@ -470,6 +464,7 @@ static void
|
||||
pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
pic_t *dev = (pic_t *) priv;
|
||||
uint8_t i;
|
||||
|
||||
pic_log("pic_write(%04X, %02X, %08X)\n", addr, val, priv);
|
||||
|
||||
@@ -494,7 +489,10 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case STATE_NONE:
|
||||
dev->imr = val;
|
||||
update_pending();
|
||||
if (is286)
|
||||
update_pending();
|
||||
else
|
||||
timer_on_auto(&pic_timer, 1.0 * ((10000000.0 * (double) xt_cpu_multi) / (double) cpu_s->rspeed));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -511,7 +509,13 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
if (!(dev->icw1 & 1))
|
||||
dev->icw4 = 0x00;
|
||||
dev->ocw2 = dev->ocw3 = 0x00;
|
||||
dev->irr = dev->lines;
|
||||
dev->irr = 0x00;
|
||||
dev->edge_lines = 0x00;
|
||||
dev->irq_latch = 0x00;
|
||||
dev->flags |= PIC_MASTER_CLEAR;
|
||||
for (i = 0; i <= 7; i++)
|
||||
pic_update_request(dev, i);
|
||||
dev->flags &= ~PIC_MASTER_CLEAR;
|
||||
dev->imr = dev->isr = 0x00;
|
||||
dev->ack_bytes = dev->priority = 0x00;
|
||||
dev->auto_eoi_rotate = dev->special_mask_mode = 0x00;
|
||||
@@ -522,7 +526,7 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
} else if (val & 0x08) {
|
||||
dev->ocw3 = val;
|
||||
if (dev->ocw3 & 0x04)
|
||||
dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */
|
||||
dev->flags |= PIC_FREEZE; /* Freeze the interrupt until the poll is over. */
|
||||
if (dev->ocw3 & 0x40)
|
||||
dev->special_mask_mode = !!(dev->ocw3 & 0x20);
|
||||
} else {
|
||||
@@ -554,12 +558,15 @@ pic_set_pci(void)
|
||||
void
|
||||
pic_kbd_latch(int enable)
|
||||
{
|
||||
uint16_t old_latches = enabled_latches;
|
||||
|
||||
pic_log("PIC keyboard latch now %sabled\n", enable ? "en" : "dis");
|
||||
|
||||
if (!!(enable | mouse_latch) != !!(kbd_latch | mouse_latch))
|
||||
io_handler(!!(enable | mouse_latch), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
enable = (!!enable) << 1;
|
||||
enabled_latches = (enabled_latches & 0x1000) | enable;
|
||||
|
||||
kbd_latch = !!enable;
|
||||
if (!!(enabled_latches & 0x1002) != !!(old_latches & 0x1002))
|
||||
io_handler(!!(enabled_latches & 0x1002), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!enable)
|
||||
picintc(0x0002);
|
||||
@@ -568,12 +575,15 @@ pic_kbd_latch(int enable)
|
||||
void
|
||||
pic_mouse_latch(int enable)
|
||||
{
|
||||
uint16_t old_latches = enabled_latches;
|
||||
|
||||
pic_log("PIC mouse latch now %sabled\n", enable ? "en" : "dis");
|
||||
|
||||
if (!!(kbd_latch | enable) != !!(kbd_latch | mouse_latch))
|
||||
io_handler(!!(kbd_latch | enable), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
enable = (!!enable) << 12;
|
||||
enabled_latches = (enabled_latches & 0x0002) | enable;
|
||||
|
||||
mouse_latch = !!enable;
|
||||
if (!!(enabled_latches & 0x1002) != !!(old_latches & 0x1002))
|
||||
io_handler(!!(enabled_latches & 0x1002), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!enable)
|
||||
picintc(0x1000);
|
||||
@@ -585,11 +595,11 @@ pic_reset_hard(void)
|
||||
pic_reset();
|
||||
|
||||
/* Explicitly reset the latches. */
|
||||
kbd_latch = mouse_latch = 0;
|
||||
enabled_latches = 0x0000;
|
||||
latched_irqs = 0x0000;
|
||||
|
||||
/* The situation is as follows: There is a giant mess when it comes to these latches on real hardware,
|
||||
to the point that there's even boards with board-level latched that get used in place of the latches
|
||||
to the point that there's even boards with board-level latches that get used in place of the latches
|
||||
on the chipset, therefore, I'm just doing this here for the sake of simplicity. */
|
||||
if (machine_has_bus(machine, MACHINE_BUS_PS2_LATCH)) {
|
||||
pic_kbd_latch(0x01);
|
||||
@@ -626,30 +636,131 @@ pic2_init(void)
|
||||
}
|
||||
|
||||
void
|
||||
picint_common(uint16_t num, int level, int set)
|
||||
pic_update_lines(pic_t *dev, uint16_t num, int level, int set, uint8_t *irq_state)
|
||||
{
|
||||
int raise;
|
||||
uint8_t b;
|
||||
uint8_t slaves = 0;
|
||||
uint8_t old_edge_lines, bit;
|
||||
|
||||
switch (level) {
|
||||
case PIC_IRQ_EDGE:
|
||||
old_edge_lines = dev->edge_lines;
|
||||
|
||||
dev->edge_lines &= ~num;
|
||||
if (set)
|
||||
dev->edge_lines |= num;
|
||||
|
||||
if ((dev->isr & num) || (dev->flags & PIC_MASTER_CLEAR))
|
||||
dev->irq_latch = (dev->irq_latch & ~num) | (dev->edge_lines & num);
|
||||
else if ((dev->edge_lines & num) && !(old_edge_lines & num))
|
||||
dev->irq_latch |= num;
|
||||
break;
|
||||
case PIC_IRQ_LEVEL:
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
bit = (1 << i);
|
||||
if ((num & bit) && ((!!*irq_state) != !!set))
|
||||
dev->lines[i] += (set ? 1 : -1);
|
||||
}
|
||||
|
||||
if ((!!*irq_state) != !!set)
|
||||
*irq_state = set;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pic_irq_get_request(pic_t *dev, int irq)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
ret = ((dev->edge_lines & (1 << irq)) || (dev->lines[irq] > 0));
|
||||
|
||||
pic_log("pic_irq_get_request(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pic_es_latch_clear(pic_t *dev, int irq)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
ret = (dev->isr & (1 << irq)) || (dev->flags & PIC_MASTER_CLEAR);
|
||||
|
||||
pic_log("pic_es_latch_clear(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pic_es_latch_out(pic_t *dev, int irq)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
ret = !((pic_es_latch_clear(dev, irq) && (dev->irq_latch & (1 << irq))) || !pic_irq_get_request(dev, irq));
|
||||
|
||||
pic_log("pic_es_latch_out(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pic_es_latch_nor(pic_t *dev, int irq)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
ret = !(pic_es_latch_out(dev, irq) || picint_is_level(irq));
|
||||
|
||||
pic_log("pic_es_latch_nor(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pic_irq_request_nor(pic_t *dev, int irq)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
ret = !(pic_es_latch_nor(dev, irq) || !pic_irq_get_request(dev, irq));
|
||||
|
||||
pic_log("pic_irq_request_nor(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
pic_update_request(pic_t *dev, int irq)
|
||||
{
|
||||
dev->irr &= ~(1 << irq);
|
||||
|
||||
if (dev->flags & PIC_FREEZE) {
|
||||
pic_log("pic_update_request(%08X, %i): FREEZE#\n", (uint32_t) (uintptr_t) dev, irq);
|
||||
} else {
|
||||
dev->irr |= (pic_irq_request_nor(dev, irq) << irq);
|
||||
pic_log("pic_update_request(%08X, %i): IRR = %02X\n", (uint32_t) (uintptr_t) dev, irq, dev->irr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pic_update_irr(pic_t *dev, uint16_t num)
|
||||
{
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (num & (1 << i))
|
||||
pic_update_request(dev, i);
|
||||
}
|
||||
|
||||
pic_log("IRQ %04x: IRR now: %02X\n", num, dev->irr);
|
||||
}
|
||||
|
||||
void
|
||||
picint_common(uint16_t num, int level, int set, uint8_t *irq_state)
|
||||
{
|
||||
pic_log("picint_common(%04X, %i, %i, %08X)\n", num, level, set, (uint32_t) (uintptr_t) irq_state);
|
||||
|
||||
set = !!set;
|
||||
|
||||
/* Make sure to ignore all slave IRQ's, and in case of AT+,
|
||||
translate IRQ 2 to IRQ 9. */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
b = (uint8_t) (1 << i);
|
||||
raise = num & b;
|
||||
|
||||
if (pic.icw3 & b) {
|
||||
slaves++;
|
||||
|
||||
if (raise) {
|
||||
num &= ~b;
|
||||
if (pic.at && (i == 2))
|
||||
num |= (1 << 9);
|
||||
}
|
||||
}
|
||||
if (num & pic.icw3) {
|
||||
num &= ~pic.icw3;
|
||||
if (pic.at)
|
||||
num |= (1 << 9);
|
||||
}
|
||||
|
||||
if (!slaves)
|
||||
if (!pic.has_slaves)
|
||||
num &= 0x00ff;
|
||||
|
||||
if (!num) {
|
||||
@@ -660,77 +771,41 @@ picint_common(uint16_t num, int level, int set)
|
||||
if (num & 0x0100)
|
||||
acpi_rtc_status = !!set;
|
||||
|
||||
if (set) {
|
||||
if (smi_irq_mask & num) {
|
||||
smi_raise();
|
||||
smi_irq_status |= num;
|
||||
}
|
||||
|
||||
if (num & 0xff00) {
|
||||
if (level)
|
||||
pic2.lines |= (num >> 8);
|
||||
|
||||
/* Latch IRQ 12 if the mouse latch is enabled. */
|
||||
if ((num & 0x1000) && mouse_latch)
|
||||
latched_irqs |= 0x1000;
|
||||
|
||||
pic2.irr |= (num >> 8);
|
||||
}
|
||||
|
||||
if (num & 0x00ff) {
|
||||
if (level)
|
||||
pic.lines |= (num & 0x00ff);
|
||||
|
||||
/* Latch IRQ 1 if the keyboard latch is enabled. */
|
||||
if (kbd_latch && (num & 0x0002))
|
||||
latched_irqs |= 0x0002;
|
||||
|
||||
pic.irr |= (num & 0x00ff);
|
||||
}
|
||||
} else {
|
||||
smi_irq_status &= ~num;
|
||||
|
||||
if (num & 0xff00) {
|
||||
pic2.lines &= ~(num >> 8);
|
||||
|
||||
/* Unlatch IRQ 12 if the mouse latch is enabled. */
|
||||
if ((num & 0x1000) && mouse_latch)
|
||||
latched_irqs &= 0xefff;
|
||||
|
||||
pic2.irr &= ~(num >> 8);
|
||||
}
|
||||
|
||||
if (num & 0x00ff) {
|
||||
pic.lines &= ~(num & 0x00ff);
|
||||
|
||||
/* Unlatch IRQ 1 if the keyboard latch is enabled. */
|
||||
if (kbd_latch && (num & 0x0002))
|
||||
latched_irqs &= 0xfffd;
|
||||
|
||||
pic.irr &= ~(num & 0x00ff);
|
||||
}
|
||||
smi_irq_status &= ~num;
|
||||
if (set && (smi_irq_mask & num)) {
|
||||
smi_raise();
|
||||
smi_irq_status |= num;
|
||||
}
|
||||
|
||||
if (!(pic.interrupt & 0x20) && !(pic2.interrupt & 0x20))
|
||||
if (num & 0xff00) {
|
||||
pic_update_lines(&pic2, num >> 8, level, set, irq_state);
|
||||
|
||||
/* Latch IRQ 12 if the mouse latch is enabled. */
|
||||
if ((num & enabled_latches) & 0x1000)
|
||||
latched_irqs = (latched_irqs & 0xefff) | (set << 12);
|
||||
|
||||
pic_update_irr(&pic2, num >> 8);
|
||||
}
|
||||
|
||||
if (num & 0x00ff) {
|
||||
pic_update_lines(&pic, num & 0x00ff, level, set, irq_state);
|
||||
|
||||
/* Latch IRQ 1 if the keyboard latch is enabled. */
|
||||
if ((num & enabled_latches) & 0x0002)
|
||||
latched_irqs = (latched_irqs & 0xfffd) | (set << 1);
|
||||
|
||||
pic_update_irr(&pic, num & 0x00ff);
|
||||
}
|
||||
|
||||
if (!(pic.flags & PIC_FREEZE) && !(pic2.flags & PIC_FREEZE))
|
||||
update_pending();
|
||||
}
|
||||
|
||||
void
|
||||
picint(uint16_t num)
|
||||
static void
|
||||
pic_cascade(int set)
|
||||
{
|
||||
picint_common(num, 0, 1);
|
||||
}
|
||||
|
||||
void
|
||||
picintlevel(uint16_t num)
|
||||
{
|
||||
picint_common(num, 1, 1);
|
||||
}
|
||||
|
||||
void
|
||||
picintc(uint16_t num)
|
||||
{
|
||||
picint_common(num, 0, 0);
|
||||
pic_update_lines(&pic, (1 << pic2.icw3), PIC_IRQ_EDGE, set, NULL);
|
||||
pic_update_irr(&pic, (1 << pic2.icw3));
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -742,15 +817,12 @@ pic_i86_mode(pic_t *dev)
|
||||
static uint8_t
|
||||
pic_irq_ack_read(pic_t *dev, int phase)
|
||||
{
|
||||
uint8_t intr = dev->interrupt & 0x47;
|
||||
uint8_t slave = intr & 0x40;
|
||||
intr &= 0x07;
|
||||
uint8_t intr = dev->interrupt & 0x07;
|
||||
uint8_t slave = dev->flags & PIC_SLAVE_PENDING;
|
||||
pic_log(" pic_irq_ack_read(%08X, %i)\n", dev, phase);
|
||||
|
||||
if (dev != NULL) {
|
||||
if (phase == 0) {
|
||||
dev->interrupt |= 0x20; /* Freeze it so it still takes interrupts but they do not
|
||||
override the one currently being processed. */
|
||||
pic_acknowledge(dev);
|
||||
if (slave)
|
||||
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
|
||||
@@ -796,7 +868,7 @@ pic_irq_ack(void)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
pic.interrupt |= 0x40; /* Mark slave pending. */
|
||||
pic.flags |= PIC_SLAVE_PENDING;
|
||||
}
|
||||
|
||||
ret = pic_irq_ack_read(&pic, pic.ack_bytes);
|
||||
@@ -804,8 +876,13 @@ pic_irq_ack(void)
|
||||
|
||||
if (pic.ack_bytes == 0) {
|
||||
/* Needed for Xi8088. */
|
||||
if (pic.interrupt & 0x40)
|
||||
if (pic.flags & PIC_SLAVE_PENDING) {
|
||||
pic2.flags &= ~PIC_FREEZE;
|
||||
pic_update_request(&pic2, pic2.interrupt & 0x07);
|
||||
pic2.interrupt = 0x17;
|
||||
}
|
||||
pic.flags &= ~(PIC_SLAVE_PENDING | PIC_FREEZE);
|
||||
pic_update_request(&pic, pic.interrupt & 0x07);
|
||||
pic.interrupt = 0x17;
|
||||
update_pending();
|
||||
}
|
||||
@@ -826,7 +903,7 @@ picinterrupt(void)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
pic.interrupt |= 0x40; /* Mark slave pending. */
|
||||
pic.flags |= PIC_SLAVE_PENDING;
|
||||
}
|
||||
|
||||
if ((pic.interrupt == 0) && (pit_devs[1].data != NULL))
|
||||
@@ -838,8 +915,13 @@ picinterrupt(void)
|
||||
pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3);
|
||||
|
||||
if (pic.ack_bytes == 0) {
|
||||
if (pic.interrupt & 0x40)
|
||||
if (pic.flags & PIC_SLAVE_PENDING) {
|
||||
pic2.flags &= ~PIC_FREEZE;
|
||||
pic_update_request(&pic2, pic2.interrupt & 0x07);
|
||||
pic2.interrupt = 0x17;
|
||||
}
|
||||
pic.flags &= ~(PIC_SLAVE_PENDING | PIC_FREEZE);
|
||||
pic_update_request(&pic, pic.interrupt & 0x07);
|
||||
pic.interrupt = 0x17;
|
||||
update_pending();
|
||||
}
|
||||
|
||||
@@ -37,21 +37,6 @@ static std::vector<std::pair<int, libevdev *>> evdev_mice;
|
||||
static std::atomic<bool> stopped = false;
|
||||
static QThread *evdev_thread;
|
||||
|
||||
static std::atomic<int> evdev_mouse_rel_x = 0, evdev_mouse_rel_y = 0;
|
||||
|
||||
void
|
||||
evdev_mouse_poll()
|
||||
{
|
||||
if (!evdev_mice.size() || !mouse_capture) {
|
||||
evdev_mouse_rel_x = 0;
|
||||
evdev_mouse_rel_y = 0;
|
||||
return;
|
||||
}
|
||||
mouse_x = evdev_mouse_rel_x;
|
||||
mouse_y = evdev_mouse_rel_y;
|
||||
evdev_mouse_rel_x = evdev_mouse_rel_y = 0;
|
||||
}
|
||||
|
||||
void
|
||||
evdev_thread_func()
|
||||
{
|
||||
@@ -67,11 +52,11 @@ evdev_thread_func()
|
||||
struct input_event ev;
|
||||
if (pfds[i].revents & POLLIN) {
|
||||
while (libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev) == 0) {
|
||||
if (ev.type == EV_REL && mouse_capture) {
|
||||
if (evdev_mice.size() && (ev.type == EV_REL) && mouse_capture) {
|
||||
if (ev.code == REL_X)
|
||||
evdev_mouse_rel_x += ev.value;
|
||||
mouse_scale_x(ev.value);
|
||||
if (ev.code == REL_Y)
|
||||
evdev_mouse_rel_y += ev.value;
|
||||
mouse_scale_y(ev.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#ifdef EVDEV_INPUT
|
||||
void evdev_init();
|
||||
void evdev_mouse_poll();
|
||||
#endif
|
||||
|
||||
@@ -17,13 +17,6 @@ extern int mouse_capture;
|
||||
extern void plat_mouse_capture(int);
|
||||
}
|
||||
|
||||
typedef struct mouseinputdata {
|
||||
int deltax, deltay, deltaz;
|
||||
int mousebuttons;
|
||||
} mouseinputdata;
|
||||
|
||||
static mouseinputdata mousedata;
|
||||
|
||||
CocoaEventFilter::~CocoaEventFilter()
|
||||
{
|
||||
}
|
||||
@@ -31,6 +24,8 @@ CocoaEventFilter::~CocoaEventFilter()
|
||||
bool
|
||||
CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result)
|
||||
{
|
||||
int b = 0;
|
||||
|
||||
if (mouse_capture) {
|
||||
if (eventType == "mac_generic_NSEvent") {
|
||||
NSEvent *event = (NSEvent *) message;
|
||||
@@ -38,12 +33,11 @@ CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message,
|
||||
|| [event type] == NSEventTypeLeftMouseDragged
|
||||
|| [event type] == NSEventTypeRightMouseDragged
|
||||
|| [event type] == NSEventTypeOtherMouseDragged) {
|
||||
mousedata.deltax += [event deltaX];
|
||||
mousedata.deltay += [event deltaY];
|
||||
mouse_scale([event deltaX], [event deltaY]);
|
||||
return true;
|
||||
}
|
||||
if ([event type] == NSEventTypeScrollWheel) {
|
||||
mousedata.deltaz += [event deltaY];
|
||||
mouse_set_z([event deltaY]);
|
||||
return true;
|
||||
}
|
||||
switch ([event type]) {
|
||||
@@ -51,27 +45,32 @@ CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message,
|
||||
return false;
|
||||
case NSEventTypeLeftMouseDown:
|
||||
{
|
||||
mousedata.mousebuttons |= 1;
|
||||
b = mouse_get_buttons_ex() | 1;
|
||||
mouse_set_buttons_ex(b);
|
||||
break;
|
||||
}
|
||||
case NSEventTypeLeftMouseUp:
|
||||
{
|
||||
mousedata.mousebuttons &= ~1;
|
||||
b = mouse_get_buttons_ex() & ~1;
|
||||
mouse_set_buttons_ex(b);
|
||||
break;
|
||||
}
|
||||
case NSEventTypeRightMouseDown:
|
||||
{
|
||||
mousedata.mousebuttons |= 2;
|
||||
b = mouse_get_buttons_ex() | 2;
|
||||
mouse_set_buttons_ex(b);
|
||||
break;
|
||||
}
|
||||
case NSEventTypeRightMouseUp:
|
||||
{
|
||||
mousedata.mousebuttons &= ~2;
|
||||
b = mouse_get_buttons_ex() & ~2;
|
||||
mouse_set_buttons_ex(b);
|
||||
break;
|
||||
}
|
||||
case NSEventTypeOtherMouseDown:
|
||||
{
|
||||
mousedata.mousebuttons |= 4;
|
||||
b = mouse_get_buttons_ex() | 4;
|
||||
mouse_set_buttons_ex(b);
|
||||
break;
|
||||
}
|
||||
case NSEventTypeOtherMouseUp:
|
||||
@@ -80,7 +79,8 @@ CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message,
|
||||
plat_mouse_capture(0);
|
||||
return true;
|
||||
}
|
||||
mousedata.mousebuttons &= ~4;
|
||||
b = mouse_get_buttons_ex() & ~4;
|
||||
mouse_set_buttons_ex(b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -89,13 +89,3 @@ CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
macos_poll_mouse()
|
||||
{
|
||||
mouse_x = mousedata.deltax;
|
||||
mouse_y = mousedata.deltay;
|
||||
mouse_z = mousedata.deltaz;
|
||||
mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0;
|
||||
mouse_buttons = mousedata.mousebuttons;
|
||||
}
|
||||
|
||||
@@ -256,7 +256,6 @@ main(int argc, char *argv[])
|
||||
auto rawInputFilter = WindowsRawInputFilter::Register(main_window);
|
||||
if (rawInputFilter) {
|
||||
app.installNativeEventFilter(rawInputFilter.get());
|
||||
QObject::connect(main_window, &MainWindow::pollMouse, (WindowsRawInputFilter *) rawInputFilter.get(), &WindowsRawInputFilter::mousePoll, Qt::DirectConnection);
|
||||
main_window->setSendKeyboardInput(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -253,8 +253,6 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
|
||||
emit updateMenuResizeOptions();
|
||||
|
||||
connect(this, &MainWindow::pollMouse, ui->stackedWidget, &RendererStack::mousePoll, Qt::DirectConnection);
|
||||
|
||||
connect(this, &MainWindow::setMouseCapture, this, [this](bool state) {
|
||||
mouse_capture = state ? 1 : 0;
|
||||
qt_mouse_capture(mouse_capture);
|
||||
@@ -630,7 +628,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
|
||||
setContextMenuPolicy(Qt::PreventContextMenu);
|
||||
/* Remove default Shift+F10 handler, which unfocuses keyboard input even with no context menu. */
|
||||
connect(new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F10), this), &QShortcut::activated, this, [this](){});
|
||||
connect(new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F10), this), &QShortcut::activated, this, [](){});
|
||||
|
||||
connect(this, &MainWindow::initRendererMonitor, this, &MainWindow::initRendererMonitorSlot);
|
||||
connect(this, &MainWindow::initRendererMonitorForNonQtThread, this, &MainWindow::initRendererMonitorSlot, Qt::BlockingQueuedConnection);
|
||||
@@ -764,7 +762,6 @@ MainWindow::initRendererMonitorSlot(int monitor_index)
|
||||
secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api);
|
||||
secondaryRenderer->setMouseTracking(true);
|
||||
}
|
||||
connect(this, &MainWindow::pollMouse, secondaryRenderer.get(), &RendererStack::mousePoll, Qt::DirectConnection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -890,6 +887,9 @@ MainWindow::on_actionSettings_triggered()
|
||||
Settings settings(this);
|
||||
settings.setModal(true);
|
||||
settings.setWindowModality(Qt::WindowModal);
|
||||
settings.setWindowFlag(Qt::CustomizeWindowHint, true);
|
||||
settings.setWindowFlag(Qt::WindowTitleHint, true);
|
||||
settings.setWindowFlag(Qt::WindowSystemMenuHint, false);
|
||||
settings.exec();
|
||||
|
||||
switch (settings.result()) {
|
||||
|
||||
@@ -39,7 +39,6 @@ signals:
|
||||
void paint(const QImage &image);
|
||||
void resizeContents(int w, int h);
|
||||
void resizeContentsMonitor(int w, int h, int monitor_index);
|
||||
void pollMouse();
|
||||
void statusBarMessage(const QString &msg);
|
||||
void updateStatusBarPanes();
|
||||
void updateStatusBarActivity(int tag, bool active);
|
||||
|
||||
@@ -49,26 +49,21 @@
|
||||
extern "C" {
|
||||
#include <86box/86box.h>
|
||||
#include <86box/config.h>
|
||||
#include <86box/mouse.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/video.h>
|
||||
|
||||
double mouse_sensitivity = 1.0;
|
||||
double mouse_x_error = 0.0, mouse_y_error = 0.0;
|
||||
#include <86box/mouse.h>
|
||||
}
|
||||
|
||||
struct mouseinputdata {
|
||||
atomic_int deltax;
|
||||
atomic_int deltay;
|
||||
atomic_int deltaz;
|
||||
atomic_int mousebuttons;
|
||||
atomic_bool mouse_tablet_in_proximity;
|
||||
|
||||
std::atomic<double> x_abs;
|
||||
std::atomic<double> y_abs;
|
||||
|
||||
char *mouse_type;
|
||||
};
|
||||
static mouseinputdata mousedata;
|
||||
|
||||
extern "C" void macos_poll_mouse();
|
||||
extern MainWindow *main_window;
|
||||
RendererStack::RendererStack(QWidget *parent, int monitor_index)
|
||||
: QStackedWidget(parent)
|
||||
@@ -78,8 +73,9 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index)
|
||||
|
||||
m_monitor_index = monitor_index;
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
char *mouse_type = getenv("EMU86BOX_MOUSE"), auto_mouse_type[16];
|
||||
if (!mouse_type || (mouse_type[0] == '\0') || !stricmp(mouse_type, "auto")) {
|
||||
char auto_mouse_type[16];
|
||||
mousedata.mouse_type = getenv("EMU86BOX_MOUSE");
|
||||
if (!mousedata.mouse_type || (mousedata.mouse_type[0] == '\0') || !stricmp(mousedata.mouse_type, "auto")) {
|
||||
if (QApplication::platformName().contains("wayland"))
|
||||
strcpy(auto_mouse_type, "wayland");
|
||||
else if (QApplication::platformName() == "eglfs")
|
||||
@@ -88,35 +84,27 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index)
|
||||
strcpy(auto_mouse_type, "xinput2");
|
||||
else
|
||||
auto_mouse_type[0] = '\0';
|
||||
mouse_type = auto_mouse_type;
|
||||
mousedata.mouse_type = auto_mouse_type;
|
||||
}
|
||||
|
||||
# ifdef WAYLAND
|
||||
if (!stricmp(mouse_type, "wayland")) {
|
||||
if (!stricmp(mousedata.mouse_type, "wayland")) {
|
||||
wl_init();
|
||||
this->mouse_poll_func = wl_mouse_poll;
|
||||
this->mouse_capture_func = wl_mouse_capture;
|
||||
this->mouse_uncapture_func = wl_mouse_uncapture;
|
||||
}
|
||||
# endif
|
||||
# ifdef EVDEV_INPUT
|
||||
if (!stricmp(mouse_type, "evdev")) {
|
||||
if (!stricmp(mousedata.mouse_type, "evdev"))
|
||||
evdev_init();
|
||||
this->mouse_poll_func = evdev_mouse_poll;
|
||||
}
|
||||
# endif
|
||||
if (!stricmp(mouse_type, "xinput2")) {
|
||||
if (!stricmp(mousedata.mouse_type, "xinput2")) {
|
||||
extern void xinput2_init();
|
||||
extern void xinput2_poll();
|
||||
extern void xinput2_exit();
|
||||
xinput2_init();
|
||||
this->mouse_poll_func = xinput2_poll;
|
||||
this->mouse_exit_func = xinput2_exit;
|
||||
}
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
this->mouse_poll_func = macos_poll_mouse;
|
||||
#endif
|
||||
}
|
||||
|
||||
RendererStack::~RendererStack()
|
||||
@@ -149,49 +137,25 @@ RendererStack::mousePoll()
|
||||
{
|
||||
if (m_monitor_index >= 1) {
|
||||
if (mouse_mode >= 1) {
|
||||
mouse_x_abs = mousedata.x_abs;
|
||||
mouse_y_abs = mousedata.y_abs;
|
||||
if (!mouse_tablet_in_proximity) {
|
||||
mouse_x_abs = mousedata.x_abs;
|
||||
mouse_y_abs = mousedata.y_abs;
|
||||
if (!mouse_tablet_in_proximity)
|
||||
mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity;
|
||||
}
|
||||
if (mousedata.mouse_tablet_in_proximity) {
|
||||
mouse_buttons = mousedata.mousebuttons;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if (mouse_mode == 0) {
|
||||
mouse_x_abs = mousedata.x_abs;
|
||||
mouse_y_abs = mousedata.y_abs;
|
||||
mouse_x_abs = mousedata.x_abs;
|
||||
mouse_y_abs = mousedata.y_abs;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__
|
||||
mouse_x = mousedata.deltax;
|
||||
mouse_y = mousedata.deltay;
|
||||
mouse_z = mousedata.deltaz;
|
||||
mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0;
|
||||
mouse_buttons = mousedata.mousebuttons;
|
||||
|
||||
if (this->mouse_poll_func)
|
||||
#endif
|
||||
this->mouse_poll_func();
|
||||
|
||||
mouse_x_abs = mousedata.x_abs;
|
||||
mouse_y_abs = mousedata.y_abs;
|
||||
mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity;
|
||||
|
||||
double scaled_x = mouse_x * mouse_sensitivity + mouse_x_error;
|
||||
double scaled_y = mouse_y * mouse_sensitivity + mouse_y_error;
|
||||
|
||||
mouse_x = static_cast<int>(scaled_x);
|
||||
mouse_y = static_cast<int>(scaled_y);
|
||||
|
||||
mouse_x_error = scaled_x - mouse_x;
|
||||
mouse_y_error = scaled_y - mouse_y;
|
||||
}
|
||||
|
||||
int ignoreNextMouseEvent = 1;
|
||||
@@ -212,8 +176,9 @@ RendererStack::mouseReleaseEvent(QMouseEvent *event)
|
||||
isMouseDown &= ~1;
|
||||
return;
|
||||
}
|
||||
if (mouse_capture || mouse_mode >= 1) {
|
||||
mousedata.mousebuttons &= ~event->button();
|
||||
if (mouse_capture || (mouse_mode >= 1)) {
|
||||
if ((mouse_mode >= 1) && ((m_monitor_index < 1) || mousedata.mouse_tablet_in_proximity))
|
||||
mouse_set_buttons_ex(mouse_get_buttons_ex() & ~event->button());
|
||||
}
|
||||
isMouseDown &= ~1;
|
||||
}
|
||||
@@ -222,8 +187,9 @@ void
|
||||
RendererStack::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
isMouseDown |= 1;
|
||||
if (mouse_capture || mouse_mode >= 1) {
|
||||
mousedata.mousebuttons |= event->button();
|
||||
if (mouse_capture || (mouse_mode >= 1)) {
|
||||
if ((mouse_mode >= 1) && ((m_monitor_index < 1) || mousedata.mouse_tablet_in_proximity))
|
||||
mouse_set_buttons_ex(mouse_get_buttons_ex() | event->button());
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
@@ -231,9 +197,7 @@ RendererStack::mousePressEvent(QMouseEvent *event)
|
||||
void
|
||||
RendererStack::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (mouse_capture) {
|
||||
mousedata.deltaz += event->pixelDelta().y();
|
||||
}
|
||||
mouse_set_z(event->pixelDelta().y());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -258,8 +222,12 @@ RendererStack::mouseMoveEvent(QMouseEvent *event)
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
mousedata.deltax += event->pos().x() - oldPos.x();
|
||||
mousedata.deltay += event->pos().y() - oldPos.y();
|
||||
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
if (!stricmp(mousedata.mouse_type, "wayland"))
|
||||
mouse_scale(event->pos().x() - oldPos.x(), event->pos().y() - oldPos.y());
|
||||
#endif
|
||||
|
||||
if (QApplication::platformName() == "eglfs") {
|
||||
leaveEvent((QEvent *) event);
|
||||
ignoreNextMouseEvent--;
|
||||
|
||||
@@ -82,9 +82,9 @@ public:
|
||||
rendererWindow->onResize(width, height);
|
||||
}
|
||||
|
||||
void (*mouse_poll_func)() = nullptr;
|
||||
void (*mouse_capture_func)(QWindow *window) = nullptr;
|
||||
void (*mouse_uncapture_func)() = nullptr;
|
||||
|
||||
void (*mouse_exit_func)() = nullptr;
|
||||
|
||||
signals:
|
||||
|
||||
@@ -198,12 +198,6 @@ static const uint16_t sdl_to_xt[0x200] = {
|
||||
[SDL_SCANCODE_NONUSBACKSLASH] = 0x56,
|
||||
};
|
||||
|
||||
typedef struct mouseinputdata {
|
||||
int deltax, deltay, deltaz;
|
||||
int mousebuttons;
|
||||
} mouseinputdata;
|
||||
static mouseinputdata mousedata;
|
||||
|
||||
// #define ENABLE_SDL_LOG 3
|
||||
#ifdef ENABLE_SDL_LOG
|
||||
int sdl_do_log = ENABLE_SDL_LOG;
|
||||
@@ -620,16 +614,14 @@ sdl_main()
|
||||
event.wheel.x *= -1;
|
||||
event.wheel.y *= -1;
|
||||
}
|
||||
mousedata.deltaz = event.wheel.y;
|
||||
mouse_set_z(event.wheel.y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
if (mouse_capture || video_fullscreen) {
|
||||
mousedata.deltax += event.motion.xrel;
|
||||
mousedata.deltay += event.motion.yrel;
|
||||
}
|
||||
if (mouse_capture || video_fullscreen)
|
||||
mouse_scale(event.motion.xrel, event.motion.yrel);
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
@@ -660,10 +652,10 @@ sdl_main()
|
||||
buttonmask = 4;
|
||||
break;
|
||||
}
|
||||
if (event.button.state == SDL_PRESSED) {
|
||||
mousedata.mousebuttons |= buttonmask;
|
||||
} else
|
||||
mousedata.mousebuttons &= ~buttonmask;
|
||||
if (event.button.state == SDL_PRESSED)
|
||||
mouse_set_buttons_ex(mouse_get_buttons_ex() | buttonmask);
|
||||
else
|
||||
mouse_set_buttons_ex(mouse_get_buttons_ex() & ~buttonmask);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -714,13 +706,3 @@ sdl_mouse_capture(int on)
|
||||
{
|
||||
SDL_SetRelativeMouseMode((SDL_bool) on);
|
||||
}
|
||||
|
||||
void
|
||||
sdl_mouse_poll()
|
||||
{
|
||||
mouse_x = mousedata.deltax;
|
||||
mouse_y = mousedata.deltay;
|
||||
mouse_z = mousedata.deltaz;
|
||||
mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0;
|
||||
mouse_buttons = mousedata.mousebuttons;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,5 @@ enum sdl_main_status {
|
||||
extern enum sdl_main_status sdl_main();
|
||||
|
||||
extern void sdl_mouse_capture(int on);
|
||||
extern void sdl_mouse_poll();
|
||||
|
||||
#endif /*WIN_SDL_H*/
|
||||
|
||||
@@ -88,12 +88,6 @@ qt_blit(int x, int y, int w, int h, int monitor_index)
|
||||
main_window->blitToWidget(x, y, w, h, monitor_index);
|
||||
}
|
||||
|
||||
void
|
||||
mouse_poll()
|
||||
{
|
||||
main_window->pollMouse();
|
||||
}
|
||||
|
||||
extern "C" int vid_resize;
|
||||
void
|
||||
plat_resize_request(int w, int h, int monitor_index)
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include <QMenuBar>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <86box/keyboard.h>
|
||||
@@ -338,85 +340,71 @@ void
|
||||
WindowsRawInputFilter::mouse_handle(PRAWINPUT raw)
|
||||
{
|
||||
RAWMOUSE state = raw->data.mouse;
|
||||
static int x;
|
||||
static int y;
|
||||
static int x, delta_x;
|
||||
static int y, delta_y;
|
||||
static int b, delta_z;
|
||||
|
||||
b = mouse_get_buttons_ex();
|
||||
|
||||
/* read mouse buttons and wheel */
|
||||
if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
|
||||
buttons |= 1;
|
||||
b |= 1;
|
||||
else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
|
||||
buttons &= ~1;
|
||||
b &= ~1;
|
||||
|
||||
if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)
|
||||
buttons |= 4;
|
||||
b |= 4;
|
||||
else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP)
|
||||
buttons &= ~4;
|
||||
b &= ~4;
|
||||
|
||||
if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
|
||||
buttons |= 2;
|
||||
b |= 2;
|
||||
else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
|
||||
buttons &= ~2;
|
||||
b &= ~2;
|
||||
|
||||
if (state.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN)
|
||||
buttons |= 8;
|
||||
b |= 8;
|
||||
else if (state.usButtonFlags & RI_MOUSE_BUTTON_4_UP)
|
||||
buttons &= ~8;
|
||||
b &= ~8;
|
||||
|
||||
if (state.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN)
|
||||
buttons |= 16;
|
||||
b |= 16;
|
||||
else if (state.usButtonFlags & RI_MOUSE_BUTTON_5_UP)
|
||||
buttons &= ~16;
|
||||
|
||||
b &= ~16;
|
||||
|
||||
mouse_set_buttons_ex(b);
|
||||
|
||||
if (state.usButtonFlags & RI_MOUSE_WHEEL) {
|
||||
dwheel += (SHORT) state.usButtonData / 120;
|
||||
}
|
||||
delta_z = (SHORT) state.usButtonData / 120;
|
||||
mouse_set_z(delta_z);
|
||||
} else
|
||||
delta_z = 0;
|
||||
|
||||
if (state.usFlags & MOUSE_MOVE_ABSOLUTE) {
|
||||
/* absolute mouse, i.e. RDP or VNC
|
||||
* seems to work fine for RDP on Windows 10
|
||||
* Not sure about other environments.
|
||||
*/
|
||||
dx += (state.lLastX - x) / 25;
|
||||
dy += (state.lLastY - y) / 25;
|
||||
delta_x = (state.lLastX - x) / 25;
|
||||
delta_y = (state.lLastY - y) / 25;
|
||||
x = state.lLastX;
|
||||
y = state.lLastY;
|
||||
} else {
|
||||
/* relative mouse, i.e. regular mouse */
|
||||
dx += state.lLastX;
|
||||
dy += state.lLastY;
|
||||
delta_x = state.lLastX;
|
||||
delta_y = state.lLastY;
|
||||
}
|
||||
HWND wnd = (HWND) window->winId();
|
||||
|
||||
mouse_scale(delta_x, delta_y);
|
||||
|
||||
HWND wnd = (HWND)window->winId();
|
||||
|
||||
RECT rect;
|
||||
|
||||
GetWindowRect(wnd, &rect);
|
||||
|
||||
int left = rect.left + (rect.right - rect.left) / 2;
|
||||
int top = rect.top + (rect.bottom - rect.top) / 2;
|
||||
int top = rect.top + (rect.bottom - rect.top) / 2;
|
||||
|
||||
SetCursorPos(left, top);
|
||||
}
|
||||
|
||||
void
|
||||
WindowsRawInputFilter::mousePoll()
|
||||
{
|
||||
if (mouse_mode >= 1) return;
|
||||
if (mouse_capture || video_fullscreen) {
|
||||
static int b = 0;
|
||||
|
||||
if (dx != 0 || dy != 0 || dwheel != 0) {
|
||||
mouse_x += dx;
|
||||
mouse_y += dy;
|
||||
mouse_z = dwheel;
|
||||
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
dwheel = 0;
|
||||
}
|
||||
|
||||
if (b != buttons) {
|
||||
mouse_buttons = buttons;
|
||||
b = buttons;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +59,6 @@ public:
|
||||
|
||||
~WindowsRawInputFilter();
|
||||
|
||||
public slots:
|
||||
void mousePoll();
|
||||
|
||||
private:
|
||||
MainWindow *window;
|
||||
uint16_t scancode_map[768];
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <QGuiApplication>
|
||||
|
||||
extern "C" {
|
||||
#include <86box/mouse.h>
|
||||
#include <86box/plat.h>
|
||||
}
|
||||
|
||||
@@ -34,28 +35,12 @@ static zwp_relative_pointer_v1 *rel_pointer = nullptr;
|
||||
static zwp_pointer_constraints_v1 *conf_pointer_interface = nullptr;
|
||||
static zwp_locked_pointer_v1 *conf_pointer = nullptr;
|
||||
|
||||
static int rel_mouse_x = 0;
|
||||
static int rel_mouse_y = 0;
|
||||
static bool wl_init_ok = false;
|
||||
|
||||
void
|
||||
rel_mouse_event(void *data, zwp_relative_pointer_v1 *zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real)
|
||||
{
|
||||
rel_mouse_x += wl_fixed_to_int(dx_real);
|
||||
rel_mouse_y += wl_fixed_to_int(dy_real);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
extern int mouse_x, mouse_y;
|
||||
}
|
||||
|
||||
void
|
||||
wl_mouse_poll()
|
||||
{
|
||||
mouse_x = rel_mouse_x;
|
||||
mouse_y = rel_mouse_y;
|
||||
rel_mouse_x = 0;
|
||||
rel_mouse_y = 0;
|
||||
mouse_scale(wl_fixed_to_int(dx_real), wl_fixed_to_int(dy_real));
|
||||
}
|
||||
|
||||
static struct zwp_relative_pointer_v1_listener rel_listener = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user