diff --git a/.ci/build.sh b/.ci/build.sh index 0aa6a499d..6d4d9697d 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -540,12 +540,25 @@ then # Attempt to install dependencies. sudo "$macports/bin/port" install $(cat .ci/dependencies_macports.txt) 2>&1 | tee macports.log - # Stop if no port version activation errors were found. + # Check for port activation errors. stuck_dep=$(grep " cannot be built while another version of " macports.log | cut -d" " -f10) - [ -z $stuck_dep ] && break + if [ -n "$stuck_dep" ] + then + # Deactivate the stuck dependency and try again. + sudo "$macports/bin/port" -f deactivate "$stuck_dep" + continue + fi - # Deactivate the stuck dependency and try again. - sudo "$macports/bin/port" -f deactivate $stuck_dep + stuck_dep=$(grep " Please deactivate this port first, or " macports.log | cut -d" " -f5 | tr -d :) + if [ -n "$stuck_dep" ] + then + # Activate the stuck dependency and try again. + sudo "$macports/bin/port" -f activate "$stuck_dep" + continue + fi + + # Stop if no errors were found. + break done # Remove MacPorts error detection log. diff --git a/.ci/dependencies_msys.txt b/.ci/dependencies_msys.txt index 1b9ccdcc8..22601b643 100644 --- a/.ci/dependencies_msys.txt +++ b/.ci/dependencies_msys.txt @@ -9,5 +9,6 @@ zlib libpng rtmidi libslirp +fluidsynth qt5-static qt5-translations diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..32eb262c9 --- /dev/null +++ b/.gitattributes @@ -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 diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 12d278e8f..00aef7e1b 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -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: >- diff --git a/cmake/flags-gcc.cmake b/cmake/flags-gcc.cmake index 885353b87..9e84ac16b 100644 --- a/cmake/flags-gcc.cmake +++ b/cmake/flags-gcc.cmake @@ -14,8 +14,8 @@ # # Define our flags -string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition") -string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing") +string(APPEND CMAKE_C_FLAGS_INIT " -std=c99 -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition") +string(APPEND CMAKE_CXX_FLAGS_INIT " -std=c++11 -fomit-frame-pointer -Wall -fno-strict-aliasing") string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3") string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3") string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -ggdb -Og") diff --git a/src/86box.c b/src/86box.c index 3a1ad179b..ec0967237 100644 --- a/src/86box.c +++ b/src/86box.c @@ -918,11 +918,15 @@ pc_init_modules(void) #ifdef USE_DYNAREC # if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(0); + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(0); + } # endif codegen_init(); # if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(1); + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(1); + } # endif #endif @@ -1048,19 +1052,9 @@ pc_reset_hard_init(void) /* Initialize the actual machine and its basic modules. */ machine_init(); - /* Reset and reconfigure the serial ports. */ - serial_standalone_init(); - serial_passthrough_init(); - - /* Reset and reconfigure the Sound Card layer. */ - sound_card_reset(); - - /* Reset any ISA RTC cards. */ - isartc_reset(); - - fdc_card_init(); - - fdd_reset(); + /* Reset some basic devices. */ + speaker_init(); + shadowbios = 0; /* * Once the machine has been initialized, all that remains @@ -1071,10 +1065,20 @@ pc_reset_hard_init(void) * that will be a call to device_reset_all() later ! */ - /* Reset some basic devices. */ - speaker_init(); + if (joystick_type) + gameport_update_joystick_type(); + + /* Reset and reconfigure the Sound Card layer. */ + sound_card_reset(); + + /* Reset and reconfigure the Network Card layer. */ + network_reset(); + lpt_devices_init(); - shadowbios = 0; + + /* Reset and reconfigure the serial ports. */ + serial_standalone_init(); + serial_passthrough_init(); /* * Reset the mouse, this will attach it to any port needed. @@ -1084,25 +1088,30 @@ pc_reset_hard_init(void) /* Reset the Hard Disk Controller module. */ hdc_reset(); + fdc_card_init(); + + fdd_reset(); + /* Reset the CD-ROM Controller module. */ cdrom_interface_reset(); /* Reset and reconfigure the SCSI layer. */ scsi_card_init(); - cdrom_hard_reset(); + scsi_disk_hard_reset(); - zip_hard_reset(); + cdrom_hard_reset(); mo_hard_reset(); - scsi_disk_hard_reset(); + zip_hard_reset(); - /* Reset and reconfigure the Network Card layer. */ - network_reset(); + /* Reset any ISA RTC cards. */ + isartc_reset(); - if (joystick_type) - gameport_update_joystick_type(); + /* Initialize the Voodoo cards here inorder to minmize + the chances of the SCSI controller ending up on the bridge. */ + video_voodoo_init(); ui_sb_update_panes(); @@ -1119,6 +1128,11 @@ pc_reset_hard_init(void) if (postcard_enabled) device_add(&postcard_device); + if (IS_ARCH(machine, MACHINE_BUS_PCI)) { + pci_register_cards(); + device_reset_all(DEVICE_PCI); + } + /* Reset the CPU module. */ resetx86(); dma_reset(); @@ -1273,10 +1287,12 @@ pc_run(void) startblit(); cpu_exec(cpu_s->rspeed / 100); #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ - // if (gdbstub_step == GDBSTUB_EXEC) + if (gdbstub_step == GDBSTUB_EXEC) { #endif -#if 0 - mouse_process(); + if (!mouse_timed) + mouse_process(); +#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ + } #endif joystick_process(); endblit(); diff --git a/src/acpi.c b/src/acpi.c index 157e3cadd..614deaa8c 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -124,18 +124,18 @@ acpi_update_irq(acpi_t *dev) if (sci_level) { if (dev->irq_mode == 1) - pci_set_irq(dev->slot, dev->irq_pin); + pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); else if (dev->irq_mode == 2) - pci_set_mirq(5, dev->mirq_is_level); + pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state); else - pci_set_mirq(0xf0 | dev->irq_line, 1); + pci_set_mirq(PCI_DIRQ_BASE | dev->irq_line, 1, &dev->irq_state); } else { if (dev->irq_mode == 1) - pci_clear_irq(dev->slot, dev->irq_pin); + pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); else if (dev->irq_mode == 2) - pci_clear_mirq(5, dev->mirq_is_level); + pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state); else - pci_clear_mirq(0xf0 | dev->irq_line, 1); + pci_clear_mirq(PCI_DIRQ_BASE | dev->irq_line, 1, &dev->irq_state); } acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS)); @@ -1657,6 +1657,9 @@ acpi_reset(void *priv) dev->regs.pmsts |= 0x8000; acpi_rtc_status = 0; + + acpi_update_irq(dev); + dev->irq_state = 0; } static void diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index e94668d75..9b9775603 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -652,9 +652,7 @@ cdi_cue_get_buffer(char *str, char **line, int up) done = 1; break; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; default: if (up && islower((int) *s)) diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 45182481d..94b4e44ca 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -331,7 +331,7 @@ viso_fill_fn_short(char *data, const viso_entry_t *entry, viso_entry_t **entries } /* Check if this filename is unique, and add a tail if required, while also adding the extension. */ - char tail[8]; + char tail[16]; for (int i = force_tail; i <= 999999; i++) { /* Add tail to the filename if this is not the first run. */ int tail_len = -1; @@ -429,7 +429,7 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform) or way too far into 64-bit space (Linux). Fall back to epoch. */ time_t epoch = 0; time_s = localtime(&epoch); - if (!time_s) + if (UNLIKELY(!time_s)) fatal("VISO: localtime(0) = NULL\n"); /* Force year clamping if the timestamp is known to be outside the supported ranges. */ @@ -636,12 +636,8 @@ pad_susp: break; } - if ((p - data) > 255) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - fatal("VISO: Directory record overflow (%d) on entry %016" PRIX64 "\n", (uint32_t) (uintptr_t) (p - data), (uint64_t) (uintptr_t) entry); -#else - fatal("VISO: Directory record overflow (%d) on entry %08X\n", (uint32_t) (uintptr_t) (p - data), (uint32_t) (uintptr_t) entry); -#endif + if (UNLIKELY((p - data) > 255)) + fatal("VISO: Directory record overflow (%" PRIuPTR ") on entry %08" PRIXPTR "\n", (uintptr_t) (p - data), (uintptr_t) entry); data[0] = p - data; /* length */ return data[0]; diff --git a/src/cdrom/cdrom_mitsumi.c b/src/cdrom/cdrom_mitsumi.c index 6c015fa9d..19e19a420 100644 --- a/src/cdrom/cdrom_mitsumi.c +++ b/src/cdrom/cdrom_mitsumi.c @@ -324,9 +324,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) break; case 5: dev->readmsf = 0; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 4: case 3: dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3); diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 0a6a5fbe5..3e72ae541 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -13,13 +13,14 @@ # Copyright 2020-2021 David Hrdlička. # -add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c ali1531.c ali1541.c ali1543.c - ali1621.c ali6117.c headland.c ims8848.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c - intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c - opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c - sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c - sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c - via_pipc.c vl82c480.c wd76c10.c) +add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c + ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c ims8848.c intel_82335.c + compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c + intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c + opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c sis_85c496.c + sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c + sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c + via_apollo.c via_pipc.c vl82c480.c wd76c10.c) if(OLIVETTI) target_sources(chipset PRIVATE olivetti_eva.c) diff --git a/src/chipset/ali1435.c b/src/chipset/ali1435.c index 72595cf84..9476d2b45 100644 --- a/src/chipset/ali1435.c +++ b/src/chipset/ali1435.c @@ -46,11 +46,12 @@ typedef struct ali_1435_t { uint8_t index; uint8_t cfg_locked; + uint8_t pci_slot; + uint8_t pad; uint8_t regs[16]; uint8_t pci_regs[256]; } ali1435_t; -#define ENABLE_ALI1435_LOG 1 #ifdef ENABLE_ALI1435_LOG int ali1435_do_log = ENABLE_ALI1435_LOG; @@ -190,24 +191,20 @@ ali1435_write(uint16_t addr, uint8_t val, void *priv) break; case 0x23: -#if 0 -#ifdef ENABLE_ALI1435_LOG - if (dev->index != 0x03) - ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val); -#endif -#endif if (dev->index == 0x03) dev->cfg_locked = (val != 0x69); +#ifdef ENABLE_ALI1435_LOG + else + ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val); +#endif if (!dev->cfg_locked) { - pclog("M1435: dev->regs[%02x] = %02x\n", dev->index, val); - switch (dev->index) { /* PCI Mechanism select? */ case 0x00: dev->regs[dev->index] = val; - pclog("PMC = %i\n", val != 0xc8); - pci_set_pmc(val != 0xc8); + ali1435_log("PMC = %i\n", val != 0xc8); + pci_key_write(((val & 0xc8) == 0xc8) ? 0xf0 : 0x00); break; /* ???? */ @@ -253,8 +250,6 @@ ali1435_reset(void *priv) dev->regs[0x00] = 0xff; - pci_set_pmc(0); - dev->cfg_locked = 1; memset(dev->pci_regs, 0, 256); @@ -298,17 +293,10 @@ ali1435_init(UNUSED(const device_t *info)) */ io_sethandler(0x0022, 0x0002, ali1435_read, NULL, NULL, ali1435_write, NULL, NULL, dev); - pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev, &dev->pci_slot); ali1435_reset(dev); -#if 0 - pci_set_irq_level(PCI_INTA, 0); - pci_set_irq_level(PCI_INTB, 0); - pci_set_irq_level(PCI_INTC, 0); - pci_set_irq_level(PCI_INTD, 0); -#endif - return dev; } diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 1b2087e4d..822ab7baf 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -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); diff --git a/src/chipset/ali1531.c b/src/chipset/ali1531.c index 3812e4ca4..9eb75f7cd 100644 --- a/src/chipset/ali1531.c +++ b/src/chipset/ali1531.c @@ -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(); diff --git a/src/chipset/ali1541.c b/src/chipset/ali1541.c index 55cf5d25d..d57ef51e7 100644 --- a/src/chipset/ali1541.c +++ b/src/chipset/ali1541.c @@ -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(); diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index cefaa4f0d..ba8ce4f3b 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -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); diff --git a/src/chipset/ali1621.c b/src/chipset/ali1621.c index b927d3e34..6194dce19 100644 --- a/src/chipset/ali1621.c +++ b/src/chipset/ali1621.c @@ -36,6 +36,11 @@ #include <86box/chipset.h> typedef struct ali1621_t { + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t pad1; + uint8_t pci_conf[256]; smram_t *smram[2]; @@ -109,9 +114,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev) switch (val & 0x30) { case 0x10: /* Open. */ access_normal = ACCESS_SMRAM_RX; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x30: /* Protect. */ access_smm |= ACCESS_SMRAM_R; break; @@ -124,9 +127,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev) switch (val & 0x30) { case 0x10: /* Open. */ access_normal |= ACCESS_SMRAM_W; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x30: /* Protect. */ access_smm |= ACCESS_SMRAM_W; break; @@ -671,7 +672,7 @@ ali1621_init(UNUSED(const device_t *info)) ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t)); memset(dev, 0, sizeof(ali1621_t)); - pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev, &dev->pci_slot); dev->smram[0] = smram_add(); dev->smram[1] = smram_add(); diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index 78705ee26..c7ada4bc6 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -234,9 +234,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x12: val &= 0xf7; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x14: case 0x15: diff --git a/src/chipset/compaq_386.c b/src/chipset/compaq_386.c new file mode 100644 index 000000000..0f90cc6af --- /dev/null +++ b/src/chipset/compaq_386.c @@ -0,0 +1,767 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Compaq 386 memory controller. + * + * Authors: Miran Grca, + * + * Copyright 2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/pit.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/machine.h> +#include <86box/video.h> +#include <86box/vid_cga.h> +#include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> + +#define RAM_DIAG_L_BASE_MEM_640KB 0x00 +#define RAM_DIAG_L_BASE_MEM_INV 0x10 +#define RAM_DIAG_L_BASE_MEM_512KB 0x20 +#define RAM_DIAG_L_BASE_MEM_256KB 0x30 +#define RAM_DIAG_L_BASE_MEM_MASK 0x30 +#define RAM_DIAG_L_PERMA_BITS 0x80 + +#define RAM_DIAG_H_SYS_RAM_4MB 0x01 +#define RAM_DIAG_H_SYS_RAM_1MB 0x02 +#define RAM_DIAG_H_SYS_RAM_NONE 0x03 +#define RAM_DIAG_H_SYS_RAM_MASK 0x03 +#define RAM_DIAG_H_MOD_A_RAM_4MB 0x04 +#define RAM_DIAG_H_MOD_A_RAM_1MB 0x08 +#define RAM_DIAG_H_MOD_A_RAM_NONE 0x0c +#define RAM_DIAG_H_MOD_A_RAM_MASK 0x0c +#define RAM_DIAG_H_MOD_B_RAM_4MB 0x10 +#define RAM_DIAG_H_MOD_B_RAM_1MB 0x20 +#define RAM_DIAG_H_MOD_B_RAM_NONE 0x30 +#define RAM_DIAG_H_MOD_B_RAM_MASK 0x30 +#define RAM_DIAG_H_MOD_C_RAM_4MB 0x40 +#define RAM_DIAG_H_MOD_C_RAM_1MB 0x80 +#define RAM_DIAG_H_MOD_C_RAM_NONE 0xc0 +#define RAM_DIAG_H_MOD_C_RAM_MASK 0xc0 + +#define MEM_STATE_BUS 0x00 +#define MEM_STATE_SYS 0x01 +#define MEM_STATE_SYS_RELOC 0x02 +#define MEM_STATE_MOD_A 0x04 +#define MEM_STATE_MOD_B 0x08 +#define MEM_STATE_MOD_C 0x10 +#define MEM_STATE_MASK (MEM_STATE_SYS | MEM_STATE_MOD_A | MEM_STATE_MOD_B | MEM_STATE_MOD_C) +#define MEM_STATE_WP 0x20 + +typedef struct cpq_ram_t { + uint8_t wp; + + uint32_t phys_base; + uint32_t virt_base; + + mem_mapping_t mapping; +} cpq_ram_t; + +typedef struct cpq_386_t { + uint8_t regs[8]; + + uint8_t old_state[256]; + uint8_t mem_state[256]; + + uint32_t ram_bases[4]; + + uint32_t ram_sizes[4]; + uint32_t ram_map_sizes[4]; + + cpq_ram_t ram[4][64]; + cpq_ram_t high_ram[16]; + + mem_mapping_t regs_mapping; +} cpq_386_t; + +static uint8_t +cpq_read_ram(uint32_t addr, void *priv) +{ + cpq_ram_t *dev = (cpq_ram_t *) priv; + uint8_t ret = 0xff; + uint32_t old = addr; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (addr < (mem_size << 10)) + ret = mem_read_ram(addr, priv); + + return ret; +} + +static uint16_t +cpq_read_ramw(uint32_t addr, void *priv) +{ + cpq_ram_t *dev = (cpq_ram_t *) priv; + uint16_t ret = 0xffff; + uint32_t old = addr; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (addr < (mem_size << 10)) + ret = mem_read_ramw(addr, priv); + + return ret; +} + +static uint32_t +cpq_read_raml(uint32_t addr, void *priv) +{ + cpq_ram_t *dev = (cpq_ram_t *) priv; + uint32_t ret = 0xffffffff; + uint32_t old = addr; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (addr < (mem_size << 10)) + ret = mem_read_raml(addr, priv); + + return ret; +} + +static void +cpq_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + cpq_ram_t *dev = (cpq_ram_t *) priv; + uint32_t old = addr; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (!dev->wp && (addr < (mem_size << 10))) + mem_write_ram(addr, val, priv); +} + +static void +cpq_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + cpq_ram_t *dev = (cpq_ram_t *) priv; + uint32_t old = addr; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (!dev->wp && (addr < (mem_size << 10))) + mem_write_ramw(addr, val, priv); +} + +static void +cpq_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + cpq_ram_t *dev = (cpq_ram_t *) priv; + uint32_t old = addr; + + addr = (addr - dev->virt_base) + dev->phys_base; + + if (!dev->wp && (addr < (mem_size << 10))) + mem_write_raml(addr, val, priv); +} + +static uint8_t +cpq_read_regs(uint32_t addr, void *priv) +{ + cpq_386_t *dev = (cpq_386_t *) priv; + uint8_t ret = 0xff; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000000: + case 0x00000001: + /* RAM Diagnostics (Read Only) */ + case 0x00000002: + case 0x00000003: + /* RAM Setup Port (Read/Write) */ + ret = dev->regs[addr]; + break; + } + + return ret; +} + +static uint16_t +cpq_read_regsw(uint32_t addr, void *priv) +{ + cpq_386_t *dev = (cpq_386_t *) priv; + uint16_t ret = 0xffff; + + ret = cpq_read_regs(addr, priv); + ret |= (((uint16_t) cpq_read_regs(addr + 1, priv)) << 8); + + return ret; +} + +static uint32_t +cpq_read_regsl(uint32_t addr, void *priv) +{ + cpq_386_t *dev = (cpq_386_t *) priv; + uint32_t ret = 0xffffffff; + + ret = cpq_read_regsw(addr, priv); + ret |= (((uint32_t) cpq_read_regsw(addr + 2, priv)) << 16); + + return ret; +} + +static void +cpq_recalc_state(cpq_386_t *dev, uint8_t i) +{ + uint32_t addr; + + addr = ((uint32_t) i) << 16; + if (dev->mem_state[i] == 0x00) + mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else if (dev->mem_state[i] == MEM_STATE_WP) + mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_DISABLED); + else if (dev->mem_state[i] & MEM_STATE_WP) + mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + else + mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + + dev->old_state[i] = dev->mem_state[i]; +} + +static void +cpq_recalc_states(cpq_386_t *dev) +{ + /* Recalculate the entire 16 MB space. */ + for (uint16_t i = 0; i < 256; i++) { + if (dev->mem_state[i] != dev->old_state[i]) + cpq_recalc_state(dev, i); + } + + flushmmucache_nopc(); +} + +static void +cpq_recalc_cache(cpq_386_t *dev) +{ + cpu_cache_ext_enabled = (dev->regs[0x00000002] & 0x40); + cpu_update_waitstates(); +} + +static void +cpq_recalc_ram(cpq_386_t *dev) +{ + uint8_t sys_ram = (dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK) & 0x01; + uint8_t setup_port = dev->regs[0x00000002] & 0x0f; + uint8_t sys_min_high = sys_ram ? 0xfa : 0xf4; + uint8_t ram_states[4] = { MEM_STATE_SYS, MEM_STATE_MOD_A, + MEM_STATE_MOD_B, MEM_STATE_MOD_C }; + uint8_t ram_bases[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 } }, + { { 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } }, + { { 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x20, 0x20, + 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 } }, + { { 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x00, 0x00 }, + { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x90, 0x00, 0x00, 0xc0, 0xc0, 0xc0 } } }; + uint8_t ram_sizes[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x30, 0x00, 0x10, 0x20, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 } }, + { { 0x00, 0x00, 0x10, 0x10, 0x10, 0x40, 0x10, 0x10, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } }, + { { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, + 0x30, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, + 0x00, 0x10, 0x10, 0x30, 0x40, 0x40, 0x40, 0x40 } }, + { { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x10, 0x20, 0x30, 0x40, 0x00, 0x00 }, + { 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x20, 0x30 } } }; + uint8_t size; + uint8_t start; + uint8_t end; + uint8_t k; + uint32_t virt_base; + uint32_t virt_addr; + uint32_t phys_addr; + cpq_ram_t *cram; + + for (uint16_t i = 0x10; i < sys_min_high; i++) + dev->mem_state[i] &= ~MEM_STATE_MASK; + + for (uint8_t i = 0; i < 4; i++) { + for (uint8_t j = 0; j <= 64; j++) { + if ((i >= 1) || (j >= 0x10)) + mem_mapping_disable(&dev->ram[i][j].mapping); + } + } + + for (uint8_t i = 0; i < 4; i++) { + size = ram_sizes[i][sys_ram][setup_port]; + if (size > 0x00) { + start = ram_bases[i][sys_ram][setup_port]; + end = start + (size - 1); + + virt_base = ((uint32_t) start) << 16; + + for (uint16_t j = start; j <= end; j++) { + k = j - start; + if (i == 0) + k += 0x10; + + cram = &(dev->ram[i][k]); + + dev->mem_state[j] |= ram_states[i]; + + cram->virt_base = ((uint32_t) j) << 16; + cram->phys_base = cram->virt_base - virt_base + dev->ram_bases[i]; + + mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000); + mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base])); + } + } + } + + /* Recalculate the entire 16 MB space. */ + cpq_recalc_states(dev); +} + +static void +cpq_write_regs(uint32_t addr, uint8_t val, void *priv) +{ + cpq_386_t *dev = (cpq_386_t *) priv; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000000: + case 0x00000001: + /* RAM Relocation (Write Only) */ + dev->regs[addr + 4] = val; + if (addr == 0x00000000) { + dev->mem_state[0x0e] &= ~(MEM_STATE_SYS | MEM_STATE_WP); + dev->mem_state[0x0f] &= ~(MEM_STATE_SYS | MEM_STATE_WP); + dev->mem_state[0xfe] &= ~MEM_STATE_WP; + dev->mem_state[0xff] &= ~MEM_STATE_WP; + if (!(val & 0x01)) { + dev->mem_state[0x0e] |= MEM_STATE_SYS; + dev->mem_state[0x0f] |= MEM_STATE_SYS; + } + if (!(val & 0x02)) { + dev->mem_state[0x0e] |= MEM_STATE_WP; + dev->mem_state[0x0f] |= MEM_STATE_WP; + dev->mem_state[0xfe] |= MEM_STATE_WP; + dev->mem_state[0xff] |= MEM_STATE_WP; + } + cpq_recalc_state(dev, 0x0e); + cpq_recalc_state(dev, 0x0f); + cpq_recalc_state(dev, 0xfe); + cpq_recalc_state(dev, 0xff); + flushmmucache_nopc(); + } + break; + case 0x00000002: + case 0x00000003: + /* RAM Setup Port (Read/Write) */ + dev->regs[addr] = val; + if (addr == 0x00000002) { + cpq_recalc_ram(dev); + cpq_recalc_cache(dev); + } + break; + } +} + +static void +cpq_write_regsw(uint32_t addr, uint16_t val, void *priv) +{ + cpq_386_t *dev = (cpq_386_t *) priv; + + cpq_write_regs(addr, val & 0xff, priv); + cpq_write_regs(addr + 1, (val >> 8) & 0xff, priv); +} + +static void +cpq_write_regsl(uint32_t addr, uint32_t val, void *priv) +{ + cpq_386_t *dev = (cpq_386_t *) priv; + + cpq_write_regsw(addr, val & 0xff, priv); + cpq_write_regsw(addr + 2, (val >> 16) & 0xff, priv); +} + +static void +compaq_ram_init(cpq_ram_t *dev) +{ + mem_mapping_add(&dev->mapping, + 0x00000000, + 0x00010000, + cpq_read_ram, + cpq_read_ramw, + cpq_read_raml, + cpq_write_ram, + cpq_write_ramw, + cpq_write_raml, + NULL, + MEM_MAPPING_INTERNAL, + dev); + + mem_mapping_disable(&dev->mapping); +} + +static void +compaq_ram_diags_parse(cpq_386_t *dev) +{ + uint8_t val = dev->regs[0x00000001]; + uint32_t accum = 0x00100000; + + val; + + for (uint8_t i = 0; i < 4; i++) { + dev->ram_bases[i] = accum; + + switch (val & 0x03) { + case RAM_DIAG_H_SYS_RAM_1MB: + dev->ram_sizes[i] = 0x00100000; + break; + case RAM_DIAG_H_SYS_RAM_4MB: + dev->ram_sizes[i] = 0x00400000; + break; + } + if (i == 0) + dev->ram_sizes[i] -= 0x00100000; + + dev->ram_map_sizes[i] = dev->ram_sizes[i]; + accum += dev->ram_sizes[i]; + + if (accum >= (mem_size << 10)) { + dev->ram_sizes[i] = (mem_size << 10) - dev->ram_bases[i]; + break; + } + + val >>= 2; + } +} + +static void +compaq_recalc_base_ram(cpq_386_t *dev) +{ + uint8_t base_mem = dev->regs[0x00000000] & RAM_DIAG_L_BASE_MEM_MASK; + uint8_t sys_ram = dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK; + uint8_t low_start = 0x00; + uint8_t low_end = 0x00; + uint8_t high_start = 0x00; + uint8_t high_end = 0x00; + uint32_t phys_addr = 0x00000000; + uint32_t virt_addr = 0x00000000; + cpq_ram_t *cram; + + switch (base_mem) { + case RAM_DIAG_L_BASE_MEM_256KB: + switch (sys_ram) { + case RAM_DIAG_H_SYS_RAM_1MB: + low_start = 0x00; + low_end = 0x03; + high_start = 0xf4; + high_end = 0xff; + break; + case RAM_DIAG_H_SYS_RAM_4MB: + low_start = 0x00; + low_end = 0x03; + high_start = 0xfa; + high_end = 0xff; + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram); + return; + } + break; + case RAM_DIAG_L_BASE_MEM_512KB: + switch (sys_ram) { + case RAM_DIAG_H_SYS_RAM_1MB: + low_start = 0x00; + low_end = 0x07; + high_start = 0xf8; + high_end = 0xff; + break; + case RAM_DIAG_H_SYS_RAM_4MB: + low_start = 0x00; + low_end = 0x07; + high_start = 0xfa; + high_end = 0xff; + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram); + return; + } + break; + case RAM_DIAG_L_BASE_MEM_640KB: + switch (sys_ram) { + case RAM_DIAG_H_SYS_RAM_1MB: + low_start = 0x00; + low_end = 0x09; + high_start = 0xfa; + high_end = 0xff; + break; + case RAM_DIAG_H_SYS_RAM_4MB: + low_start = 0x00; + low_end = 0x09; + high_start = 0xfa; + high_end = 0xff; + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram); + return; + } + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram); + return; + } + + switch (sys_ram) { + case RAM_DIAG_H_SYS_RAM_1MB: + if (mem_size < 1024) + dev->regs[0x00000002] = 0x01; + else if (mem_size == 8192) + dev->regs[0x00000002] = 0x09; + else if (mem_size >= 11264) + dev->regs[0x00000002] = 0x0d; + else + dev->regs[0x00000002] = (mem_size >> 10); + break; + case RAM_DIAG_H_SYS_RAM_4MB: + if (mem_size < 4096) + dev->regs[0x00000002] = 0x04; + else if (mem_size == 11264) + dev->regs[0x00000002] = 0x0c; + else if (mem_size >= 16384) + dev->regs[0x00000002] = 0x00; + else if (mem_size > 13312) + dev->regs[0x00000002] = 0x0d; + else + dev->regs[0x00000002] = (mem_size >> 10); + break; + default: + fatal("Compaq 386 - Invalid configuation: %02X\n", sys_ram); + return; + } + + /* The base 640 kB. */ + for (uint8_t i = low_start; i <= low_end; i++) { + cram = &(dev->ram[0][i]); + + cram->phys_base = cram->virt_base = ((uint32_t) i) << 16; + dev->mem_state[i] |= MEM_STATE_SYS; + + mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000); + mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base])); + + cpq_recalc_state(dev, i); + } + + /* The relocated 128 kB. */ + for (uint8_t i = 0x0e; i <= 0x0f; i++) { + cram = &(dev->ram[0][i]); + + cram->phys_base = cram->virt_base = ((uint32_t) i) << 16; + + mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000); + mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base])); + } + + /* Blocks FA-FF. */ + for (uint16_t i = high_start; i <= high_end; i++) { + cram = &(dev->high_ram[i & 0x0f]); + + cram->phys_base = ((uint32_t) (i & 0x0f)) << 16; + cram->virt_base = ((uint32_t) i) << 16; + dev->mem_state[i] |= MEM_STATE_SYS; + + mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000); + mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base])); + + cpq_recalc_state(dev, i); + } +} + +static void +compaq_386_close(void *priv) +{ + cpq_386_t *dev = (cpq_386_t *) priv; + + free(dev); +} + +static void * +compaq_386_init(const device_t *info) +{ + cpq_386_t *dev = (cpq_386_t *) calloc(1, sizeof(cpq_386_t)); + + mem_mapping_add(&dev->regs_mapping, + 0x80c00000, + 0x00001000, + cpq_read_regs, + cpq_read_regsw, + cpq_read_regsl, + cpq_write_regs, + cpq_write_regsw, + cpq_write_regsl, + NULL, + MEM_MAPPING_INTERNAL, + dev); + + mem_set_mem_state(0x80c00000, 0x00001000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + + dev->regs[0x00000000] = RAM_DIAG_L_PERMA_BITS; + if (mem_size >= 640) + dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_640KB; + else if (mem_size >= 512) + dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_512KB; + else if (mem_size >= 256) + dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_256KB; + else + dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_INV; + /* Indicate no parity error. */ + dev->regs[0x00000000] |= 0x0f; + + if (mem_size >= 1024) { + switch (mem_size) { + case 1024: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 2048: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 3072: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 4096: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 5120: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 6144: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB | + RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 7168: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB | + RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB; + break; + case 8192: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 9216: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 10240: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB; + break; + case 11264: + case 12288: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_NONE; + break; + case 13312: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_1MB; + break; + case 14336: + case 15360: + case 16384: + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB | + RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_4MB; + break; + } + } else + dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_1MB | RAM_DIAG_H_MOD_A_RAM_NONE | + RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE; + + dev->regs[0x00000003] = 0xfc; + dev->regs[0x00000004] = dev->regs[0x00000005] = 0xff; + + compaq_ram_diags_parse(dev); + + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + /* Should never be the case, but you never know what a user may set. */ + if (mem_size > 1048576) + mem_mapping_disable(&ram_2gb_mapping); +#endif + + /* Initialize in reverse order for memory mapping precedence + reasons. */ + for (int8_t i = 3; i >= 0; i--) { + for (uint8_t j = 0; j < 64; j++) + compaq_ram_init(&(dev->ram[i][j])); + } + + for (uint8_t i = 0; i < 16; i++) + compaq_ram_init(&(dev->high_ram[i])); + + /* First, set the entire 256 MB of space to invalid states. */ + for (uint16_t i = 0; i < 256; i++) + dev->old_state[i] = 0xff; + + /* Then, recalculate the base RAM mappings. */ + compaq_recalc_base_ram(dev); + + /* Enable the external cache. */ + dev->regs[0x00000002] |= 0x40; + cpq_recalc_cache(dev); + + /* Recalculate the rest of the RAM mapping. */ + cpq_recalc_ram(dev); + + return dev; +} + +const device_t compaq_386_device = { + .name = "Compaq 386 Memory Control", + .internal_name = "opti391", + .flags = 0, + .local = 0, + .init = compaq_386_init, + .close = compaq_386_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/ims8848.c b/src/chipset/ims8848.c index f84eb5706..3e86a44e1 100644 --- a/src/chipset/ims8848.c +++ b/src/chipset/ims8848.c @@ -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); diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index 5200d8834..03720b668 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -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; diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index c68f6218c..eebe95f58 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -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); diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index b81c3dde4..90b807a6d 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -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(); diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 038f35f97..878fd53ae 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -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); diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index 1dcbafe5a..0f32eb4c8 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -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; diff --git a/src/chipset/opti283.c b/src/chipset/opti283.c index 865ec6ff5..1fa59f2f0 100644 --- a/src/chipset/opti283.c +++ b/src/chipset/opti283.c @@ -229,9 +229,7 @@ opti283_write(uint16_t addr, uint8_t val, void *priv) case 0x14: reset_on_hlt = !!(val & 0x40); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x11: case 0x12: case 0x13: diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index 73548adab..ad6db361a 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -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); diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index 8bc93702f..512c4fc82 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -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]; diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index dc2ef42e4..d30ef39ca 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -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 */ diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 0e09de199..391cc4e8b 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -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); diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 8aac6ecd5..88618b1a0 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -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); diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 00556c6f0..7f4aebb7c 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -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(); diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index 092c0ae32..59d01186a 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -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); diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index ded9c7e56..f6a923346 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -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) diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index 60b070f0b..4e115eeb6 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -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); diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index bd4445521..2d3633115 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -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; diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 04bcd5576..b284cb6b9 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -117,9 +117,10 @@ typedef struct { } pipc_io_trap_t; typedef struct _pipc_ { - uint32_t local; uint8_t max_func; uint8_t max_pcs; + uint8_t pci_slot; + uint8_t pad; uint8_t pci_isa_regs[256]; uint8_t ide_regs[256]; @@ -129,10 +130,11 @@ typedef struct _pipc_ { uint8_t fmnmi_regs[4]; uint8_t fmnmi_status; + uint32_t local; + sff8038i_t *bm[2]; nvr_t *nvr; int nvr_enabled; - int slot; ddma_t *ddma; smbus_piix4_t *smbus; usb_t *usb[2]; @@ -1094,7 +1096,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv) case 0x47: if (val & 0x01) - trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL); + pci_write(0x0cf9, (val & 0x80) ? 0x06 : 0x04, NULL); pic_set_shadow(!!(val & 0x10)); pic_elcr_io_handler(!!(val & 0x20)); dev->pci_isa_regs[0x47] = val & 0xfe; @@ -1475,9 +1477,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv) case 0xd2: if (dev->local == VIA_PIPC_686B) smbus_piix4_setclock(dev->smbus, (val & 0x04) ? 65536 : 16384); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x90: case 0x91: @@ -1620,6 +1620,14 @@ pipc_reset(void *priv) pipc_write(0, 0x44, 0x00, priv); pipc_write(0, 0x77, 0x00, priv); + + sff_set_slot(dev->bm[0], dev->pci_slot); + sff_set_slot(dev->bm[1], dev->pci_slot); + + if (dev->local >= VIA_PIPC_686A) + ac97_via_set_slot(dev->ac97, dev->pci_slot, PCI_INTC); + if (dev->acpi) + acpi_set_slot(dev->acpi, dev->pci_slot); } static void * @@ -1631,16 +1639,14 @@ pipc_init(const device_t *info) pipc_log("PIPC: init()\n"); dev->local = info->local; - dev->slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev); + pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev, &dev->pci_slot); dev->bm[0] = device_add_inst(&sff8038i_device, 1); - sff_set_slot(dev->bm[0], dev->slot); sff_set_irq_mode(dev->bm[0], 0, 0); sff_set_irq_mode(dev->bm[0], 1, 0); sff_set_irq_pin(dev->bm[0], PCI_INTA); dev->bm[1] = device_add_inst(&sff8038i_device, 2); - sff_set_slot(dev->bm[1], dev->slot); sff_set_irq_mode(dev->bm[1], 0, 0); sff_set_irq_mode(dev->bm[1], 1, 0); sff_set_irq_pin(dev->bm[1], PCI_INTA); @@ -1665,7 +1671,6 @@ pipc_init(const device_t *info) dev->usb[1] = device_add_inst(&usb_device, 2); dev->ac97 = device_add(&ac97_via_device); - ac97_via_set_slot(dev->ac97, dev->slot, PCI_INTC); dev->sb = device_add_inst(&sb_pro_compat_device, 2); sound_add_handler(pipc_sb_get_buffer, dev); @@ -1695,7 +1700,6 @@ pipc_init(const device_t *info) dev->ddma = device_add(&ddma_device); if (dev->acpi) { - acpi_set_slot(dev->acpi, dev->slot); acpi_set_nvr(dev->acpi, dev->nvr); acpi_init_gporeg(dev->acpi, 0xff, 0xbf, 0xff, 0x7f); diff --git a/src/chipset/via_vt82c505.c b/src/chipset/via_vt82c505.c index 136d335c7..34efbead9 100644 --- a/src/chipset/via_vt82c505.c +++ b/src/chipset/via_vt82c505.c @@ -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; diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index aa5e5870a..dd47204f3 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -1,5 +1,6 @@ #if defined __aarch64__ || defined _M_ARM64 +# include # include # include <86box/86box.h> # include "cpu.h" @@ -340,7 +341,7 @@ host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm } else if (imm_data & 0xfff000) codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); } else - fatal("ADD_IMM_X %016llx\n", imm_data); + fatal("ADD_IMM_X %016" PRIu64 "\n", imm_data); } void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) @@ -662,7 +663,7 @@ host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) } else if (!(imm_data & 0xfffffffffffff000ull)) { codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); } else - fatal("CMNX_IMM %08x\n", imm_data); + fatal("CMNX_IMM %016" PRIx64 "\n", imm_data); } void @@ -683,7 +684,7 @@ host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) } else if (!(imm_data & 0xfffffffffffff000ull)) { codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); } else - fatal("CMPX_IMM %08x\n", imm_data); + fatal("CMPX_IMM %08" PRIu64 "\n", imm_data); } void diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 91fb9c903..a3a38ab22 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -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; } diff --git a/src/codegen_new/codegen_block.c b/src/codegen_new/codegen_block.c index 3a1a5e1ab..95e422408 100644 --- a/src/codegen_new/codegen_block.c +++ b/src/codegen_new/codegen_block.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -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) { diff --git a/src/cpu/386.c b/src/cpu/386.c index 87d481e1f..5dd143efd 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -12,17 +12,22 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" -#include <86box/timer.h> #include "x86.h" +#include "x86_ops.h" #include "x87.h" +#include <86box/io.h> #include <86box/nmi.h> #include <86box/mem.h> #include <86box/pic.h> +#include <86box/timer.h> #include <86box/pit.h> #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/machine.h> #include <86box/gdbstub.h> +#ifndef OPS_286_386 +# define OPS_286_386 +#endif #include "386_common.h" #ifdef USE_NEW_DYNAREC # include "codegen.h" @@ -33,54 +38,7 @@ extern int codegen_flags_changed; -int tempc, oldcpl, optype, inttype, oddeven = 0; -int timetolive; - -uint16_t oldcs; - -uint32_t oldds, oldss, olddslimit, oldsslimit, - olddslimitw, oldsslimitw; -uint32_t oxpc; -uint32_t rmdat32; -uint32_t backupregs[16]; - -x86seg _oldds; - -#if 1 -int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */ - 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */ - 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */ - 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x3x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */ - 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */ - 3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */ - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */ - 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */ - 3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */ - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */ - 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */ -#else -int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */ - 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */ - 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x2x */ - 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 1, /* 0x3x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */ - 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */ - 3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */ - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */ - 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */ - 3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */ - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */ - 3, 1, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */ -#endif +static int fpu_cycles = 0; #ifdef ENABLE_386_LOG int x386_do_log = ENABLE_386_LOG; @@ -103,9 +61,6 @@ x386_log(const char *fmt, ...) #undef CPU_BLOCK_END #define CPU_BLOCK_END() -#include "x86_flags.h" - -/* #define getbytef() \ ((uint8_t) (fetchdat)); \ cpu_state.pc++ @@ -118,40 +73,169 @@ x386_log(const char *fmt, ...) #define getword2f() \ ((uint16_t) (fetchdat >> 8)); \ cpu_state.pc += 2 -*/ -#define OP_TABLE(name) ops_##name +static __inline void +fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) { + uint8_t sib = rmdat >> 8; -#if 0 -# define CLOCK_CYCLES(c) \ - { \ - if (fpu_cycles > 0) { \ - fpu_cycles -= (c); \ - if (fpu_cycles < 0) { \ - cycles += fpu_cycles; \ - } \ - } else { \ - cycles -= (c); \ - } \ + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t) (int8_t) getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } else { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) { + if (cpu_rm == 5 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) { + cpu_state.eaaddr += ((uint32_t) (int8_t) (rmdat >> 8)); + cpu_state.pc++; + } else { + cpu_state.eaaddr += getlong(); + } + } else if (cpu_rm == 5) { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } +} -# define CLOCK_CYCLES_FPU(c) cycles -= (c) -# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) -#else -# define CLOCK_CYCLES(c) cycles -= (c) -# define CLOCK_CYCLES_FPU(c) cycles -= (c) -# define CONCURRENCY_CYCLES(c) +static __inline void +fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) { + cpu_state.eaaddr = getword(); + } else { + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t) (int8_t) (rmdat >> 8); + cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } +} + +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_16_long(rmdat); \ + if (cpu_state.abrt) \ + return 1; \ + } +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_32_long(rmdat); \ + } \ + if (cpu_state.abrt) \ + return 1 + +#include "x86_flags.h" + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); \ + } while (0) + +#define PREFETCH_PREFIX() \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_prefixes++; \ + } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + +#ifndef FPU_CYCLES +# define FPU_CYCLES #endif +#define OP_TABLE(name) ops_2386_##name +#define CLOCK_CYCLES(c) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (c); \ + if (fpu_cycles < 0) { \ + cycles += fpu_cycles; \ + } \ + } else { \ + cycles -= (c); \ + } \ + } + +#define CLOCK_CYCLES_FPU(c) cycles -= (c) +#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) + #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) -#include "x86_ops.h" +#include "386_ops.h" void -exec386(int cycs) +exec386_2386(int cycs) { - int vector, tempi, cycdiff, oldcyc; - int cycle_period, ins_cycles; + int vector; + int tempi; + int cycdiff; + int oldcyc; + int cycle_period; + int ins_cycles; uint32_t addr; cycles += cycs; @@ -184,7 +268,7 @@ exec386(int cycs) if (!cpu_state.abrt) { #ifdef ENABLE_386_LOG if (in_smm) - x386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat); + x386_2386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat); #endif opcode = fetchdat & 0xFF; fetchdat >>= 8; diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 760e41eaa..5c6b43980 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -26,6 +26,7 @@ #include "386_common.h" #include "x86_flags.h" #include "x86seg.h" +#include <86box/plat_unused.h> #ifdef USE_DYNAREC # include "codegen.h" @@ -34,19 +35,26 @@ # define CPU_BLOCK_END() #endif -x86seg gdt, ldt, idt, tr; +x86seg gdt; +x86seg ldt; +x86seg idt; +x86seg tr; -uint32_t cr2, cr3, cr4; +uint32_t cr2; +uint32_t cr3; +uint32_t cr4; uint32_t dr[8]; uint32_t use32; int stack32; -uint32_t *eal_r, *eal_w; +uint32_t *eal_r; +uint32_t *eal_w; int nmi_enable = 1; -int alt_access, cpl_override = 0; +int alt_access; +int cpl_override = 0; #ifdef USE_NEW_DYNAREC uint16_t cpu_cur_status = 0; @@ -59,16 +67,60 @@ extern uint8_t *pccache2; extern int optype; extern uint32_t pccache; -int in_sys = 0, unmask_a20_in_smm = 0; -uint32_t old_rammask = 0xffffffff; +int in_sys = 0; +int unmask_a20_in_smm = 0; +uint32_t old_rammask = 0xffffffff; int soft_reset_mask = 0; int smi_latched = 0; -int smm_in_hlt = 0, smi_block = 0; +int smm_in_hlt = 0; +int smi_block = 0; -uint32_t addr64, addr64_2; -uint32_t addr64a[8], addr64a_2[8]; +int prefetch_prefixes = 0; + +int tempc; +int oldcpl; +int optype; +int inttype; +int oddeven = 0; +int timetolive; + +uint16_t oldcs; + +uint32_t oldds; +uint32_t oldss; +uint32_t olddslimit; +uint32_t oldsslimit; +uint32_t olddslimitw; +uint32_t oldsslimitw; +uint32_t oxpc; +uint32_t rmdat32; +uint32_t backupregs[16]; + +x86seg _oldds; + +int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */ + 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */ + 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */ + 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x3x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x4x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x5x */ + 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 2, 3, 1, 1, 1, 1, /* 0x6x */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x7x */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x8x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, /* 0x9x */ + 3, 3, 3, 3, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, /* 0xax */ + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xbx */ + 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 2, 1, 1, /* 0xcx */ + 3, 3, 3, 3, 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xdx */ + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */ + 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */ + +uint32_t addr64; +uint32_t addr64_2; +uint32_t addr64a[8]; +uint32_t addr64a_2[8]; static pc_timer_t *cpu_fast_off_timer = NULL; static double cpu_fast_off_period = 0.0; @@ -321,6 +373,77 @@ x386_common_log(const char *fmt, ...) # define x386_common_log(fmt, ...) #endif +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; + +void +prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads * cpu_cycles_read + reads_l * cpu_cycles_read_l + writes * cpu_cycles_write + writes_l * cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) { + if (ea32) { + if ((modrm & 7) == 4) { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } else { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } else { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +void +prefetch_flush(void) +{ + prefetch_bytes = 0; +} + static __inline void set_stack32(int s) { @@ -391,12 +514,10 @@ smm_seg_load(x86seg *s) static void smram_save_state_p5(uint32_t *saved_state, int in_hlt) { - int n = 0; - saved_state[SMRAM_FIELD_P5_SMM_REVISION_ID] = SMM_REVISION_ID; saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase; - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l; if (in_hlt) @@ -485,9 +606,7 @@ smram_save_state_p5(uint32_t *saved_state, int in_hlt) static void smram_restore_state_p5(uint32_t *saved_state) { - int n = 0; - - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n]; if (saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] & 0xffff) @@ -598,12 +717,10 @@ smram_restore_state_p5(uint32_t *saved_state) static void smram_save_state_p6(uint32_t *saved_state, int in_hlt) { - int n = 0; - saved_state[SMRAM_FIELD_P6_SMM_REVISION_ID] = SMM_REVISION_ID; saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase; - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l; if (in_hlt) @@ -684,9 +801,7 @@ smram_save_state_p6(uint32_t *saved_state, int in_hlt) static void smram_restore_state_p6(uint32_t *saved_state) { - int n = 0; - - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n]; if (saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] & 0xffff) @@ -791,12 +906,10 @@ smram_restore_state_p6(uint32_t *saved_state) static void smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) { - int n = 0; - saved_state[SMRAM_FIELD_AMD_K_SMM_REVISION_ID] = SMM_REVISION_ID; saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase; - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l; if (in_hlt) @@ -876,9 +989,7 @@ smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) static void smram_restore_state_amd_k(uint32_t *saved_state) { - int n = 0; - - for (n = 0; n < 8; n++) + for (uint8_t n = 0; n < 8; n++) cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n]; if (saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] & 0xffff) @@ -977,7 +1088,7 @@ smram_restore_state_amd_k(uint32_t *saved_state) } static void -smram_save_state_cyrix(uint32_t *saved_state, int in_hlt) +smram_save_state_cyrix(uint32_t *saved_state, UNUSED(int in_hlt)) { saved_state[0] = dr[7]; saved_state[1] = cpu_state.flags | (cpu_state.eflags << 16); @@ -1001,7 +1112,7 @@ smram_restore_state_cyrix(uint32_t *saved_state) void enter_smm(int in_hlt) { - uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n; + uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE]; uint32_t smram_state = smbase + 0x10000; /* If it's a CPU on which SMM is not supported, do nothing. */ @@ -1053,13 +1164,13 @@ enter_smm(int in_hlt) memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); - if (is_cxsmm) /* Cx6x86 */ + if (is_cxsmm) /* Cx6x86 */ smram_save_state_cyrix(saved_state, in_hlt); else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ smram_save_state_p5(saved_state, in_hlt); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ + else if (is_k5 || is_k6) /* AMD K5 and K6 */ smram_save_state_amd_k(saved_state, in_hlt); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ smram_save_state_p6(saved_state, in_hlt); cr0 &= ~0x8000000d; @@ -1128,7 +1239,7 @@ enter_smm(int in_hlt) writememl(0, smram_state - 0x18, saved_state[5]); writememl(0, smram_state - 0x24, saved_state[6]); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { smram_state -= 4; writememl(0, smram_state, saved_state[n]); } @@ -1188,7 +1299,7 @@ enter_smm_check(int in_hlt) void leave_smm(void) { - uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n; + uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE]; uint32_t smram_state = smbase + 0x10000; /* If it's a CPU on which SMM is not supported (or not implemented in 86Box), do nothing. */ @@ -1209,7 +1320,7 @@ leave_smm(void) cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); saved_state[6] = readmeml(0, smram_state - 0x24); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { smram_state -= 4; saved_state[n] = readmeml(0, smram_state); x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n); @@ -1224,13 +1335,13 @@ leave_smm(void) } x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]); - if (is_cxsmm) /* Cx6x86 */ + if (is_cxsmm) /* Cx6x86 */ smram_restore_state_cyrix(saved_state); else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ smram_restore_state_p5(saved_state); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ + else if (is_k5 || is_k6) /* AMD K5 and K6 */ smram_restore_state_amd_k(saved_state); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ smram_restore_state_p6(saved_state); in_smm = 0; @@ -1380,7 +1491,8 @@ int x86_int_sw_rm(int num) { uint32_t addr; - uint16_t new_pc, new_cs; + uint16_t new_pc; + uint16_t new_cs; flags_rebuild(); cycles -= timing_int; @@ -1468,8 +1580,10 @@ checkio(uint32_t port, int mask) int divl(uint32_t val) { - uint64_t num, quo; - uint32_t rem, quo32; + uint64_t num; + uint64_t quo; + uint32_t rem; + uint32_t quo32; if (val == 0) { divexcp(); @@ -1495,8 +1609,10 @@ divl(uint32_t val) int idivl(int32_t val) { - int64_t num, quo; - int32_t rem, quo32; + int64_t num; + int64_t quo; + int32_t rem; + int32_t quo32; if (val == 0) { divexcp(); diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 8cad28ae7..b709e743d 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -20,83 +20,112 @@ #define _386_COMMON_H_ #include - #include +#include -#define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -#define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -#define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -#define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -#define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -#define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) -#define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +#ifdef OPS_286_386 +# define readmemb_n(s, a, b) readmembl_no_mmut_2386((s) + (a), b) +# define readmemw_n(s, a, b) readmemwl_no_mmut_2386((s) + (a), b) +# define readmeml_n(s, a, b) readmemll_no_mmut_2386((s) + (a), b) +# define readmemb(s, a) readmembl_2386((s) + (a)) +# define readmemw(s, a) readmemwl_2386((s) + (a)) +# define readmeml(s, a) readmemll_2386((s) + (a)) +# define readmemq(s, a) readmemql_2386((s) + (a)) -#define writememb_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - writemembl_no_mmut((s) + (a), b, v); \ - else \ - *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememw_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - writememwl_no_mmut((s) + (a), b, v); \ - else \ - *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememl_n(s, a, b, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - writememll_no_mmut((s) + (a), b, v); \ - else \ - *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememb(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - writemembl((s) + (a), v); \ - else \ - *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememw(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - writememwl((s) + (a), v); \ - else \ - *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememl(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - writememll((s) + (a), v); \ - else \ - *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define writememq(s, a, v) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \ - writememql((s) + (a), v); \ - else \ - *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememb_n(s, a, b, v) writemembl_no_mmut_2386((s) + (a), b, v) +# define writememw_n(s, a, b, v) writememwl_no_mmut_2386((s) + (a), b, v) +# define writememl_n(s, a, b, v) writememll_no_mmut_2386((s) + (a), b, v) +# define writememb(s, a, v) writemembl_2386((s) + (a), v) +# define writememw(s, a, v) writememwl_2386((s) + (a), v) +# define writememl(s, a, v) writememll_2386((s) + (a), v) +# define writememq(s, a, v) writememql_2386((s) + (a), v) -#define do_mmut_rb(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - do_mmutranslate((s) + (a), b, 1, 0) -#define do_mmut_rw(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - do_mmutranslate((s) + (a), b, 2, 0) -#define do_mmut_rl(s, a, b) \ - if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - do_mmutranslate((s) + (a), b, 4, 0) -#define do_mmut_rb2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - do_mmutranslate((s) + (a), b, 1, 0) -#define do_mmut_rw2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - do_mmutranslate((s) + (a), b, 2, 0) -#define do_mmut_rl2(s, a, b) \ - old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ - if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - do_mmutranslate((s) + (a), b, 4, 0) +# define do_mmut_rb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 0) +# define do_mmut_rw(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 0) +# define do_mmut_rl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 0) +# define do_mmut_rb2(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 0) +# define do_mmut_rw2(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 0) +# define do_mmut_rl2(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 0) -#define do_mmut_wb(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ - do_mmutranslate((s) + (a), b, 1, 1) -#define do_mmut_ww(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ - do_mmutranslate((s) + (a), b, 2, 1) -#define do_mmut_wl(s, a, b) \ - if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ - do_mmutranslate((s) + (a), b, 4, 1) +# define do_mmut_wb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 1) +# define do_mmut_ww(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 1) +# define do_mmut_wl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 1) +#else +# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) + +# define writememb_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl_no_mmut((s) + (a), b, v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememw_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl_no_mmut((s) + (a), b, v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememl_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll_no_mmut((s) + (a), b, v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememb(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl((s) + (a), v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememw(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl((s) + (a), v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememl(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll((s) + (a), v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +# define writememq(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \ + writememql((s) + (a), v); \ + else \ + *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v + +# define do_mmut_rb(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +# define do_mmut_rw(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +# define do_mmut_rl(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) +# define do_mmut_rb2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +# define do_mmut_rw2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +# define do_mmut_rl2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) + +# define do_mmut_wb(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 1) +# define do_mmut_ww(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 1) +# define do_mmut_wl(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 1) +#endif int checkio(uint32_t port, int mask); @@ -191,27 +220,47 @@ int checkio(uint32_t port, int mask); return 1; \ } +#ifdef OPS_286_386 +/* TODO: Introduce functions to read exec. */ +static __inline uint8_t +fastreadb(uint32_t a) +{ + return readmembl(a); +} + +static __inline uint16_t +fastreadw(uint32_t a) +{ + return readmemwl(a); +} + +static __inline uint32_t +fastreadl(uint32_t a) +{ + return readmemll(a); +} +#else static __inline uint8_t fastreadb(uint32_t a) { uint8_t *t; if ((a >> 12) == pccache) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint8_t *) &pccache2[a]); -#endif +# endif t = getpccache(a); if (cpu_state.abrt) return 0; pccache = a >> 12; pccache2 = t; -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint8_t *) &pccache2[a]); -#endif +# endif } static __inline uint16_t @@ -225,22 +274,22 @@ fastreadw(uint32_t a) return val; } if ((a >> 12) == pccache) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint16_t *) &pccache2[a]); -#endif +# endif t = getpccache(a); if (cpu_state.abrt) return 0; pccache = a >> 12; pccache2 = t; -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint16_t *) &pccache2[a]); -#endif +# endif } static __inline uint32_t @@ -256,16 +305,17 @@ fastreadl(uint32_t a) pccache2 = t; pccache = a >> 12; } -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint32_t *) &pccache2[a]); -#endif +# endif } val = fastreadw(a); val |= (fastreadw(a + 2) << 16); return val; } +#endif static __inline void * get_ram_ptr(uint32_t a) @@ -288,6 +338,37 @@ get_ram_ptr(uint32_t a) extern int opcode_length[256]; +#ifdef OPS_286_386 +static __inline uint16_t +fastreadw_fetch(uint32_t a) +{ + uint16_t val; + + if ((a & 0xFFF) > 0xFFE) { + val = fastreadb(a); + if (opcode_length[val & 0xff] > 1) + val |= (fastreadb(a + 1) << 8); + return val; + } + + return readmemwl(a); +} + +static __inline uint32_t +fastreadl_fetch(uint32_t a) +{ + uint32_t val; + + if ((a & 0xFFF) > 0xFFC) { + val = fastreadw_fetch(a); + if (opcode_length[val & 0xff] > 2) + val |= (fastreadw(a + 2) << 16); + return val; + } + + return readmemll(a); +} +#else static __inline uint16_t fastreadw_fetch(uint32_t a) { @@ -300,22 +381,22 @@ fastreadw_fetch(uint32_t a) return val; } if ((a >> 12) == pccache) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint16_t *) &pccache2[a]); -#endif +# endif t = getpccache(a); if (cpu_state.abrt) return 0; pccache = a >> 12; pccache2 = t; -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint16_t *) &pccache2[a]); -#endif +# endif } static __inline uint32_t @@ -331,17 +412,18 @@ fastreadl_fetch(uint32_t a) pccache2 = t; pccache = a >> 12; } -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -#else +# else return *((uint32_t *) &pccache2[a]); -#endif +# endif } val = fastreadw_fetch(a); if (opcode_length[val & 0xff] > 2) val |= (fastreadw(a + 2) << 16); return val; } +#endif static __inline uint8_t getbyte(void) @@ -371,6 +453,93 @@ getquad(void) return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32); } +#ifdef OPS_286_386 +static __inline uint8_t +geteab(void) +{ + if (cpu_mod == 3) + return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l; + return readmemb(easeg, cpu_state.eaaddr); +} + +static __inline uint16_t +geteaw(void) +{ + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].w; + return readmemw(easeg, cpu_state.eaaddr); +} + +static __inline uint32_t +geteal(void) +{ + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].l; + return readmeml(easeg, cpu_state.eaaddr); +} + +static __inline uint64_t +geteaq(void) +{ + return readmemq(easeg, cpu_state.eaaddr); +} + +static __inline uint8_t +geteab_mem(void) +{ + return readmemb(easeg, cpu_state.eaaddr); +} +static __inline uint16_t +geteaw_mem(void) +{ + return readmemw(easeg, cpu_state.eaaddr); +} +static __inline uint32_t +geteal_mem(void) +{ + return readmeml(easeg, cpu_state.eaaddr); +} + +static __inline int +seteaq_cwc(void) +{ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + return 0; +} + +static __inline void +seteaq(uint64_t v) +{ + if (seteaq_cwc()) + return; + writememql(easeg + cpu_state.eaaddr, v); +} + +# define seteab(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \ + writemembl_2386(easeg + cpu_state.eaaddr, v); \ + } else if (cpu_rm & 4) \ + cpu_state.regs[cpu_rm & 3].b.h = v; \ + else \ + cpu_state.regs[cpu_rm].b.l = v +# define seteaw(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + writememwl_2386(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].w = v +# define seteal(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + writememll_2386(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].l = v + +# define seteab_mem(v) writemembl_2386(easeg + cpu_state.eaaddr, v); +# define seteaw_mem(v) writememwl_2386(easeg + cpu_state.eaaddr, v); +# define seteal_mem(v) writememll_2386(easeg + cpu_state.eaaddr, v); +#else static __inline uint8_t geteab(void) { @@ -444,51 +613,52 @@ seteaq(uint64_t v) writememql(easeg + cpu_state.eaaddr, v); } -#define seteab(v) \ - if (cpu_mod != 3) { \ - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \ - if (eal_w) \ - *(uint8_t *) eal_w = v; \ - else \ - writemembl(easeg + cpu_state.eaaddr, v); \ - } else if (cpu_rm & 4) \ - cpu_state.regs[cpu_rm & 3].b.h = v; \ - else \ - cpu_state.regs[cpu_rm].b.l = v -#define seteaw(v) \ - if (cpu_mod != 3) { \ - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ - if (eal_w) \ - *(uint16_t *) eal_w = v; \ +# define seteab(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); \ + } else if (cpu_rm & 4) \ + cpu_state.regs[cpu_rm & 3].b.h = v; \ else \ - writememwl(easeg + cpu_state.eaaddr, v); \ - } else \ - cpu_state.regs[cpu_rm].w = v -#define seteal(v) \ - if (cpu_mod != 3) { \ - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - if (eal_w) \ - *eal_w = v; \ - else \ - writememll(easeg + cpu_state.eaaddr, v); \ - } else \ - cpu_state.regs[cpu_rm].l = v + cpu_state.regs[cpu_rm].b.l = v +# define seteaw(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].w = v +# define seteal(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].l = v -#define seteab_mem(v) \ - if (eal_w) \ - *(uint8_t *) eal_w = v; \ - else \ - writemembl(easeg + cpu_state.eaaddr, v); -#define seteaw_mem(v) \ - if (eal_w) \ - *(uint16_t *) eal_w = v; \ - else \ - writememwl(easeg + cpu_state.eaaddr, v); -#define seteal_mem(v) \ - if (eal_w) \ - *eal_w = v; \ - else \ - writememll(easeg + cpu_state.eaaddr, v); +# define seteab_mem(v) \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); +# define seteaw_mem(v) \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); +# define seteal_mem(v) \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); +#endif #define getbytef() \ ((uint8_t) (fetchdat)); \ diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index d7b3751b2..a31704c1b 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -46,7 +46,8 @@ #define CPU_BLOCK_END() cpu_block_end = 1 -int inrecomp = 0, cpu_block_end = 0; +int inrecomp = 0; +int cpu_block_end = 0; int cpu_end_block_after_ins = 0; #ifdef ENABLE_386_DYNAREC_LOG @@ -183,78 +184,6 @@ fetch_ea_16_long(uint32_t rmdat) #include "x86_flags.h" -/*Prefetch emulation is a fairly simplistic model: - - All instruction bytes must be fetched before it starts. - - Cycles used for non-instruction memory accesses are counted and subtracted - from the total cycles taken - - Any remaining cycles are used to refill the prefetch queue. - - Note that this is only used for 286 / 386 systems. It is disabled when the - internal cache on 486+ CPUs is enabled. -*/ -static int prefetch_bytes = 0; -static int prefetch_prefixes = 0; - -static void -prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) -{ - int mem_cycles = reads * cpu_cycles_read + reads_l * cpu_cycles_read_l + writes * cpu_cycles_write + writes_l * cpu_cycles_write_l; - - if (instr_cycles < mem_cycles) - instr_cycles = mem_cycles; - - prefetch_bytes -= prefetch_prefixes; - prefetch_bytes -= bytes; - if (modrm != -1) { - if (ea32) { - if ((modrm & 7) == 4) { - if ((modrm & 0x700) == 0x500) - prefetch_bytes -= 5; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 5; - } else { - if ((modrm & 0xc7) == 0x05) - prefetch_bytes -= 4; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes--; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 4; - } - } else { - if ((modrm & 0xc7) == 0x06) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) != 0xc0) - prefetch_bytes -= ((modrm & 0xc0) >> 6); - } - } - - /* Fill up prefetch queue */ - while (prefetch_bytes < 0) { - prefetch_bytes += cpu_prefetch_width; - cycles -= cpu_prefetch_cycles; - } - - /* Subtract cycles used for memory access by instruction */ - instr_cycles -= mem_cycles; - - while (instr_cycles >= cpu_prefetch_cycles) { - prefetch_bytes += cpu_prefetch_width; - instr_cycles -= cpu_prefetch_cycles; - } - - prefetch_prefixes = 0; - if (prefetch_bytes > 16) - prefetch_bytes = 16; -} - -static void -prefetch_flush(void) -{ - prefetch_bytes = 0; -} - #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ do { \ if (cpu_prefetch_cycles) \ @@ -406,8 +335,9 @@ exec386_dynarec_int(void) static __inline void exec386_dynarec_dyn(void) { - uint32_t start_pc = 0, phys_addr = get_phys(cs + cpu_state.pc); - int hash = HASH(phys_addr); + uint32_t start_pc = 0; + uint32_t phys_addr = get_phys(cs + cpu_state.pc); + int hash = HASH(phys_addr); # ifdef USE_NEW_DYNAREC codeblock_t *block = &codeblock[codeblock_hash[hash]]; # else @@ -556,7 +486,9 @@ exec386_dynarec_dyn(void) x86_was_reset = 0; # if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(0); + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(0); + } # endif codegen_block_start_recompile(block); codegen_in_recompile = 1; @@ -640,7 +572,9 @@ exec386_dynarec_dyn(void) codegen_in_recompile = 0; # if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(1); + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(1); + } # endif } else if (!cpu_state.abrt) { /* Mark block but do not recompile */ @@ -742,10 +676,13 @@ exec386_dynarec_dyn(void) void exec386_dynarec(int cycs) { - int vector, tempi; + int vector; + int tempi; int cycdiff; - int oldcyc, oldcyc2; - uint64_t oldtsc, delta; + int oldcyc; + int oldcyc2; + uint64_t oldtsc; + uint64_t delta; int cyc_period = cycs / 2000; /*5us*/ @@ -858,3 +795,160 @@ exec386_dynarec(int cycs) } } #endif + +void +exec386(int cycs) +{ + int vector; + int tempi; + int cycdiff; + int oldcyc; + int cycle_period; + int ins_cycles; + uint32_t addr; + + cycles += cycs; + + while (cycles > 0) { + cycle_period = (timer_target - (uint32_t) tsc) + 1; + + x86_was_reset = 0; + cycdiff = 0; + oldcyc = cycles; + while (cycdiff < cycle_period) { + ins_cycles = cycles; + +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + +#ifndef USE_NEW_DYNAREC + x86_was_reset = 0; +#endif + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl_fetch(cs + cpu_state.pc); + + if (!cpu_state.abrt) { +#ifdef ENABLE_386_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat); +#endif + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + if (x86_was_reset) + break; + } +#ifdef ENABLE_386_LOG + else if (in_smm) + x386_dynarec_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc); +#endif + +#ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +#endif + + if (cpu_end_block_after_ins) + cpu_end_block_after_ins--; + + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt & ABRT_MASK; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + cpu_state.pc = cpu_state.oldpc; + x386_dynarec_log("Double fault\n"); + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } else if (trap) { + flags_rebuild(); + trap = 0; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + cpu_state.oldpc = cpu_state.pc; + dr[6] |= 0x4000; + x86_int(1); + } + + if (smi_line) + enter_smm_check(0); + else if (nmi && nmi_enable && nmi_mask) { +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; +#ifdef OLD_NMI_BEHAVIOR + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } +#else + nmi = 0; +#endif + } else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) { + vector = picinterrupt(); + if (vector != -1) { + flags_rebuild(); + if (msw & 1) + pmodeint(vector, 0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (vector << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } + } + + ins_cycles -= cycles; + tsc += ins_cycles; + + cycdiff = oldcyc - cycles; + + if (timetolive) { + timetolive--; + if (!timetolive) + fatal("Life expired\n"); + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process_inline(); + +#ifdef USE_GDBSTUB + if (gdbstub_instruction()) + return; +#endif + } + } +} diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index f3e2f6e6e..f46062bcc 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -21,6 +21,7 @@ #include <86box/pic.h> #include <86box/gdbstub.h> #include "codegen.h" +#include <86box/plat_unused.h> #define CPU_BLOCK_END() cpu_block_end = 1 @@ -31,7 +32,7 @@ #include "386_common.h" static __inline void -fetch_ea_32_long(uint32_t rmdat) +fetch_ea_32_long(UNUSED(uint32_t rmdat)) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; @@ -45,7 +46,7 @@ fetch_ea_32_long(uint32_t rmdat) } static __inline void -fetch_ea_16_long(uint32_t rmdat) +fetch_ea_16_long(UNUSED(uint32_t rmdat)) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 91449efeb..dc5eea606 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -179,7 +179,9 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_bcd.h" #include "x86_ops_bit.h" #include "x86_ops_bitscan.h" -#include "x86_ops_cyrix.h" +#ifndef OPS_286_386 +# include "x86_ops_cyrix.h" +#endif #include "x86_ops_flag.h" #include "x86_ops_fpu.h" #include "x86_ops_inc_dec.h" @@ -188,38 +190,53 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_jump.h" #include "x86_ops_misc.h" #include "x87_ops.h" -#include "x86_ops_i686.h" -#include "x86_ops_mmx.h" -#include "x86_ops_mmx_arith.h" -#include "x86_ops_mmx_cmp.h" -#include "x86_ops_mmx_logic.h" -#include "x86_ops_mmx_mov.h" -#include "x86_ops_mmx_pack.h" -#include "x86_ops_mmx_shift.h" +#ifndef OPS_286_386 +# include "x86_ops_i686.h" +# include "x86_ops_mmx.h" +# include "x86_ops_mmx_arith.h" +# include "x86_ops_mmx_cmp.h" +# include "x86_ops_mmx_logic.h" +# include "x86_ops_mmx_mov.h" +# include "x86_ops_mmx_pack.h" +# include "x86_ops_mmx_shift.h" +#endif #include "x86_ops_mov.h" #include "x86_ops_mov_ctrl.h" #include "x86_ops_mov_seg.h" #include "x86_ops_movx.h" -#include "x86_ops_msr.h" +#ifndef OPS_286_386 +# include "x86_ops_msr.h" +#endif #include "x86_ops_mul.h" #include "x86_ops_pmode.h" #include "x86_ops_prefix.h" #ifdef IS_DYNAREC # include "x86_ops_rep_dyn.h" #else -# include "x86_ops_rep.h" +# ifdef OPS_286_386 +# include "x86_ops_rep_2386.h" +# else +# include "x86_ops_rep.h" +# endif #endif #include "x86_ops_ret.h" #include "x86_ops_set.h" #include "x86_ops_stack.h" -#include "x86_ops_string.h" +#ifdef OPS_286_386 +# include "x86_ops_string_2386.h" +#else +# include "x86_ops_string.h" +#endif #include "x86_ops_xchg.h" #include "x86_ops_call.h" #include "x86_ops_shift.h" -#include "x86_ops_amd.h" -#include "x86_ops_3dnow.h" +#ifndef OPS_286_386 +# include "x86_ops_amd.h" +# include "x86_ops_3dnow.h" +#endif #include +#ifndef OPS_286_386 static int opVPCEXT(uint32_t fetchdat) { @@ -331,7 +348,54 @@ opVPCEXT(uint32_t fetchdat) return 1; } +#endif +#ifdef OPS_286_386 +static int +op0F_w_a16(uint32_t fetchdat) +{ + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; + + PREFETCH_PREFIX(); + + return x86_2386_opcodes_0f[opcode](fetchdat >> 8); +} +static int +op0F_l_a16(uint32_t fetchdat) +{ + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; + + PREFETCH_PREFIX(); + + return x86_2386_opcodes_0f[opcode | 0x100](fetchdat >> 8); +} +static int +op0F_w_a32(uint32_t fetchdat) +{ + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; + + PREFETCH_PREFIX(); + + return x86_2386_opcodes_0f[opcode | 0x200](fetchdat >> 8); +} +static int +op0F_l_a32(uint32_t fetchdat) +{ + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; + + PREFETCH_PREFIX(); + + return x86_2386_opcodes_0f[opcode | 0x300](fetchdat >> 8); +} +#else static int op0F_w_a16(uint32_t fetchdat) { @@ -376,6 +440,7 @@ op0F_l_a32(uint32_t fetchdat) return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } +#endif const OpFn OP_TABLE(186_0f)[1024] = { // clang-format off @@ -745,6 +810,7 @@ const OpFn OP_TABLE(486_0f)[1024] = { // clang-format on }; +#ifndef OPS_286_386 const OpFn OP_TABLE(c486_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -928,6 +994,7 @@ const OpFn OP_TABLE(stpc_0f)[1024] = { /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, // clang-format on }; +#endif const OpFn OP_TABLE(ibm486_0f)[1024] = { // clang-format off @@ -1021,6 +1088,7 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = { // clang-format on }; +#ifndef OPS_286_386 const OpFn OP_TABLE(winchip_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -1297,7 +1365,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = { // clang-format on }; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) const OpFn OP_TABLE(c6x86_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -1389,7 +1457,7 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = { /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, // clang-format on }; -#endif +# endif const OpFn OP_TABLE(pentiummmx_0f)[1024] = { // clang-format off @@ -1667,7 +1735,7 @@ const OpFn OP_TABLE(k62_0f)[1024] = { // clang-format on }; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) const OpFn OP_TABLE(c6x86mx_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -1759,7 +1827,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, // clang-format on }; -#endif +# endif const OpFn OP_TABLE(pentiumpro_0f)[1024] = { // clang-format off @@ -2036,6 +2104,7 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] = { /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, // clang-format on }; +#endif const OpFn OP_TABLE(186)[1024] = { // clang-format off diff --git a/src/cpu/8080.c b/src/cpu/8080.c index 6f3dd4267..7a7e7b96c 100644 --- a/src/cpu/8080.c +++ b/src/cpu/8080.c @@ -19,15 +19,21 @@ #include <86box/timer.h> #include <86box/i8080.h> #include <86box/mem.h> +#include <86box/plat_unused.h> -static int completed = 1; -static int in_rep = 0, repeating = 0, rep_c_flag = 0; -static int oldc, cycdiff; +static int completed = 1; +static int in_rep = 0; +static int repeating = 0; +static int rep_c_flag = 0; +static int oldc; +static int cycdiff; #ifdef UNUSED_8080_VARS static int prefetching = 1; -static int refresh = 0, clear_lock = 0; +static int refresh = 0; +static int clear_lock = 0; -static uint32_t cpu_src = 0, cpu_dest = 0; +static uint32_t cpu_src = 0; +static uint32_t cpu_dest = 0; static uint32_t cpu_data = 0; #endif @@ -43,7 +49,7 @@ clock_end(void) int diff = cycdiff - cycles; /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ - tsc += (uint64_t) diff * ((uint64_t) xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ + tsc += (uint64_t) diff * (xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) timer_process(); } @@ -237,7 +243,7 @@ setreg_i8080(i8080 *cpu, uint8_t reg, uint8_t val) } void -interpret_exec8080(i8080 *cpu, uint8_t opcode) +interpret_exec8080(UNUSED(i8080 *cpu), uint8_t opcode) { switch (opcode) { case 0x00: diff --git a/src/cpu/808x.c b/src/cpu/808x.c index e0419a9f7..84389874a 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -35,6 +35,8 @@ #include <86box/ppi.h> #include <86box/timer.h> #include <86box/gdbstub.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> /* Is the CPU 8088 or 8086. */ int is8086 = 0; @@ -46,7 +48,8 @@ uint32_t custom_nmi_vector = 0x00000000; static uint8_t pfq[6]; /* Variables to aid with the prefetch queue operation. */ -static int biu_cycles = 0, pfq_pos = 0; +static int biu_cycles = 0; +static int pfq_pos = 0; /* The IP equivalent of the current prefetch queue position. */ static uint16_t pfq_ip; @@ -57,43 +60,50 @@ static x86seg *_opseg[4]; static int noint = 0; static int in_lock = 0; -static int cpu_alu_op, pfq_size; +static int cpu_alu_op; +static int pfq_size; -static uint32_t cpu_src = 0, cpu_dest = 0; +static uint32_t cpu_src = 0; +static uint32_t cpu_dest = 0; static uint32_t cpu_data = 0; static uint16_t last_addr = 0x0000; static uint32_t *ovr_seg = NULL; -static int prefetching = 1, completed = 1; -static int in_rep = 0, repeating = 0, rep_c_flag = 0; -static int oldc, clear_lock = 0; -static int refresh = 0, cycdiff; +static int prefetching = 1; +static int completed = 1; +static int in_rep = 0; +static int repeating = 0; +static int rep_c_flag = 0; +static int oldc; +static int clear_lock = 0; +static int refresh = 0; +static int cycdiff; -static int access_code = 0; -static int hlda = 0; -static int not_ready = 0; -static int bus_request_type = 0; -static int pic_data = -1; -static int last_was_code = 0; -static uint16_t mem_data = 0; -static uint32_t mem_seg = 0; -static uint16_t mem_addr = 0; -static int schedule_fetch = 1; -static int pasv = 0; +static int access_code = 0; +static int hlda = 0; +static int not_ready = 0; +static int bus_request_type = 0; +static int pic_data = -1; +static int last_was_code = 0; +static uint16_t mem_data = 0; +static uint32_t mem_seg = 0; +static uint16_t mem_addr = 0; +static int schedule_fetch = 1; +static int pasv = 0; -#define BUS_OUT 1 -#define BUS_HIGH 2 -#define BUS_WIDE 4 -#define BUS_CODE 8 -#define BUS_IO 16 -#define BUS_MEM 32 -#define BUS_PIC 64 +#define BUS_OUT 1 +#define BUS_HIGH 2 +#define BUS_WIDE 4 +#define BUS_CODE 8 +#define BUS_IO 16 +#define BUS_MEM 32 +#define BUS_PIC 64 #define BUS_ACCESS_TYPE (BUS_CODE | BUS_IO | BUS_MEM | BUS_PIC) -#define BUS_CYCLE (biu_cycles & 3) -#define BUS_CYCLE_T1 biu_cycles = 0 -#define BUS_CYCLE_NEXT biu_cycles = (biu_cycles + 1) & 3 +#define BUS_CYCLE (biu_cycles & 3) +#define BUS_CYCLE_T1 biu_cycles = 0 +#define BUS_CYCLE_NEXT biu_cycles = (biu_cycles + 1) & 3 enum { BUS_T1 = 0, @@ -204,14 +214,14 @@ clock_end(void) int diff = cycdiff - cycles; /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ - tsc += ((uint64_t) diff * ((uint64_t) xt_cpu_multi >> 32ULL)); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ + tsc += ((uint64_t) diff * (xt_cpu_multi >> 32ULL)); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) timer_process(); } static void process_timers(void) -{ +{ clock_end(); clock_start(); } @@ -248,7 +258,7 @@ bus_outw(uint16_t port, uint16_t val) static uint8_t bus_inb(uint16_t port) { - int old_cycles = cycles; + int old_cycles = cycles; uint8_t ret; cycles--; @@ -261,7 +271,7 @@ bus_inb(uint16_t port) static uint16_t bus_inw(uint16_t port) { - int old_cycles = cycles; + int old_cycles = cycles; uint16_t ret; cycles--; @@ -367,7 +377,7 @@ run_bus_cycle(int io_type) not_ready = 0; } - switch(BUS_CYCLE) { + switch (BUS_CYCLE) { case BUS_T1: access_code = !!(io_type & BUS_CODE); break; @@ -384,7 +394,7 @@ run_bus_cycle(int io_type) bus_do_mem(io_type); break; case BUS_PIC: - pic_data = pic_irq_ack(); + pic_data = pic_irq_ack(); last_was_code = 0; break; default: @@ -423,9 +433,7 @@ run_dma_cycle(int idle) static void cycles_idle(int c) { - int d; - - for (d = 0; d < c; d++) { + for (int d = 0; d < c; d++) { x808x_log("[%04X:%04X] %02X TI\n", CS, cpu_state.pc, opcode); cycles_forward(1); @@ -447,17 +455,20 @@ cycles_biu(int bus, int init) switch (BUS_CYCLE) { case BUS_T1: case BUS_T2: - BUS_CYCLE_T1; /* Simply abort the prefetch before actual scheduling, no penalty. */ + BUS_CYCLE_T1; /* Simply abort the prefetch before actual scheduling, no penalty. */ break; case BUS_T3: case BUS_T4: - cycles_idle(5 - BUS_CYCLE); /* Leftover BIU cycles + 2 idle cycles. */ - BUS_CYCLE_T1; /* Abort the prefetch. */ + cycles_idle(5 - BUS_CYCLE); /* Leftover BIU cycles + 2 idle cycles. */ + BUS_CYCLE_T1; /* Abort the prefetch. */ + break; + + default: break; } schedule_fetch = 0; - access_code = 0; + access_code = 0; } } @@ -500,14 +511,12 @@ bus_init(void) static void wait(int c, int bus) { - int d; - if (c < 0) pclog("Negative cycles: %i!\n", c); x808x_log("[%04X:%04X] %02X %i cycles (%i)\n", CS, cpu_state.pc, opcode, c, bus); - for (d = 0; d < c; d++) { + for (int d = 0; d < c; d++) { x808x_log("[%04X:%04X] %02X cycle %i BIU\n", CS, cpu_state.pc, opcode, d); cycles_biu(bus, !d); x808x_log("[%04X:%04X] %02X cycle %i EU\n", CS, cpu_state.pc, opcode, d); @@ -530,12 +539,12 @@ sub_cycles(int c) void resub_cycles(int old_cycles) { - int i, cyc_diff = 0; + int cyc_diff = 0; if (old_cycles > cycles) { cyc_diff = old_cycles - cycles; - for (i = 0; i < cyc_diff; i++) { + for (int i = 0; i < cyc_diff; i++) { if (not_ready > 0) not_ready--; } @@ -564,7 +573,7 @@ cpu_io(int bits, int out, uint16_t port) } else { bus_request_type = BUS_IO | BUS_OUT; wait(4, 1); - schedule_fetch = 0; + schedule_fetch = 0; bus_request_type = BUS_IO | BUS_OUT | BUS_HIGH; wait(4, 1); } @@ -580,7 +589,7 @@ cpu_io(int bits, int out, uint16_t port) } else { bus_request_type = BUS_IO; wait(4, 1); - schedule_fetch = 0; + schedule_fetch = 0; bus_request_type = BUS_IO | BUS_HIGH; wait(4, 1); } @@ -603,11 +612,11 @@ readmemb(uint32_t s, uint16_t a) bus_init(); #endif - mem_seg = s; - mem_addr = a; + mem_seg = s; + mem_addr = a; bus_request_type = BUS_MEM; wait(4, 1); - ret = mem_data & 0xff; + ret = mem_data & 0xff; bus_request_type = 0; return ret; @@ -637,7 +646,7 @@ readmemw(uint32_t s, uint16_t a) bus_init(); #endif - mem_seg = s; + mem_seg = s; mem_addr = a; if (is8086 && !(a & 1)) { bus_request_type = BUS_MEM | BUS_WIDE; @@ -645,11 +654,11 @@ readmemw(uint32_t s, uint16_t a) } else { bus_request_type = BUS_MEM | BUS_HIGH; wait(4, 1); - schedule_fetch = 0; + schedule_fetch = 0; bus_request_type = BUS_MEM; wait(4, 1); } - ret = mem_data; + ret = mem_data; bus_request_type = 0; return ret; @@ -710,9 +719,9 @@ writememb(uint32_t s, uint32_t a, uint8_t v) bus_init(); #endif - mem_seg = s; - mem_addr = a; - mem_data = v; + mem_seg = s; + mem_addr = a; + mem_data = v; bus_request_type = BUS_MEM | BUS_OUT; wait(4, 1); bus_request_type = 0; @@ -731,7 +740,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v) bus_init(); #endif - mem_seg = s; + mem_seg = s; mem_addr = a; mem_data = v; if (is8086 && !(a & 1)) { @@ -740,7 +749,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v) } else { bus_request_type = BUS_MEM | BUS_OUT | BUS_HIGH; wait(4, 1); - schedule_fetch = 0; + schedule_fetch = 0; bus_request_type = BUS_MEM | BUS_OUT; wait(4, 1); } @@ -785,13 +794,13 @@ pfq_write(void) free in the queue. */ tempw = readmemwf(pfq_ip); *(uint16_t *) &(pfq[pfq_pos]) = tempw; - pfq_ip = (pfq_ip + 2) & 0xffff; + pfq_ip = (pfq_ip + 2) & 0xffff; pfq_pos += 2; } else if (!fetch_word && (pfq_pos < pfq_size)) { /* The 8088 fetches 1 byte at a time, and only if there's at least 1 byte free in the queue. */ pfq[pfq_pos] = readmembf(pfq_ip); - pfq_ip = (pfq_ip + 1) & 0xffff; + pfq_ip = (pfq_ip + 1) & 0xffff; pfq_pos++; } @@ -884,8 +893,8 @@ pfq_add(void) static void pfq_clear(void) { - pfq_pos = 0; - prefetching = 0; + pfq_pos = 0; + prefetching = 0; schedule_fetch = 0; BUS_CYCLE_T1; @@ -894,8 +903,8 @@ pfq_clear(void) static void pfq_suspend(void) { - pfq_clear(); - cycles_idle(3); + pfq_clear(); + cycles_idle(3); } static void @@ -934,7 +943,7 @@ reset_808x(int hard) _opseg[2] = &cpu_state.seg_ss; _opseg[3] = &cpu_state.seg_ds; - pfq_size = (is8086) ? 6 : 4; + pfq_size = is8086 ? 6 : 4; pfq_clear(); } @@ -949,20 +958,20 @@ reset_808x(int hard) schedule_fetch = 1; pasv = 0; - cpu_alu_op = 0; + cpu_alu_op = 0; use_custom_nmi_vector = 0x00; custom_nmi_vector = 0x00000000; - access_code = 0; - hlda = 0; - not_ready = 0; - bus_request_type = 0; - pic_data = -1; - last_was_code = 0; - mem_data = 0; - mem_seg = 0; - mem_addr = 0; + access_code = 0; + hlda = 0; + not_ready = 0; + bus_request_type = 0; + pic_data = -1; + last_was_code = 0; + mem_data = 0; + mem_seg = 0; + mem_addr = 0; } static void @@ -970,7 +979,7 @@ set_ip(uint16_t new_ip) { pfq_ip = cpu_state.pc = new_ip; prefetching = 1; - schedule_fetch = prefetching && (pfq_pos < pfq_size); + schedule_fetch = prefetching && (pfq_pos < pfq_size); } /* Memory refresh read - called by reads and writes on DMA channel 0. */ @@ -1019,16 +1028,20 @@ do_mod_rm(void) easeg = ovr_seg ? *ovr_seg : ds; wait(2, 0); return; - } else switch (cpu_rm) { - case 0: - case 3: - wait(2, 0); - break; - case 1: - case 2: - wait(3, 0); - break; - } + } else + switch (cpu_rm) { + case 0: + case 3: + wait(2, 0); + break; + case 1: + case 2: + wait(3, 0); + break; + + default: + break; + } cpu_state.eaaddr = (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); easeg = ovr_seg ? *ovr_seg : *mod1seg[cpu_rm]; switch (rmdat & 0xc0) { @@ -1042,6 +1055,8 @@ do_mod_rm(void) cpu_state.eaaddr += pfq_fetchw(); wait(1, 0); break; + default: + break; } cpu_state.eaaddr &= 0xffff; wait(2, 0); @@ -1205,18 +1220,20 @@ pop(void) static void interrupt(uint16_t addr) { - uint16_t old_cs, old_ip; - uint16_t new_cs, new_ip; + uint16_t old_cs; + uint16_t old_ip; + uint16_t new_cs; + uint16_t new_ip; uint16_t tempf; addr <<= 2; cpu_state.eaaddr = addr; old_cs = CS; - new_ip = readmemw(0, cpu_state.eaaddr); + new_ip = readmemw(0, cpu_state.eaaddr); wait(1, 0); cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; - new_cs = readmemw(0, cpu_state.eaaddr); - prefetching = 0; + new_cs = readmemw(0, cpu_state.eaaddr); + prefetching = 0; pfq_clear(); ovr_seg = NULL; wait(2, 0); @@ -1242,8 +1259,10 @@ interrupt_808x(uint16_t addr) static void custom_nmi(void) { - uint16_t old_cs, old_ip; - uint16_t new_cs, new_ip; + uint16_t old_cs; + uint16_t old_ip; + uint16_t new_cs; + uint16_t new_ip; uint16_t tempf; cpu_state.eaaddr = 0x0002; @@ -1286,7 +1305,7 @@ bus_pic_ack(void) { int old_in_lock = in_lock; - in_lock = 1; + in_lock = 1; bus_request_type = BUS_PIC; wait(4, 1); in_lock = old_in_lock; @@ -1366,7 +1385,7 @@ rep_interrupt(void) return 0; } completed = 1; - CX = tmpc; + CX = tmpc; pfq_clear(); if (is_nec && (ovr_seg != NULL)) set_ip(cpu_state.pc - 3); @@ -1376,7 +1395,7 @@ rep_interrupt(void) } static int -rep_action(int bits) +rep_action(UNUSED(int bits)) { uint16_t t; @@ -1562,14 +1581,14 @@ alu_op(int bits) case 2: if (cpu_state.flags & C_FLAG) cpu_src++; - /* Fall through. */ + fallthrough; case 0: add(bits); break; case 3: if (cpu_state.flags & C_FLAG) cpu_src++; - /* Fall through. */ + fallthrough; case 5: case 7: sub(bits); @@ -1580,6 +1599,9 @@ alu_op(int bits) case 6: bitwise(bits, (cpu_dest ^ cpu_src)); break; + + default: + break; } } @@ -1600,10 +1622,11 @@ mul(uint16_t a, uint16_t b) { int negate = 0; int bit_count = 8; - int carry, i; + int carry; uint16_t high_bit = 0x80; uint16_t size_mask; - uint16_t c, r; + uint16_t c; + uint16_t r; size_mask = (1 << bit_count) - 1; @@ -1644,7 +1667,7 @@ mul(uint16_t a, uint16_t b) a &= size_mask; carry = (a & 1) != 0; a >>= 1; - for (i = 0; i < bit_count; ++i) { + for (int i = 0; i < bit_count; ++i) { wait(7, 0); if (carry) { cpu_src = c; @@ -1705,7 +1728,7 @@ set_pzs(int bits) } static void -set_co_mul(int bits, int carry) +set_co_mul(UNUSED(int bits), int carry) { set_cf(carry); set_of(carry); @@ -1718,10 +1741,11 @@ set_co_mul(int bits, int carry) static int x86_div(uint16_t l, uint16_t h) { - int b, bit_count = 8; + int bit_count = 8; int negative = 0; int dividend_negative = 0; - int size_mask, carry; + int size_mask; + int carry; uint16_t r; if (opcode & 1) { @@ -1765,7 +1789,7 @@ x86_div(uint16_t l, uint16_t h) wait(1, 0); wait(2, 0); carry = 1; - for (b = 0; b < bit_count; ++b) { + for (int b = 0; b < bit_count; ++b) { r = (l << 1) + (carry ? 1 : 0); carry = top_bit(l, bit_count); l = r; @@ -1948,20 +1972,46 @@ cpu_outw(uint16_t port, uint16_t val) void execx86(int cycs) { - uint8_t temp = 0, temp2, old_af, nests; - uint8_t temp_val, temp_al, bit, handled = 0; - uint8_t odd, zero, nibbles_count, destcmp; - uint8_t destbyte, srcbyte, nibble_result, bit_length; + uint8_t temp = 0; + uint8_t temp2; + uint8_t old_af; + uint8_t nests; + uint8_t temp_val; + uint8_t temp_al; + uint8_t bit; + uint8_t handled = 0; + uint8_t odd; + uint8_t zero; + uint8_t nibbles_count; + uint8_t destcmp; + uint8_t destbyte; + uint8_t srcbyte; + uint8_t nibble_result; + uint8_t bit_length; uint8_t bit_offset; int8_t nibble_result_s; - uint16_t addr, tempw, new_cs, new_ip; - uint16_t tempw_int, size, tempbp, lowbound; - uint16_t highbound, regval, orig_sp, wordtopush; - uint16_t immediate, old_flags; - uint16_t tmpa; + uint16_t addr; + uint16_t tempw; + uint16_t new_cs; + uint16_t new_ip; + uint16_t tempw_int; + uint16_t size; + uint16_t tempbp; + uint16_t lowbound; + uint16_t highbound; + uint16_t regval; + uint16_t orig_sp; + uint16_t wordtopush; + uint16_t immediate; + uint16_t old_flags; + uint16_t tmpa; int bits; - uint32_t dest_seg, i, carry, nibble; - uint32_t srcseg, byteaddr; + uint32_t dest_seg; + uint32_t i; + uint32_t carry; + uint32_t nibble; + uint32_t srcseg; + uint32_t byteaddr; cycles += cycs; @@ -1970,10 +2020,12 @@ execx86(int cycs) if (!repeating) { cpu_state.oldpc = cpu_state.pc; - // opcode = pfq_fetchb(); - opcode = pfq_fetchb_common(); - handled = 0; - oldc = cpu_state.flags & C_FLAG; +#if 0 + opcode = pfq_fetchb(); +#endif + opcode = pfq_fetchb_common(); + handled = 0; + oldc = cpu_state.flags & C_FLAG; if (clear_lock) { in_lock = 0; clear_lock = 0; @@ -2233,6 +2285,9 @@ execx86(int cycs) set_af(0); set_pzs(bits); break; + + default: + break; } if ((opcode & 2) != 0) wait(4, 0); @@ -2247,6 +2302,9 @@ execx86(int cycs) BP = pop(); handled = 1; break; + + default: + break; } } if (!handled) { @@ -2498,7 +2556,7 @@ execx86(int cycs) } for (i = 0; i < bit_length; i++) { byteaddr = (es) + DI; - writememb(es, DI, (read_mem_b(byteaddr) & ~(1 << (bit_offset))) | ((!!(AX & (1 << i))) << bit_offset)); + writememb(es, DI, (read_mem_b(byteaddr) & ~(1 << bit_offset)) | ((!!(AX & (1 << i))) << bit_offset)); bit_offset++; if (bit_offset == 8) { DI++; @@ -2547,7 +2605,7 @@ execx86(int cycs) break; default: - opcode = orig_opcode; + opcode = orig_opcode; cpu_state.pc = (cpu_state.pc - 1) & 0xffff; break; } @@ -3063,7 +3121,7 @@ execx86(int cycs) bits = 8 << (opcode & 1); wait(2, 0); cpu_state.eaaddr = pfq_fetchw(); - set_accum(bits, readmem((ovr_seg ? *ovr_seg : ds))); + set_accum(bits, readmem(ovr_seg ? *ovr_seg : ds)); break; case 0xA2: case 0xA3: @@ -3125,7 +3183,7 @@ execx86(int cycs) wait(2, 0); cpu_state.eaaddr = DI; cpu_data = readmem(es); - DI = string_increment(bits); + DI = string_increment(bits); cpu_src = cpu_data; cpu_dest = tmpa; sub(bits); @@ -3392,6 +3450,9 @@ execx86(int cycs) set_af(0); set_pzs(bits); break; + + default: + break; } if ((opcode & 2) != 0) wait(4, 0); @@ -3453,55 +3514,61 @@ execx86(int cycs) if (fpu_softfloat) { switch (opcode) { case 0xD8: - ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); + ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat); break; case 0xD9: - ops_sf_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat); + ops_sf_fpu_8087_d9[rmdat & 0xff](rmdat); break; case 0xDA: - ops_sf_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat); + ops_sf_fpu_8087_da[rmdat & 0xff](rmdat); break; case 0xDB: - ops_sf_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat); + ops_sf_fpu_8087_db[rmdat & 0xff](rmdat); break; case 0xDC: - ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); + ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat); break; case 0xDD: - ops_sf_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat); + ops_sf_fpu_8087_dd[rmdat & 0xff](rmdat); break; case 0xDE: - ops_sf_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat); + ops_sf_fpu_8087_de[rmdat & 0xff](rmdat); break; case 0xDF: - ops_sf_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat); + ops_sf_fpu_8087_df[rmdat & 0xff](rmdat); + break; + + default: break; } } else { switch (opcode) { case 0xD8: - ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); + ops_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat); break; case 0xD9: - ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat); + ops_fpu_8087_d9[rmdat & 0xff](rmdat); break; case 0xDA: - ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat); + ops_fpu_8087_da[rmdat & 0xff](rmdat); break; case 0xDB: - ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat); + ops_fpu_8087_db[rmdat & 0xff](rmdat); break; case 0xDC: - ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); + ops_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat); break; case 0xDD: - ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat); + ops_fpu_8087_dd[rmdat & 0xff](rmdat); break; case 0xDE: - ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat); + ops_fpu_8087_de[rmdat & 0xff](rmdat); break; case 0xDF: - ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat); + ops_fpu_8087_df[rmdat & 0xff](rmdat); + break; + + default: break; } } @@ -3531,6 +3598,9 @@ execx86(int cycs) if (!(cpu_state.flags & Z_FLAG)) oldc = 0; break; + + default: + break; } } else oldc = (CX == 0); @@ -3542,7 +3612,7 @@ execx86(int cycs) case 0xE5: bits = 8 << (opcode & 1); wait(1, 0); - cpu_data = pfq_fetchb(); + cpu_data = pfq_fetchb(); cpu_state.eaaddr = cpu_data; wait(1, 0); cpu_io(bits, 0, cpu_state.eaaddr); @@ -3551,16 +3621,16 @@ execx86(int cycs) case 0xE7: bits = 8 << (opcode & 1); wait(1, 0); - cpu_data = pfq_fetchb(); + cpu_data = pfq_fetchb(); cpu_state.eaaddr = cpu_data; - cpu_data = (bits == 16) ? AX : AL; + cpu_data = (bits == 16) ? AX : AL; wait(2, 0); cpu_io(bits, 1, cpu_state.eaaddr); break; case 0xEC: case 0xED: - bits = 8 << (opcode & 1); - cpu_data = DX; + bits = 8 << (opcode & 1); + cpu_data = DX; cpu_state.eaaddr = cpu_data; wait(1, 0); cpu_io(bits, 0, cpu_state.eaaddr); @@ -3569,9 +3639,9 @@ execx86(int cycs) case 0xEF: bits = 8 << (opcode & 1); wait(2, 0); - cpu_data = DX; + cpu_data = DX; cpu_state.eaaddr = cpu_data; - cpu_data = (bits == 16) ? AX : AL; + cpu_data = (bits == 16) ? AX : AL; cpu_io(bits, 1, cpu_state.eaaddr); wait(1, 0); break; @@ -3703,6 +3773,9 @@ execx86(int cycs) if (x86_div(AL, AH)) wait(1, 0); break; + + default: + break; } break; @@ -3800,7 +3873,10 @@ execx86(int cycs) if (cpu_mod != 3) wait(1, 0); wait(4, 0); - push((uint16_t *) &(cpu_data)); + push((uint16_t *) &cpu_data); + break; + + default: break; } break; diff --git a/src/cpu/808x/queue.c b/src/cpu/808x/queue.c index 2eebde0ce..b37ee0fb0 100644 --- a/src/cpu/808x/queue.c +++ b/src/cpu/808x/queue.c @@ -15,6 +15,7 @@ * Copyright 2023 gloriouscow. * Copyright 2023 Miran Grca. */ +#include #include #include #include @@ -41,12 +42,13 @@ /* TODO: Move to cpu.h so this can eventually be reused for 286+ as well. */ #define QUEUE_MAX 6 -typedef struct queue_t -{ - size_t size; - size_t len; - size_t back; - size_t front; +/* NOTE: When porting from Rust to C, please use uintptr_t and not size_t, + so it can be printed with PRIuPTR. */ +typedef struct queue_t { + uintptr_t size; + uintptr_t len; + uintptr_t back; + uintptr_t front; uint8_t q[QUEUE_MAX]; uint16_t preload; queue_delay_t delay; @@ -73,15 +75,15 @@ queue_log(const char *fmt, ...) #endif void -queue_set_size(size_t size) +queue_set_size(uintptr_t size) { if (size > QUEUE_MAX) - fatal("Requested prefetch queue of %i bytes is too big\n", size); + fatal("Requested prefetch queue of %" PRIuPTR " bytes is too big\n", size); queue.size = size; } -size_t +uintptr_t queue_get_len(void) { return queue.len; diff --git a/src/cpu/808x/queue.h b/src/cpu/808x/queue.h index 544455784..7c1998295 100644 --- a/src/cpu/808x/queue.h +++ b/src/cpu/808x/queue.h @@ -17,27 +17,26 @@ #ifndef EMU_QUEUE_H #define EMU_QUEUE_H -typedef enum queue_delay_t -{ +typedef enum queue_delay_t { DELAY_READ, DELAY_WRITE, DELAY_NONE } queue_delay_t; -#define FLAG_PRELOADED 0x8000 +#define FLAG_PRELOADED 0x8000 -extern void queue_set_size(size_t size); -extern size_t queue_get_len(void); -extern int queue_is_full(void); -extern uint16_t queue_get_preload(void); -extern int queue_has_preload(void); -extern void queue_set_preload(void); -extern void queue_push8(uint8_t byte); -extern void queue_push16(uint16_t word); -extern uint8_t queue_pop(void); -extern queue_delay_t queue_get_delay(void); -extern void queue_flush(void); +extern void queue_set_size(uintptr_t size); +extern uintptr_t queue_get_len(void); +extern int queue_is_full(void); +extern uint16_t queue_get_preload(void); +extern int queue_has_preload(void); +extern void queue_set_preload(void); +extern void queue_push8(uint8_t byte); +extern void queue_push16(uint16_t word); +extern uint8_t queue_pop(void); +extern queue_delay_t queue_get_delay(void); +extern void queue_flush(void); -extern void queue_init(void); +extern void queue_init(void); #endif /*EMU_QUEUE_H*/ diff --git a/src/cpu/codegen_timing_486.c b/src/cpu/codegen_timing_486.c index 2fe5ce417..e862b123e 100644 --- a/src/cpu/codegen_timing_486.c +++ b/src/cpu/codegen_timing_486.c @@ -3,8 +3,10 @@ #include #include #include <86box/86box.h> -#include <86box/mem.h> #include "cpu.h" +#include <86box/mem.h> +#include <86box/plat_unused.h> + #include "x86.h" #include "x86_ops.h" #include "x87.h" @@ -12,11 +14,11 @@ #include "codegen_ops.h" #include "codegen_timing_common.h" -#define CYCLES(c) (int *)c -#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8)) +#define CYCLES(c) (int *) c +#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8)) -static int *opcode_timings[256] = -{ +static int *opcode_timings[256] = { + // clang-format off /*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), /*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), @@ -36,10 +38,11 @@ static int *opcode_timings[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL + // clang-format on }; -static int *opcode_timings_mod3[256] = -{ +static int *opcode_timings_mod3[256] = { + // clang-format off /*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), /*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), @@ -59,10 +62,11 @@ static int *opcode_timings_mod3[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL + // clang-format on }; -static int *opcode_timings_0f[256] = -{ +static int *opcode_timings_0f[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -82,9 +86,10 @@ static int *opcode_timings_0f[256] = /*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, + // clang-format on }; -static int *opcode_timings_0f_mod3[256] = -{ +static int *opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -104,60 +109,69 @@ static int *opcode_timings_0f_mod3[256] = /*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, + // clang-format on }; -static int *opcode_timings_shift[8] = -{ +static int *opcode_timings_shift[8] = { + // clang-format off CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) }; -static int *opcode_timings_shift_mod3[8] = -{ +static int *opcode_timings_shift_mod3[8] = { +// clang-format off CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) + // clang-format on }; -static int *opcode_timings_f6[8] = -{ +static int *opcode_timings_f6[8] = { + // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static int *opcode_timings_f6_mod3[8] = -{ +static int *opcode_timings_f6_mod3[8] = { + // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static int *opcode_timings_f7[8] = -{ +static int *opcode_timings_f7[8] = { + // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static int *opcode_timings_f7_mod3[8] = -{ +static int *opcode_timings_f7_mod3[8] = { + // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) }; -static int *opcode_timings_ff[8] = -{ +static int *opcode_timings_ff[8] = { +// clang-format off &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL }; -static int *opcode_timings_ff_mod3[8] = -{ +static int *opcode_timings_ff_mod3[8] = { +// clang-format off &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL + // clang-format on }; -static int *opcode_timings_d8[8] = -{ +static int *opcode_timings_d8[8] = { + // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_d8_mod3[8] = -{ +static int *opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_d9[8] = -{ +static int *opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) + // clang-format on }; -static int *opcode_timings_d9_mod3[64] = -{ +static int *opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), /*FXCH*/ @@ -174,26 +188,29 @@ static int *opcode_timings_d9_mod3[64] = CYCLES(140), CYCLES(196), CYCLES(200), CYCLES(218), NULL, NULL, CYCLES(3), CYCLES(3), /* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/ CYCLES(70), NULL, CYCLES(83), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(257), CYCLES(257) + // clang-format on }; -static int *opcode_timings_da[8] = -{ +static int *opcode_timings_da[8] = { + // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_da_mod3[8] = -{ +static int *opcode_timings_da_mod3[8] = { + // clang-format off NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL + // clang-format on }; - -static int *opcode_timings_db[8] = -{ +static int *opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil FLDe FSTPe*/ CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6) + // clang-format on }; -static int *opcode_timings_db_mod3[64] = -{ +static int *opcode_timings_db_mod3[64] = { + // clang-format off NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -203,219 +220,242 @@ static int *opcode_timings_db_mod3[64] = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -static int *opcode_timings_dc[8] = -{ +static int *opcode_timings_dc[8] = { + // clang-format off /* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_dc_mod3[8] = -{ +static int *opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_dd[8] = -{ +static int *opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3) + // clang-format on }; -static int *opcode_timings_dd_mod3[8] = -{ +static int *opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL + // clang-format on }; -static int *opcode_timings_de[8] = -{ +static int *opcode_timings_de[8] = { + // clang-format off /* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_de_mod3[8] = -{ +static int *opcode_timings_de_mod3[8] = { + // clang-format off /* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) + // clang-format on }; -static int *opcode_timings_df[8] = -{ +static int *opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28) + // clang-format on }; -static int *opcode_timings_df_mod3[8] = -{ +static int *opcode_timings_df_mod3[8] = { + // clang-format off /* FFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL + // clang-format on }; -static int *opcode_timings_8x[8] = -{ +static int *opcode_timings_8x[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int *opcode_timings_8x_mod3[8] = -{ +static int *opcode_timings_8x_mod3[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int *opcode_timings_81[8] = -{ +static int *opcode_timings_81[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int *opcode_timings_81_mod3[8] = -{ +static int *opcode_timings_81_mod3[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int timing_count; -static uint8_t last_prefix; +static int timing_count; +static uint8_t last_prefix; static uint32_t regmask_modified; -static inline int COUNT(int *c, int op_32) +static inline int +COUNT(int *c, int op_32) { - if ((uintptr_t)c <= 10000) - return (int)(uintptr_t)c; - if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff)) - { - if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; - } - return *c; + if ((uintptr_t) c <= 10000) + return (int) (uintptr_t) c; + if (((uintptr_t) c & ~0xffff) == (-1 & ~0xffff)) { + if (op_32 & 0x100) + return ((uintptr_t) c >> 8) & 0xff; + return (uintptr_t) c & 0xff; + } + return *c; } -void codegen_timing_486_block_start(void) +void +codegen_timing_486_block_start(void) { - regmask_modified = 0; + regmask_modified = 0; } -void codegen_timing_486_start(void) +void +codegen_timing_486_start(void) { - timing_count = 0; - last_prefix = 0; + timing_count = 0; + last_prefix = 0; } -void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) { - timing_count += COUNT(opcode_timings[prefix], 0); - last_prefix = prefix; + timing_count += COUNT(opcode_timings[prefix], 0); + last_prefix = prefix; } -void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +void +codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) { - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); + int **timings; + const uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } - case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; + timing_count += COUNT(timings[opcode], op_32); + if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) + timing_count++; /*AGI stall*/ + codegen_block_cycles += timing_count; - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - timing_count += COUNT(timings[opcode], op_32); - if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) - timing_count++; /*AGI stall*/ - codegen_block_cycles += timing_count; - - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_486_block_end(void) +void +codegen_timing_486_block_end(void) { + // } -codegen_timing_t codegen_timing_486 = -{ - codegen_timing_486_start, - codegen_timing_486_prefix, - codegen_timing_486_opcode, - codegen_timing_486_block_start, - codegen_timing_486_block_end, - NULL +codegen_timing_t codegen_timing_486 = { + codegen_timing_486_start, + codegen_timing_486_prefix, + codegen_timing_486_opcode, + codegen_timing_486_block_start, + codegen_timing_486_block_end, + NULL }; diff --git a/src/cpu/codegen_timing_686.c b/src/cpu/codegen_timing_686.c index 7d7f4042d..a6800c5b2 100644 --- a/src/cpu/codegen_timing_686.c +++ b/src/cpu/codegen_timing_686.c @@ -13,8 +13,10 @@ #include #include #include <86box/86box.h> -#include <86box/mem.h> #include "cpu.h" +#include <86box/mem.h> +#include <86box/plat_unused.h> + #include "x86.h" #include "x86_ops.h" #include "x87.h" @@ -22,7 +24,7 @@ #include "codegen_timing_common.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ -#define CYCLES_HAS_MULTI (1 << 31) +#define CYCLES_HAS_MULTI (1 << 31) #define CYCLES_MULTI(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) @@ -31,39 +33,39 @@ /*Instruction follows either register timing, read-modify, or read-modify-write. May be pairable*/ -#define CYCLES_REG (1 << 0) -#define CYCLES_RM (1 << 0) -#define CYCLES_RMW (1 << 0) +#define CYCLES_REG (1 << 0) +#define CYCLES_RM (1 << 0) +#define CYCLES_RMW (1 << 0) #define CYCLES_BRANCH (1 << 0) -#define CYCLES_MASK ((1 << 7) - 1) +#define CYCLES_MASK ((1 << 7) - 1) /*Instruction does not pair*/ #define PAIR_NP (0 << 29) /*Instruction pairs in X pipe only*/ -#define PAIR_X (1 << 29) +#define PAIR_X (1 << 29) /*Instruction pairs in X pipe only, and can not pair with a following instruction*/ -#define PAIR_X_BRANCH (2 << 29) +#define PAIR_X_BRANCH (2 << 29) /*Instruction pairs in both X and Y pipes*/ -#define PAIR_XY (3 << 29) +#define PAIR_XY (3 << 29) #define PAIR_MASK (3 << 29) -#define INVALID 0 +#define INVALID 0 -static int prev_full; -static uint32_t prev_opcode; +static int prev_full; +static uint32_t prev_opcode; static uint32_t *prev_timings; -static uint32_t prev_op_32; -static uint32_t prev_regmask; +static uint32_t prev_op_32; +static uint32_t prev_regmask; static uint64_t *prev_deps; -static uint32_t prev_fetchdat; +static uint32_t prev_fetchdat; static uint32_t last_regmask_modified; static uint32_t regmask_modified; -static uint32_t opcode_timings[256] = -{ +static uint32_t opcode_timings[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, /* ADD ADD PUSH ES POP ES*/ @@ -196,10 +198,11 @@ static uint32_t opcode_timings[256] = PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), /* CLD STD INCDEC*/ PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_RMW, INVALID + // clang-format on }; -static uint32_t opcode_timings_mod3[256] = -{ +static uint32_t opcode_timings_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, /* ADD ADD PUSH ES POP ES*/ @@ -333,10 +336,11 @@ static uint32_t opcode_timings_mod3[256] = PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), /* CLD STD INCDEC*/ PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES_REG, INVALID + // clang-format on }; -static uint32_t opcode_timings_0f[256] = -{ +static uint32_t opcode_timings_0f[256] = { + // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, @@ -416,9 +420,10 @@ static uint32_t opcode_timings_0f[256] = INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, + // clang-format on }; -static uint32_t opcode_timings_0f_mod3[256] = -{ +static uint32_t opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, @@ -497,106 +502,122 @@ static uint32_t opcode_timings_0f_mod3[256] = INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, + // clang-format on }; -static uint32_t opcode_timings_shift[8] = -{ +static uint32_t opcode_timings_shift[8] = { + // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, + // clang-format on }; -static uint32_t opcode_timings_shift_mod3[8] = -{ +static uint32_t opcode_timings_shift_mod3[8] = { + // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + // clang-format on }; -static uint32_t opcode_timings_shift_imm[8] = -{ +static uint32_t opcode_timings_shift_imm[8] = { + // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, + // clang-format on }; -static uint32_t opcode_timings_shift_imm_mod3[8] = -{ +static uint32_t opcode_timings_shift_imm_mod3[8] = { + // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + // clang-format on }; -static uint32_t opcode_timings_shift_cl[8] = -{ +static uint32_t opcode_timings_shift_cl[8] = { + // clang-format off PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), + // clang-format on }; -static uint32_t opcode_timings_shift_cl_mod3[8] = -{ +static uint32_t opcode_timings_shift_cl_mod3[8] = { + // clang-format off PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), + // clang-format on }; -static uint32_t opcode_timings_f6[8] = -{ +static uint32_t opcode_timings_f6[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18) + // clang-format on }; -static uint32_t opcode_timings_f6_mod3[8] = -{ +static uint32_t opcode_timings_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18) + // clang-format on }; -static uint32_t opcode_timings_f7[8] = -{ +static uint32_t opcode_timings_f7[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) + // clang-format on }; -static uint32_t opcode_timings_f7_mod3[8] = -{ +static uint32_t opcode_timings_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) + // clang-format on }; -static uint32_t opcode_timings_ff[8] = -{ +static uint32_t opcode_timings_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), /* JMP JMP far PUSH*/ PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID + // clang-format on }; -static uint32_t opcode_timings_ff_mod3[8] = -{ +static uint32_t opcode_timings_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), /* JMP JMP far PUSH*/ PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), PAIR_XY | CYCLES(2), INVALID + // clang-format on }; -static uint32_t opcode_timings_d8[8] = -{ +static uint32_t opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), /* FSUBs FSUBRs FDIVs FDIVRs*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_d8_mod3[8] = -{ +static uint32_t opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), /* FSUB FSUBR FDIV FDIVR*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_d9[8] = -{ +static uint32_t opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), /* FLDENV FLDCW FSTENV FSTCW*/ PAIR_X | CYCLES(30), PAIR_X | CYCLES(4), PAIR_X | CYCLES(24), PAIR_X | CYCLES(5) + // clang-format on }; -static uint32_t opcode_timings_d9_mod3[64] = -{ +static uint32_t opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), @@ -625,31 +646,34 @@ static uint32_t opcode_timings_d9_mod3[64] = PAIR_X | CYCLES(91), INVALID, PAIR_X | CYCLES(60), PAIR_X | CYCLES(161), /* opFRNDINT opFSCALE opFSIN opFCOS*/ PAIR_X | CYCLES(20), PAIR_X | CYCLES(14), PAIR_X | CYCLES(140), PAIR_X | CYCLES(141) + // clang-format on }; -static uint32_t opcode_timings_da[8] = -{ +static uint32_t opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10), /* FISUBl FISUBRl FIDIVl FIDIVRl*/ PAIR_X | CYCLES(29), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(48) + // clang-format on }; -static uint32_t opcode_timings_da_mod3[8] = -{ +static uint32_t opcode_timings_da_mod3[8] = { + // clang-format off PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, PAIR_X | CYCLES(5), INVALID, INVALID + // clang-format on }; - -static uint32_t opcode_timings_db[8] = -{ +static uint32_t opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), /* FLDe FSTPe*/ INVALID, PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_db_mod3[64] = -{ +static uint32_t opcode_timings_db_mod3[64] = { + // clang-format off PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), @@ -675,383 +699,387 @@ static uint32_t opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static uint32_t opcode_timings_dc[8] = -{ +static uint32_t opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), /* FSUBd FSUBRd FDIVd FDIVRd*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_dc_mod3[8] = -{ +static uint32_t opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_dd[8] = -{ +static uint32_t opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), /* FRSTOR FSAVE FSTSW*/ PAIR_X | CYCLES(72), INVALID, PAIR_X | CYCLES(67), PAIR_X | CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_dd_mod3[8] = -{ +static uint32_t opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ PAIR_X | CYCLES(3), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), /* FUCOM FUCOMP*/ PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, INVALID + // clang-format on }; -static uint32_t opcode_timings_de[8] = -{ +static uint32_t opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10), /* FISUBw FISUBRw FIDIVw FIDIVRw*/ PAIR_X | CYCLES(27), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(38) }; -static uint32_t opcode_timings_de_mod3[8] = -{ +static uint32_t opcode_timings_de_mod3[8] = { + // clang-format off /* FADD FMUL FCOMPP*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, PAIR_X | CYCLES(7), /* FSUB FSUBR FDIV FDIVR*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) + // clang-format on }; -static uint32_t opcode_timings_df[8] = -{ +static uint32_t opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ PAIR_X | CYCLES(8), INVALID, PAIR_X | CYCLES(10), PAIR_X | CYCLES(13), /* FILDiq FBSTP FISTPiq*/ INVALID, PAIR_X | CYCLES(8), PAIR_X | CYCLES(63), PAIR_X | CYCLES(13) + // clang-format on }; -static uint32_t opcode_timings_df_mod3[8] = -{ +static uint32_t opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ PAIR_X | CYCLES(6), INVALID, INVALID, INVALID + // clang-format on }; -static uint32_t opcode_timings_8x[8] = -{ +static uint32_t opcode_timings_8x[8] = { + // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM + // clang-format on }; -static uint32_t opcode_timings_8x_mod3[8] = -{ +static uint32_t opcode_timings_8x_mod3[8] = { + // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG + // clang-format on }; -static uint32_t opcode_timings_81[8] = -{ +static uint32_t opcode_timings_81[8] = { + // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM + // clang-format on }; -static uint32_t opcode_timings_81_mod3[8] = -{ +static uint32_t opcode_timings_81_mod3[8] = { + // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG + // clang-format on }; -static int decode_delay; +static int decode_delay; static uint8_t last_prefix; -static inline int COUNT(uint32_t c, int op_32) +static inline int +COUNT(uint32_t c, int op_32) { - if (c & CYCLES_HAS_MULTI) - { - if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; - } - if (!(c & PAIR_MASK)) - return c & 0xffff; + if (c & CYCLES_HAS_MULTI) { + if (op_32 & 0x100) + return ((uintptr_t) c >> 8) & 0xff; + return (uintptr_t) c & 0xff; + } + if (!(c & PAIR_MASK)) + return c & 0xffff; - return c & CYCLES_MASK; + return c & CYCLES_MASK; } -void codegen_timing_686_block_start(void) +void +codegen_timing_686_block_start(void) { - prev_full = decode_delay = 0; - regmask_modified = last_regmask_modified = 0; + prev_full = decode_delay = 0; + regmask_modified = last_regmask_modified = 0; } -void codegen_timing_686_start(void) +void +codegen_timing_686_start(void) { - decode_delay = 0; - last_prefix = 0; + decode_delay = 0; + last_prefix = 0; } -void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat) { - if ((prefix & 0xf8) == 0xd8) - { - last_prefix = prefix; - return; - } - if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) - { - /*0fh prefix is 'free' when used on conditional jumps*/ - last_prefix = prefix; - return; - } - - /*6x86 can decode 1 prefix per instruction per clock with no penalty. If - either instruction has more than one prefix then decode is delayed by - one cycle for each additional prefix*/ - decode_delay++; + if ((prefix & 0xf8) == 0xd8) { last_prefix = prefix; + return; + } + if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) { + /*0fh prefix is 'free' when used on conditional jumps*/ + last_prefix = prefix; + return; + } + + /*6x86 can decode 1 prefix per instruction per clock with no penalty. If + either instruction has more than one prefix then decode is delayed by + one cycle for each additional prefix*/ + decode_delay++; + last_prefix = prefix; } -static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +static int +check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) { - uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); - if (addr_regmask & IMPL_ESP) - addr_regmask |= (1 << REG_ESP); + if (addr_regmask & IMPL_ESP) + addr_regmask |= (1 << REG_ESP); - if (regmask_modified & addr_regmask) - { - regmask_modified = 0; - return 2; - } + if (regmask_modified & addr_regmask) { + regmask_modified = 0; + return 2; + } - if (last_regmask_modified & addr_regmask) - return 1; + if (last_regmask_modified & addr_regmask) + return 1; - return 0; + return 0; } -void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +void +codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) { - uint32_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); + uint32_t *timings; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xd0: + case 0xd1: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl; + deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } - case 0xc0: case 0xc1: - timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; + /*One prefix per instruction is free*/ + decode_delay--; + if (decode_delay < 0) + decode_delay = 0; - case 0xd0: case 0xd1: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; + if (prev_full) { + uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32); + int agi_stall = 0; - case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl; - deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; - opcode = (fetchdat >> 3) & 7; - break; + if (regmask & IMPL_ESP) + regmask |= SRCDEP_ESP | DSTDEP_ESP; - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; + agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32); - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } + /*Second instruction in the pair*/ + if ((timings[opcode] & PAIR_MASK) == PAIR_NP) { + /*Instruction can not pair with previous*/ + /*Run previous now*/ + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; + prev_full = 0; + last_regmask_modified = regmask_modified; + regmask_modified = prev_regmask; + } else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) + && (prev_timings[opcode] & PAIR_MASK) == PAIR_X) { + /*Instruction can not pair with previous*/ + /*Run previous now*/ + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; + prev_full = 0; + last_regmask_modified = regmask_modified; + regmask_modified = prev_regmask; + } else if (prev_regmask & regmask) { + /*Instruction can not pair with previous*/ + /*Run previous now*/ + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; + prev_full = 0; + last_regmask_modified = regmask_modified; + regmask_modified = prev_regmask; + } else { + int t1 = COUNT(prev_timings[prev_opcode], prev_op_32); + int t2 = COUNT(timings[opcode], op_32); + int t_pair = (t1 > t2) ? t1 : t2; + + if (!t_pair) + fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode); + + agi_stall = check_agi(deps, opcode, fetchdat, op_32); + + codegen_block_cycles += t_pair + agi_stall; + decode_delay = (-t_pair) + 1 + agi_stall; + + last_regmask_modified = regmask_modified; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask; + prev_full = 0; + return; } + } - /*One prefix per instruction is free*/ - decode_delay--; - if (decode_delay < 0) - decode_delay = 0; + if (!prev_full) { + /*First instruction in the pair*/ + if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) { + /*Instruction not pairable*/ + int agi_stall = 0; - if (prev_full) - { - uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32); - int agi_stall = 0; + agi_stall = check_agi(deps, opcode, fetchdat, op_32); - if (regmask & IMPL_ESP) - regmask |= SRCDEP_ESP | DSTDEP_ESP; - - agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32); - - /*Second instruction in the pair*/ - if ((timings[opcode] & PAIR_MASK) == PAIR_NP) - { - /*Instruction can not pair with previous*/ - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; - prev_full = 0; - last_regmask_modified = regmask_modified; - regmask_modified = prev_regmask; - } - else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) - && (prev_timings[opcode] & PAIR_MASK) == PAIR_X) - { - /*Instruction can not pair with previous*/ - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; - prev_full = 0; - last_regmask_modified = regmask_modified; - regmask_modified = prev_regmask; - } - else if (prev_regmask & regmask) - { - /*Instruction can not pair with previous*/ - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; - prev_full = 0; - last_regmask_modified = regmask_modified; - regmask_modified = prev_regmask; - } - else - { - int t1 = COUNT(prev_timings[prev_opcode], prev_op_32); - int t2 = COUNT(timings[opcode], op_32); - int t_pair = (t1 > t2) ? t1 : t2; - - if (!t_pair) - fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode); - - agi_stall = check_agi(deps, opcode, fetchdat, op_32); - - codegen_block_cycles += t_pair + agi_stall; - decode_delay = (-t_pair) + 1 + agi_stall; - - last_regmask_modified = regmask_modified; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask; - prev_full = 0; - return; - } - } - - if (!prev_full) - { - /*First instruction in the pair*/ - if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) - { - /*Instruction not pairable*/ - int agi_stall = 0; - - agi_stall = check_agi(deps, opcode, fetchdat, op_32); - - codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall; - decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall; - last_regmask_modified = regmask_modified; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); - } - else - { - /*Instruction might pair with next*/ - prev_full = 1; - prev_opcode = opcode; - prev_timings = timings; - prev_op_32 = op_32; - prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); - if (prev_regmask & IMPL_ESP) - prev_regmask |= SRCDEP_ESP | DSTDEP_ESP; - prev_deps = deps; - prev_fetchdat = fetchdat; - return; - } + codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall; + last_regmask_modified = regmask_modified; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + } else { + /*Instruction might pair with next*/ + prev_full = 1; + prev_opcode = opcode; + prev_timings = timings; + prev_op_32 = op_32; + prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); + if (prev_regmask & IMPL_ESP) + prev_regmask |= SRCDEP_ESP | DSTDEP_ESP; + prev_deps = deps; + prev_fetchdat = fetchdat; + return; } + } } -void codegen_timing_686_block_end(void) +void +codegen_timing_686_block_end(void) { - if (prev_full) - { - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; - prev_full = 0; - } + if (prev_full) { + /*Run previous now*/ + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; + prev_full = 0; + } } -codegen_timing_t codegen_timing_686 = -{ - codegen_timing_686_start, - codegen_timing_686_prefix, - codegen_timing_686_opcode, - codegen_timing_686_block_start, - codegen_timing_686_block_end, - NULL +codegen_timing_t codegen_timing_686 = { + codegen_timing_686_start, + codegen_timing_686_prefix, + codegen_timing_686_opcode, + codegen_timing_686_block_start, + codegen_timing_686_block_end, + NULL }; diff --git a/src/cpu/codegen_timing_common.c b/src/cpu/codegen_timing_common.c index a1f1b6ce7..0c538fc4e 100644 --- a/src/cpu/codegen_timing_common.c +++ b/src/cpu/codegen_timing_common.c @@ -8,8 +8,8 @@ #include "codegen_timing_common.h" -uint64_t opcode_deps[256] = -{ +uint64_t opcode_deps[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, /* ADD ADD PUSH ES POP ES*/ @@ -140,10 +140,11 @@ uint64_t opcode_deps[256] = 0, 0, 0, 0, /* CLD STD INCDEC*/ 0, 0, MODRM, 0 + // clang-format on }; -uint64_t opcode_deps_mod3[256] = -{ +uint64_t opcode_deps_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, /* ADD ADD PUSH ES POP ES*/ @@ -274,10 +275,11 @@ uint64_t opcode_deps_mod3[256] = 0, 0, 0, 0, /* CLD STD INCDEC*/ 0, 0, SRCDEP_RM | DSTDEP_RM | MODRM, 0 + // clang-format on }; -uint64_t opcode_deps_0f[256] = -{ +uint64_t opcode_deps_0f[256] = { + // clang-format off /*00*/ MODRM, MODRM, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, 0, @@ -357,9 +359,10 @@ uint64_t opcode_deps_0f[256] = 0, MODRM | MMX_MULTIPLY, 0, 0, MODRM, MODRM, MODRM, 0, MODRM, MODRM, MODRM, 0, + // clang-format on }; -uint64_t opcode_deps_0f_mod3[256] = -{ +uint64_t opcode_deps_0f_mod3[256] = { + // clang-format off /*00*/ MODRM, MODRM, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, 0, @@ -439,10 +442,11 @@ uint64_t opcode_deps_0f_mod3[256] = 0, MODRM | MMX_MULTIPLY, 0, 0, MODRM, MODRM, MODRM, 0, MODRM, MODRM, MODRM, 0, + // clang-format on }; -uint64_t opcode_deps_0f0f[256] = -{ +uint64_t opcode_deps_0f0f[256] = { + // clang-format off /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -522,9 +526,10 @@ uint64_t opcode_deps_0f0f[256] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // clang-format on }; -uint64_t opcode_deps_0f0f_mod3[256] = -{ +uint64_t opcode_deps_0f0f_mod3[256] = { + // clang-format off /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -604,97 +609,111 @@ uint64_t opcode_deps_0f0f_mod3[256] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // clang-format on }; -uint64_t opcode_deps_shift[8] = -{ +uint64_t opcode_deps_shift[8] = { + // clang-format off MODRM, MODRM, MODRM, MODRM, MODRM, MODRM, MODRM, MODRM, + // clang-format on }; -uint64_t opcode_deps_shift_mod3[8] = -{ +uint64_t opcode_deps_shift_mod3[8] = { + // clang-format off SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, + // clang-format on }; -uint64_t opcode_deps_shift_cl[8] = -{ +uint64_t opcode_deps_shift_cl[8] = { + // clang-format off MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, + // clang-format on }; -uint64_t opcode_deps_shift_cl_mod3[8] = -{ +uint64_t opcode_deps_shift_cl_mod3[8] = { + // clang-format off SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, + // clang-format on }; -uint64_t opcode_deps_f6[8] = -{ +uint64_t opcode_deps_f6[8] = { + // clang-format off /* TST NOT NEG*/ MODRM, 0, MODRM, MODRM, /* MUL IMUL DIV IDIV*/ SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM + // clang-format on }; -uint64_t opcode_deps_f6_mod3[8] = -{ +uint64_t opcode_deps_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, /* MUL IMUL DIV IDIV*/ SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM + // clang-format on }; -uint64_t opcode_deps_f7[8] = -{ +uint64_t opcode_deps_f7[8] = { + // clang-format off /* TST NOT NEG*/ MODRM, 0, MODRM, MODRM, /* MUL IMUL DIV IDIV*/ SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM + // clang-format on }; -uint64_t opcode_deps_f7_mod3[8] = -{ +uint64_t opcode_deps_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, /* MUL IMUL DIV IDIV*/ SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM + // clang-format on }; -uint64_t opcode_deps_ff[8] = -{ +uint64_t opcode_deps_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ MODRM, MODRM, MODRM | IMPL_ESP, MODRM, /* JMP JMP far PUSH*/ MODRM, MODRM, MODRM | IMPL_ESP, 0 + // clang-format on }; -uint64_t opcode_deps_ff_mod3[8] = -{ +uint64_t opcode_deps_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM | IMPL_ESP, MODRM, /* JMP JMP far PUSH*/ SRCDEP_RM | MODRM, MODRM, SRCDEP_RM | MODRM | IMPL_ESP, 0 + // clang-format on }; -uint64_t opcode_deps_d8[8] = -{ +uint64_t opcode_deps_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_POP | FPU_READ_ST0 | MODRM, /* FSUBs FSUBRs FDIVs FDIVRs*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM + // clang-format on }; -uint64_t opcode_deps_d8_mod3[8] = -{ +uint64_t opcode_deps_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG, FPU_POP | FPU_READ_ST0 | FPU_READ_STREG, /* FSUB FSUBR FDIV FDIVR*/ FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG + // clang-format on }; -uint64_t opcode_deps_d9[8] = -{ +uint64_t opcode_deps_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_POP | MODRM, /* FLDENV FLDCW FSTENV FSTCW*/ MODRM, MODRM, MODRM, MODRM + // clang-format on }; -uint64_t opcode_deps_d9_mod3[64] = -{ +uint64_t opcode_deps_d9_mod3[64] = { + // clang-format off /*FLD*/ FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, @@ -722,32 +741,35 @@ uint64_t opcode_deps_d9_mod3[64] = 0, 0, 0, 0, /* opFRNDINT opFSCALE opFSIN opFCOS*/ 0, 0, 0, 0 + // clang-format on }; -uint64_t opcode_deps_da[8] = -{ +uint64_t opcode_deps_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FISUBl FISUBRl FIDIVl FIDIVRl*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM + // clang-format on }; -uint64_t opcode_deps_da_mod3[8] = -{ +uint64_t opcode_deps_da_mod3[8] = { + // clang-format off 0, 0, 0, 0, /* FCOMPP*/ 0, FPU_POP2, 0, 0 + // clang-format on }; - -uint64_t opcode_deps_db[8] = -{ +uint64_t opcode_deps_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FLDe FSTPe*/ 0, FPU_PUSH | MODRM, 0, FPU_READ_ST0 | FPU_POP | MODRM + // clang-format on }; -uint64_t opcode_deps_db_mod3[64] = -{ +uint64_t opcode_deps_db_mod3[64] = { + // clang-format off 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -767,84 +789,97 @@ uint64_t opcode_deps_db_mod3[64] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // clang-format on }; -uint64_t opcode_deps_dc[8] = -{ +uint64_t opcode_deps_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FSUBd FSUBRd FDIVd FDIVRd*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM + // clang-format on }; -uint64_t opcode_deps_dc_mod3[8] = -{ +uint64_t opcode_deps_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, 0, 0, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG + // clang-format on }; -uint64_t opcode_deps_dd[8] = -{ +uint64_t opcode_deps_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FRSTOR FSAVE FSTSW*/ MODRM, 0, MODRM, MODRM + // clang-format on }; -uint64_t opcode_deps_dd_mod3[8] = -{ +uint64_t opcode_deps_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ 0, 0, FPU_READ_ST0 | FPU_WRITE_STREG, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, /* FUCOM FUCOMP*/ FPU_READ_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG | FPU_POP, 0, 0 + // clang-format on }; -uint64_t opcode_deps_de[8] = -{ +uint64_t opcode_deps_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FISUBw FISUBRw FIDIVw FIDIVRw*/ FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM + // clang-format on }; -uint64_t opcode_deps_de_mod3[8] = -{ +uint64_t opcode_deps_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, 0, FPU_READ_ST0 | FPU_READ_ST1 | FPU_POP2, /* FSUBP FSUBRP FDIVP FDIVRP*/ FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP + // clang-format on }; -uint64_t opcode_deps_df[8] = -{ +uint64_t opcode_deps_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, /* FILDiq FBSTP FISTPiq*/ 0, FPU_PUSH | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, FPU_READ_ST0 | FPU_POP | MODRM + // clang-format on }; -uint64_t opcode_deps_df_mod3[8] = -{ +uint64_t opcode_deps_df_mod3[8] = { + // clang-format off 0, 0, 0, 0, /* FSTSW AX*/ 0, 0, 0, 0 + // clang-format on }; -uint64_t opcode_deps_81[8] = -{ +uint64_t opcode_deps_81[8] = { + // clang-format off MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632 + // clang-format on }; -uint64_t opcode_deps_81_mod3[8] = -{ +uint64_t opcode_deps_81_mod3[8] = { + // clang-format off SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | MODRM | HAS_IMM1632 + // clang-format on }; -uint64_t opcode_deps_8x[8] = -{ +uint64_t opcode_deps_8x[8] = { + // clang-format off MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8 + // clang-format on }; -uint64_t opcode_deps_8x_mod3[8] = -{ +uint64_t opcode_deps_8x_mod3[8] = { + // clang-format off SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | MODRM | HAS_IMM8 + // clang-format on }; diff --git a/src/cpu/codegen_timing_common.h b/src/cpu/codegen_timing_common.h index 679997802..3d28a89de 100644 --- a/src/cpu/codegen_timing_common.h +++ b/src/cpu/codegen_timing_common.h @@ -1,79 +1,79 @@ #include "codegen_ops.h" /*Instruction has input dependency on register in REG field*/ -#define SRCDEP_REG (1ull << 0) +#define SRCDEP_REG (1ULL << 0) /*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1ull << 1) +#define SRCDEP_RM (1ULL << 1) /*Instruction modifies register in REG field*/ -#define DSTDEP_REG (1ull << 2) +#define DSTDEP_REG (1ULL << 2) /*Instruction modifies register in R/M field*/ -#define DSTDEP_RM (1ull << 3) +#define DSTDEP_RM (1ULL << 3) #define SRCDEP_SHIFT 4 #define DSTDEP_SHIFT 12 /*Instruction has input dependency on given register*/ -#define SRCDEP_EAX (1ull << 4) -#define SRCDEP_ECX (1ull << 5) -#define SRCDEP_EDX (1ull << 6) -#define SRCDEP_EBX (1ull << 7) -#define SRCDEP_ESP (1ull << 8) -#define SRCDEP_EBP (1ull << 9) -#define SRCDEP_ESI (1ull << 10) -#define SRCDEP_EDI (1ull << 11) +#define SRCDEP_EAX (1ULL << 4) +#define SRCDEP_ECX (1ULL << 5) +#define SRCDEP_EDX (1ULL << 6) +#define SRCDEP_EBX (1ULL << 7) +#define SRCDEP_ESP (1ULL << 8) +#define SRCDEP_EBP (1ULL << 9) +#define SRCDEP_ESI (1ULL << 10) +#define SRCDEP_EDI (1ULL << 11) /*Instruction modifies given register*/ -#define DSTDEP_EAX (1ull << 12) -#define DSTDEP_ECX (1ull << 13) -#define DSTDEP_EDX (1ull << 14) -#define DSTDEP_EBX (1ull << 15) -#define DSTDEP_ESP (1ull << 16) -#define DSTDEP_EBP (1ull << 17) -#define DSTDEP_ESI (1ull << 18) -#define DSTDEP_EDI (1ull << 19) +#define DSTDEP_EAX (1ULL << 12) +#define DSTDEP_ECX (1ULL << 13) +#define DSTDEP_EDX (1ULL << 14) +#define DSTDEP_EBX (1ULL << 15) +#define DSTDEP_ESP (1ULL << 16) +#define DSTDEP_EBP (1ULL << 17) +#define DSTDEP_ESI (1ULL << 18) +#define DSTDEP_EDI (1ULL << 19) /*Instruction has ModR/M byte*/ -#define MODRM (1ull << 20) +#define MODRM (1ULL << 20) /*Instruction implicitly uses ESP*/ -#define IMPL_ESP (1ull << 21) +#define IMPL_ESP (1ULL << 21) /*Instruction is MMX shift or pack/unpack instruction*/ -#define MMX_SHIFTPACK (1ull << 22) +#define MMX_SHIFTPACK (1ULL << 22) /*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1ull << 23) +#define MMX_MULTIPLY (1ULL << 23) /*Instruction pops the FPU stack*/ -#define FPU_POP (1ull << 24) +#define FPU_POP (1ULL << 24) /*Instruction pops the FPU stack twice*/ -#define FPU_POP2 (1ull << 25) +#define FPU_POP2 (1ULL << 25) /*Instruction pushes onto the FPU stack*/ -#define FPU_PUSH (1ull << 26) +#define FPU_PUSH (1ULL << 26) /*Instruction writes to ST(0)*/ -#define FPU_WRITE_ST0 (1ull << 27) +#define FPU_WRITE_ST0 (1ULL << 27) /*Instruction reads from ST(0)*/ -#define FPU_READ_ST0 (1ull << 28) +#define FPU_READ_ST0 (1ULL << 28) /*Instruction reads from and writes to ST(0)*/ -#define FPU_RW_ST0 (3ull << 27) +#define FPU_RW_ST0 (3ULL << 27) /*Instruction reads from ST(1)*/ -#define FPU_READ_ST1 (1ull << 29) +#define FPU_READ_ST1 (1ULL << 29) /*Instruction writes to ST(1)*/ -#define FPU_WRITE_ST1 (1ull << 30) +#define FPU_WRITE_ST1 (1ULL << 30) /*Instruction reads from and writes to ST(1)*/ -#define FPU_RW_ST1 (3ull << 29) +#define FPU_RW_ST1 (3ULL << 29) /*Instruction reads from ST(reg)*/ -#define FPU_READ_STREG (1ull << 31) +#define FPU_READ_STREG (1ULL << 31) /*Instruction writes to ST(reg)*/ -#define FPU_WRITE_STREG (1ull << 32) +#define FPU_WRITE_STREG (1ULL << 32) /*Instruction reads from and writes to ST(reg)*/ -#define FPU_RW_STREG (3ull << 31) +#define FPU_RW_STREG (3ULL << 31) -#define FPU_FXCH (1ull << 33) +#define FPU_FXCH (1ULL << 33) -#define HAS_IMM8 (1ull << 34) -#define HAS_IMM1632 (1ull << 35) +#define HAS_IMM8 (1ULL << 34) +#define HAS_IMM1632 (1ULL << 35) #define REGMASK_IMPL_ESP (1 << 8) #define REGMASK_SHIFTPACK (1 << 9) diff --git a/src/cpu/codegen_timing_k6.c b/src/cpu/codegen_timing_k6.c index 6a59fc157..88215bb17 100644 --- a/src/cpu/codegen_timing_k6.c +++ b/src/cpu/codegen_timing_k6.c @@ -8,6 +8,7 @@ #include <86box/mem.h> #include "cpu.h" #include <86box/machine.h> + #include "x86.h" #include "x86_ops.h" #include "x87.h" @@ -16,865 +17,748 @@ #include "codegen_ops.h" #include "codegen_timing_common.h" -typedef enum uop_type_t -{ - UOP_ALU = 0, /*Executes in Integer X or Y units*/ - UOP_ALUX, /*Executes in Integer X unit*/ - UOP_LOAD, /*Executes in Load unit*/ - UOP_STORE, /*Executes in Store unit*/ - UOP_FLOAD, /*Executes in Load unit*/ - UOP_FSTORE, /*Executes in Store unit*/ - UOP_MLOAD, /*Executes in Load unit*/ - UOP_MSTORE, /*Executes in Store unit*/ - UOP_FLOAT, /*Executes in Floating Point unit*/ - UOP_MEU, /*Executes in Multimedia unit*/ - UOP_MEU_SHIFT, /*Executes in Multimedia unit or ALU X/Y. Uses MMX shifter*/ - UOP_MEU_MUL, /*Executes in Multimedia unit or ALU X/Y. Uses MMX/3DNow multiplier*/ - UOP_MEU_3DN, /*Executes in Multimedia unit or ALU X/Y. Uses 3DNow ALU*/ - UOP_BRANCH, /*Executes in Branch unit*/ - UOP_LIMM /*Does not require an execution unit*/ +typedef enum uop_type_t { + UOP_ALU = 0, /*Executes in Integer X or Y units*/ + UOP_ALUX, /*Executes in Integer X unit*/ + UOP_LOAD, /*Executes in Load unit*/ + UOP_STORE, /*Executes in Store unit*/ + UOP_FLOAD, /*Executes in Load unit*/ + UOP_FSTORE, /*Executes in Store unit*/ + UOP_MLOAD, /*Executes in Load unit*/ + UOP_MSTORE, /*Executes in Store unit*/ + UOP_FLOAT, /*Executes in Floating Point unit*/ + UOP_MEU, /*Executes in Multimedia unit*/ + UOP_MEU_SHIFT, /*Executes in Multimedia unit or ALU X/Y. Uses MMX shifter*/ + UOP_MEU_MUL, /*Executes in Multimedia unit or ALU X/Y. Uses MMX/3DNow multiplier*/ + UOP_MEU_3DN, /*Executes in Multimedia unit or ALU X/Y. Uses 3DNow ALU*/ + UOP_BRANCH, /*Executes in Branch unit*/ + UOP_LIMM /*Does not require an execution unit*/ } uop_type_t; -typedef enum decode_type_t -{ - DECODE_SHORT, - DECODE_LONG, - DECODE_VECTOR +typedef enum decode_type_t { + DECODE_SHORT, + DECODE_LONG, + DECODE_VECTOR } decode_type_t; #define MAX_UOPS 10 -typedef struct risc86_uop_t -{ - uop_type_t type; - int throughput; - int latency; +typedef struct risc86_uop_t { + uop_type_t type; + int throughput; + int latency; } risc86_uop_t; -typedef struct risc86_instruction_t -{ - int nr_uops; - decode_type_t decode_type; - risc86_uop_t uop[MAX_UOPS]; +typedef struct risc86_instruction_t { + int nr_uops; + decode_type_t decode_type; + risc86_uop_t uop[MAX_UOPS]; } risc86_instruction_t; -static const risc86_instruction_t alu_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t alu_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t alux_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t alux_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t load_alu_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t load_alu_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t load_alux_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t load_alux_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t alu_store_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t alu_store_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t alux_store_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t alux_store_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t branch_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +static const risc86_instruction_t branch_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t limm_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LIMM, .throughput = 1, .latency = 1} +static const risc86_instruction_t limm_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LIMM, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t load_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} +static const risc86_instruction_t load_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} }; -static const risc86_instruction_t store_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t store_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} }; - -static const risc86_instruction_t bswap_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t bswap_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t leave_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t leave_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t lods_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t lods_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t loop_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +static const risc86_instruction_t loop_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t mov_reg_seg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, +static const risc86_instruction_t mov_reg_seg_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, }; -static const risc86_instruction_t movs_op = -{ - .nr_uops = 4, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t movs_op = { + .nr_uops = 4, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t pop_reg_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t pop_reg_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t pop_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t pop_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t push_imm_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, +static const risc86_instruction_t push_imm_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, }; -static const risc86_instruction_t push_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t push_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t push_seg_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t push_seg_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t stos_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t stos_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t test_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t test_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t test_reg_b_op = -{ - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t test_reg_b_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t test_mem_imm_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t test_mem_imm_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t test_mem_imm_b_op = -{ - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t test_mem_imm_b_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t xchg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t xchg_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t m3dn_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} +static const risc86_instruction_t m3dn_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t mmx_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU, .throughput = 1, .latency = 1} +static const risc86_instruction_t mmx_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t mmx_mul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +static const risc86_instruction_t mmx_mul_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} }; -static const risc86_instruction_t mmx_shift_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} +static const risc86_instruction_t mmx_shift_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t load_3dn_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} +static const risc86_instruction_t load_3dn_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_3DN, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t load_mmx_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU, .throughput = 1, .latency = 1} +static const risc86_instruction_t load_mmx_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t load_mmx_mul_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +static const risc86_instruction_t load_mmx_mul_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_MUL, .throughput = 1, .latency = 2} }; -static const risc86_instruction_t load_mmx_shift_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} +static const risc86_instruction_t load_mmx_shift_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t mload_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MLOAD, .throughput = 1, .latency = 2} +static const risc86_instruction_t mload_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MLOAD, .throughput = 1, .latency = 2} }; -static const risc86_instruction_t mstore_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MSTORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t mstore_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MSTORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t pmul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +static const risc86_instruction_t pmul_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} }; -static const risc86_instruction_t pmul_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +static const risc86_instruction_t pmul_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_MUL, .throughput = 1, .latency = 2} }; -static const risc86_instruction_t float_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +static const risc86_instruction_t float_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} }; -static const risc86_instruction_t load_float_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +static const risc86_instruction_t load_float_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_FLOAT, .throughput = 2, .latency = 2} }; -static const risc86_instruction_t fstore_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t fstore_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t fdiv_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} +static const risc86_instruction_t fdiv_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} }; -static const risc86_instruction_t fdiv_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} +static const risc86_instruction_t fdiv_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_FLOAT, .throughput = 40, .latency = 40} }; -static const risc86_instruction_t fsin_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62} +static const risc86_instruction_t fsin_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62} }; -static const risc86_instruction_t fsqrt_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 41, .latency = 41} +static const risc86_instruction_t fsqrt_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 41, .latency = 41} }; -static const risc86_instruction_t vector_fldcw_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 8, .latency = 8} +static const risc86_instruction_t vector_fldcw_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 8, .latency = 8} }; -static const risc86_instruction_t vector_float_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +static const risc86_instruction_t vector_float_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} }; -static const risc86_instruction_t vector_float_l_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 50, .latency = 50} +static const risc86_instruction_t vector_float_l_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 50, .latency = 50} }; -static const risc86_instruction_t vector_flde_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +static const risc86_instruction_t vector_flde_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[2] = { .type = UOP_FLOAT, .throughput = 2, .latency = 2} }; -static const risc86_instruction_t vector_fste_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}, - .uop[1] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_fste_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}, + .uop[1] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_alu1_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_alu1_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_alu2_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_alu2_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_alu3_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_alu3_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_alu6_op = -{ - .nr_uops = 6, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_alu6_op = { + .nr_uops = 6, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_alux1_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_alux1_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_alux3_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_alux3_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_alux6_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_alux6_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_alu_store_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_alu_store_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_alux_store_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_alux_store_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_arpl_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +static const risc86_instruction_t vector_arpl_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3} }; -static const risc86_instruction_t vector_bound_op = -{ - .nr_uops = 4, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_bound_op = { + .nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_bsx_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 10, .latency = 10} +static const risc86_instruction_t vector_bsx_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 10, .latency = 10} }; -static const risc86_instruction_t vector_call_far_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_call_far_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_cli_sti_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 7, .latency = 7} +static const risc86_instruction_t vector_cli_sti_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 7, .latency = 7} }; -static const risc86_instruction_t vector_cmps_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_cmps_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_cmpsb_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_cmpsb_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_cmpxchg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, +static const risc86_instruction_t vector_cmpxchg_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, }; -static const risc86_instruction_t vector_cmpxchg_b_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, +static const risc86_instruction_t vector_cmpxchg_b_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, }; -static const risc86_instruction_t vector_cpuid_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 22, .latency = 22} +static const risc86_instruction_t vector_cpuid_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 22, .latency = 22} }; -static const risc86_instruction_t vector_div16_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} +static const risc86_instruction_t vector_div16_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} }; -static const risc86_instruction_t vector_div16_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} +static const risc86_instruction_t vector_div16_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALUX, .throughput = 10, .latency = 10} }; -static const risc86_instruction_t vector_div32_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} +static const risc86_instruction_t vector_div32_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} }; -static const risc86_instruction_t vector_div32_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} +static const risc86_instruction_t vector_div32_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALUX, .throughput = 18, .latency = 18} }; -static const risc86_instruction_t vector_emms_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 25, .latency = 25} +static const risc86_instruction_t vector_emms_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 25, .latency = 25} }; -static const risc86_instruction_t vector_enter_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 10, .latency = 10} +static const risc86_instruction_t vector_enter_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALU, .throughput = 10, .latency = 10} }; -static const risc86_instruction_t vector_femms_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 6, .latency = 6} +static const risc86_instruction_t vector_femms_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 6, .latency = 6} }; -static const risc86_instruction_t vector_in_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11} +static const risc86_instruction_t vector_in_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11} }; -static const risc86_instruction_t vector_ins_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_ins_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1 } }; -static const risc86_instruction_t vector_int_op = -{ - .nr_uops = 5, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_int_op = { + .nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[3] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[4] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1 } }; -static const risc86_instruction_t vector_iret_op = -{ - .nr_uops = 5, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[3] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, - .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_iret_op = { + .nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[2] = { .type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[3] = { .type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[4] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1 } }; -static const risc86_instruction_t vector_invd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1000, .latency = 1000} +static const risc86_instruction_t vector_invd_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1000, .latency = 1000} }; -static const risc86_instruction_t vector_jmp_far_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_jmp_far_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_load_alu_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_load_alu_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_load_alux_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_load_alux_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_loop_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_loop_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_lss_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +static const risc86_instruction_t vector_lss_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = { .type = UOP_ALU, .throughput = 3, .latency = 3} }; -static const risc86_instruction_t vector_mov_mem_seg_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_mov_mem_seg_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_mov_seg_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +static const risc86_instruction_t vector_mov_seg_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3} }; -static const risc86_instruction_t vector_mov_seg_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +static const risc86_instruction_t vector_mov_seg_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3} }; -static const risc86_instruction_t vector_mul_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_mul_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_mul_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_mul_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_mul64_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_mul64_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_mul64_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_mul64_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_out_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 10, .latency = 10} +static const risc86_instruction_t vector_out_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 10, .latency = 10} }; -static const risc86_instruction_t vector_outs_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 10, .latency = 10}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_outs_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1 }, + .uop[1] = { .type = UOP_STORE, .throughput = 10, .latency = 10}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1 } }; -static const risc86_instruction_t vector_pusha_op = -{ - .nr_uops = 8, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_pusha_op = { + .nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[6] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[7] = { .type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_popa_op = -{ - .nr_uops = 8, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_LOAD, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_popa_op = { + .nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[6] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[7] = { .type = UOP_LOAD, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_popf_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 17, .latency = 17} +static const risc86_instruction_t vector_popf_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALUX, .throughput = 17, .latency = 17} }; -static const risc86_instruction_t vector_push_mem_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_push_mem_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_pushf_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_pushf_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_ret_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_ret_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_retf_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_retf_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[2] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_scas_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_scas_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_scasb_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_scasb_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_setcc_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_setcc_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_setcc_reg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_setcc_reg_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_test_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_test_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_test_mem_b_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_test_mem_b_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_xchg_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +static const risc86_instruction_t vector_xchg_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} }; -static const risc86_instruction_t vector_xlat_op = -{ - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} +static const risc86_instruction_t vector_xlat_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2} }; -static const risc86_instruction_t vector_wbinvd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 10000, .latency = 10000} +static const risc86_instruction_t vector_wbinvd_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 10000, .latency = 10000} }; #define INVALID NULL -static const risc86_instruction_t *opcode_timings[256] = -{ +static const risc86_instruction_t *opcode_timings[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, /* ADD ADD PUSH ES POP ES*/ @@ -1007,10 +891,11 @@ static const risc86_instruction_t *opcode_timings[256] = &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, /* CLD STD INCDEC*/ &vector_alu1_op, &vector_alu1_op, &alux_store_op, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_mod3[256] = -{ +static const risc86_instruction_t *opcode_timings_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alux_op, &alu_op, &alux_op, &alu_op, /* ADD ADD PUSH ES POP ES*/ @@ -1143,10 +1028,11 @@ static const risc86_instruction_t *opcode_timings_mod3[256] = &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, /* CLD STD INCDEC*/ &vector_alu1_op, &vector_alu1_op, &vector_alux1_op, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f[256] = -{ +static const risc86_instruction_t *opcode_timings_0f[256] = { + // clang-format off /*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, @@ -1226,9 +1112,10 @@ static const risc86_instruction_t *opcode_timings_0f[256] = INVALID, &pmul_mem_op, INVALID, INVALID, &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f_mod3[256] = -{ +static const risc86_instruction_t *opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, @@ -1308,10 +1195,11 @@ static const risc86_instruction_t *opcode_timings_0f_mod3[256] = INVALID, &pmul_op, INVALID, INVALID, &mmx_op, &mmx_op, &mmx_op, INVALID, &mmx_op, &mmx_op, &mmx_op, INVALID, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f0f[256] = -{ +static const risc86_instruction_t *opcode_timings_0f0f[256] = { + // clang-format off /*00*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1391,10 +1279,10 @@ static const risc86_instruction_t *opcode_timings_0f0f[256] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, - + // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = -{ +static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = { + // clang-format off /*00*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1474,118 +1362,135 @@ static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, - + // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift[8] = -{ +static const risc86_instruction_t *opcode_timings_shift[8] = { + // clang-format off &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift_b[8] = -{ +static const risc86_instruction_t *opcode_timings_shift_b[8] = { + // clang-format off &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_shift_mod3[8] = { + // clang-format off &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &alu_op, &alu_op, &alu_op, &alu_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = { + // clang-format off &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &alux_op, &alux_op, &alux_op, &alux_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_80[8] = -{ +static const risc86_instruction_t *opcode_timings_80[8] = { + // clang-format off &alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_80_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_80_mod3[8] = { + // clang-format off &alux_op, &alux_op, &alux_store_op, &alux_store_op, &alux_op, &alux_op, &alux_op, &alux_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_8x[8] = -{ +static const risc86_instruction_t *opcode_timings_8x[8] = { + // clang-format off &alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_8x_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_8x_mod3[8] = { + // clang-format off &alu_op, &alu_op, &alu_store_op, &alu_store_op, &alu_op, &alu_op, &alu_op, &alu_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_f6[8] = -{ +static const risc86_instruction_t *opcode_timings_f6[8] = { + // clang-format off /* TST NOT NEG*/ &test_mem_imm_b_op, INVALID, &vector_alux_store_op, &vector_alux_store_op, /* MUL IMUL DIV IDIV*/ &vector_mul_mem_op, &vector_mul_mem_op, &vector_div16_mem_op, &vector_div16_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_f6_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ &test_reg_b_op, INVALID, &alux_op, &alux_op, /* MUL IMUL DIV IDIV*/ &vector_mul_op, &vector_mul_op, &vector_div16_op, &vector_div16_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_f7[8] = -{ +static const risc86_instruction_t *opcode_timings_f7[8] = { + // clang-format off /* TST NOT NEG*/ &test_mem_imm_op, INVALID, &vector_alu_store_op, &vector_alu_store_op, /* MUL IMUL DIV IDIV*/ &vector_mul64_mem_op, &vector_mul64_mem_op, &vector_div32_mem_op, &vector_div32_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_f7_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ &test_reg_op, INVALID, &alu_op, &alu_op, /* MUL IMUL DIV IDIV*/ &vector_mul64_op, &vector_mul64_op, &vector_div32_op, &vector_div32_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_ff[8] = -{ +static const risc86_instruction_t *opcode_timings_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ &alu_store_op, &alu_store_op, &store_op, &vector_call_far_op, /* JMP JMP far PUSH*/ &branch_op, &vector_jmp_far_op, &push_mem_op, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_ff_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ &vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op, /* JMP JMP far PUSH*/ &branch_op, &vector_jmp_far_op, &vector_push_mem_op, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_d8[8] = -{ +static const risc86_instruction_t *opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, /* FSUBs FSUBRs FDIVs FDIVRs*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_d8_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ &float_op, &float_op, &float_op, &float_op, /* FSUB FSUBR FDIV FDIVR*/ &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_d9[8] = -{ +static const risc86_instruction_t *opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDENV FLDCW FSTENV FSTCW*/ &vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_d9_mod3[64] = -{ +static const risc86_instruction_t *opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, @@ -1614,31 +1519,35 @@ static const risc86_instruction_t *opcode_timings_d9_mod3[64] = &fdiv_op, INVALID, &fsqrt_op, &fsin_op, /* opFRNDINT opFSCALE opFSIN opFCOS*/ &float_op, &fdiv_op, &fsin_op, &fsin_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_da[8] = -{ +static const risc86_instruction_t *opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, /* FISUBl FISUBRl FIDIVl FIDIVRl*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_da_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_da_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ INVALID, &float_op, INVALID, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_db[8] = -{ +static const risc86_instruction_t *opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDe FSTPe*/ INVALID, &vector_flde_op, INVALID, &vector_fste_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_db_mod3[64] = -{ +static const risc86_instruction_t *opcode_timings_db_mod3[64] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1664,108 +1573,113 @@ static const risc86_instruction_t *opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_dc[8] = -{ +static const risc86_instruction_t *opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, /* FSUBd FSUBRd FDIVd FDIVRd*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_dc_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ &float_op, &float_op, INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ &float_op, &float_op, &fdiv_op, &fdiv_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_dd[8] = -{ +static const risc86_instruction_t *opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FRSTOR FSAVE FSTSW*/ &vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op + // clang-format on }; -static const risc86_instruction_t *opcode_timings_dd_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ &float_op, INVALID, &float_op, &float_op, /* FUCOM FUCOMP*/ &float_op, &float_op, INVALID, INVALID + // clang-format on }; -static const risc86_instruction_t *opcode_timings_de[8] = -{ +static const risc86_instruction_t *opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, /* FISUBw FISUBRw FIDIVw FIDIVRw*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_de_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ &float_op, &float_op, INVALID, &float_op, /* FSUBP FSUBRP FDIVP FDIVRP*/ &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_df[8] = -{ +static const risc86_instruction_t *opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FILDiq FBSTP FISTPiq*/ INVALID, &load_float_op, &vector_float_l_op, &fstore_op, + // clang-format on }; -static const risc86_instruction_t *opcode_timings_df_mod3[8] = -{ +static const risc86_instruction_t *opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ &float_op, INVALID, INVALID, INVALID + // clang-format on }; - static uint8_t last_prefix; -static int prefixes; +static int prefixes; static int decode_timestamp; static int last_complete_timestamp; -typedef struct k6_unit_t -{ - uint32_t uop_mask; - int first_available_cycle; +typedef struct k6_unit_t { + uint32_t uop_mask; + int first_available_cycle; } k6_unit_t; -static int nr_units; +static int nr_units; static k6_unit_t *units; /*K6 has dedicated MMX unit*/ -static k6_unit_t k6_units[] = -{ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX)}, /*Integer X*/ - {.uop_mask = (1 << UOP_ALU)}, /*Integer Y*/ - {.uop_mask = (1 << UOP_MEU) | (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL)}, /*Multimedia*/ - {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ - {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ - {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ +static k6_unit_t k6_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) }, /*Integer X*/ + { .uop_mask = (1 << UOP_ALU) }, /*Integer Y*/ + { .uop_mask = (1 << UOP_MEU) | (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) }, /*Multimedia*/ + { .uop_mask = (1 << UOP_FLOAT) }, /*Floating point*/ + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Load*/ + { .uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE) }, /*Store*/ + { .uop_mask = (1 << UOP_BRANCH) } /*Branch*/ }; #define NR_K6_UNITS (sizeof(k6_units) / sizeof(k6_unit_t)) /*K6-2 and later integrate MMX into ALU X & Y, sharing multiplier, shifter and 3DNow ALU between two execution units*/ -static k6_unit_t k6_2_units[] = -{ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_MEU) | /*Integer X*/ - (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_MEU) | /*Integer Y*/ - (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, - {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ - {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ - {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ +static k6_unit_t k6_2_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_MEU) | /*Integer X*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN) }, + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_MEU) | /*Integer Y*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN) }, + { .uop_mask = (1 << UOP_FLOAT) }, /*Floating point*/ + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Load*/ + { .uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE) }, /*Store*/ + { .uop_mask = (1 << UOP_BRANCH) } /*Branch*/ }; #define NR_K6_2_UNITS (sizeof(k6_2_units) / sizeof(k6_unit_t)) @@ -1775,57 +1689,52 @@ static int mul_first_available_cycle; static int shift_first_available_cycle; static int m3dnow_first_available_cycle; -static int uop_run(const risc86_uop_t *uop, int decode_time) +static int +uop_run(const risc86_uop_t *uop, int decode_time) { - int c; - k6_unit_t *best_unit = NULL; - int best_start_cycle = 99999; + k6_unit_t *best_unit = NULL; + int best_start_cycle = 99999; - /*UOP_LIMM does not require execution*/ - if (uop->type == UOP_LIMM) - return decode_time; + /*UOP_LIMM does not require execution*/ + if (uop->type == UOP_LIMM) + return decode_time; - /*Handle shared units on K6-2 and later*/ - if (units == k6_2_units) - { - if (uop->type == UOP_MEU_MUL && decode_time < mul_first_available_cycle) - decode_time = mul_first_available_cycle; - else if (uop->type == UOP_MEU_SHIFT && decode_time < mul_first_available_cycle) - decode_time = shift_first_available_cycle; - else if (uop->type == UOP_MEU_3DN && decode_time < mul_first_available_cycle) - decode_time = m3dnow_first_available_cycle; + /*Handle shared units on K6-2 and later*/ + if (units == k6_2_units) { + if (uop->type == UOP_MEU_MUL && decode_time < mul_first_available_cycle) + decode_time = mul_first_available_cycle; + else if (uop->type == UOP_MEU_SHIFT && decode_time < mul_first_available_cycle) + decode_time = shift_first_available_cycle; + else if (uop->type == UOP_MEU_3DN && decode_time < mul_first_available_cycle) + decode_time = m3dnow_first_available_cycle; + } + + /*Find execution unit for this uOP*/ + for (int c = 0; c < nr_units; c++) { + if (units[c].uop_mask & (1 << uop->type)) { + if (units[c].first_available_cycle < best_start_cycle) { + best_unit = &units[c]; + best_start_cycle = units[c].first_available_cycle; + } } + } + if (!best_unit) + fatal("uop_run: can not find execution unit\n"); - /*Find execution unit for this uOP*/ - for (c = 0; c < nr_units; c++) - { - if (units[c].uop_mask & (1 << uop->type)) - { - if (units[c].first_available_cycle < best_start_cycle) - { - best_unit = &units[c]; - best_start_cycle = units[c].first_available_cycle; - } - } - } - if (!best_unit) - fatal("uop_run: can not find execution unit\n"); + if (best_start_cycle < decode_time) + best_start_cycle = decode_time; + best_unit->first_available_cycle = best_start_cycle + uop->throughput; - if (best_start_cycle < decode_time) - best_start_cycle = decode_time; - best_unit->first_available_cycle = best_start_cycle + uop->throughput; + if (units == k6_2_units) { + if (uop->type == UOP_MEU_MUL) + mul_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_SHIFT) + shift_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_3DN) + m3dnow_first_available_cycle = best_start_cycle + uop->throughput; + } - if (units == k6_2_units) - { - if (uop->type == UOP_MEU_MUL) - mul_first_available_cycle = best_start_cycle + uop->throughput; - else if (uop->type == UOP_MEU_SHIFT) - shift_first_available_cycle = best_start_cycle + uop->throughput; - else if (uop->type == UOP_MEU_3DN) - m3dnow_first_available_cycle = best_start_cycle + uop->throughput; - } - - return best_start_cycle + uop->throughput; + return best_start_cycle + uop->throughput; } /*The K6 decoder can decode, per clock : @@ -1833,14 +1742,13 @@ static int uop_run(const risc86_uop_t *uop, int decode_time) - 1 'long' instruction, up to 4 uOPs - 1 'vector' instruction, up to 4 uOPs per cycle, plus (I think) 1 cycle startup delay) */ -static struct -{ - int nr_uops; - const risc86_uop_t *uops[4]; - /*Earliest time a uop can start. If the timestamp is -1, then the uop is - part of a dependency chain and the start time is the completion time of - the previous uop*/ - int earliest_start[4]; +static struct { + int nr_uops; + const risc86_uop_t *uops[4]; + /*Earliest time a uop can start. If the timestamp is -1, then the uop is + part of a dependency chain and the start time is the completion time of + the previous uop*/ + int earliest_start[4]; } decode_buffer; #define NR_OPQUADS 6 @@ -1858,495 +1766,465 @@ static int fpu_st_timestamp[8]; dependent uop chains*/ static int last_uop_timestamp = 0; -void decode_flush(void) +void +decode_flush(void) { - int c; - int uop_timestamp = 0; + int uop_timestamp = 0; - /*Decoded opquad can not be submitted if there are no free spaces in the - opquad buffer*/ - if (decode_timestamp < opquad_completion_timestamp[next_opquad]) - decode_timestamp = opquad_completion_timestamp[next_opquad]; + /*Decoded opquad can not be submitted if there are no free spaces in the + opquad buffer*/ + if (decode_timestamp < opquad_completion_timestamp[next_opquad]) + decode_timestamp = opquad_completion_timestamp[next_opquad]; - /*Ensure that uops can not be submitted before they have been decoded*/ - if (decode_timestamp > last_uop_timestamp) - last_uop_timestamp = decode_timestamp; + /*Ensure that uops can not be submitted before they have been decoded*/ + if (decode_timestamp > last_uop_timestamp) + last_uop_timestamp = decode_timestamp; - /*Submit uops to execution units, and determine the latest completion time*/ - for (c = 0; c < decode_buffer.nr_uops; c++) - { - int start_timestamp; + /*Submit uops to execution units, and determine the latest completion time*/ + for (int c = 0; c < decode_buffer.nr_uops; c++) { + int start_timestamp; - if (decode_buffer.earliest_start[c] == -1) - start_timestamp = last_uop_timestamp; - else - start_timestamp = decode_buffer.earliest_start[c]; - - last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); - if (last_uop_timestamp > uop_timestamp) - uop_timestamp = last_uop_timestamp; - } - - /*Calculate opquad completion time. Since opquads complete in order, it - must be after the last completion.*/ - if (uop_timestamp <= last_complete_timestamp) - last_complete_timestamp = last_complete_timestamp + 1; + if (decode_buffer.earliest_start[c] == -1) + start_timestamp = last_uop_timestamp; else - last_complete_timestamp = uop_timestamp; + start_timestamp = decode_buffer.earliest_start[c]; - /*Advance to next opquad in buffer*/ - opquad_completion_timestamp[next_opquad] = last_complete_timestamp; - next_opquad++; - if (next_opquad == NR_OPQUADS) - next_opquad = 0; + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } - decode_timestamp++; - decode_buffer.nr_uops = 0; + /*Calculate opquad completion time. Since opquads complete in order, it + must be after the last completion.*/ + if (uop_timestamp <= last_complete_timestamp) + last_complete_timestamp = last_complete_timestamp + 1; + else + last_complete_timestamp = uop_timestamp; + + /*Advance to next opquad in buffer*/ + opquad_completion_timestamp[next_opquad] = last_complete_timestamp; + next_opquad++; + if (next_opquad == NR_OPQUADS) + next_opquad = 0; + + decode_timestamp++; + decode_buffer.nr_uops = 0; } /*The instruction is only of interest here if it's longer than 7 bytes, as that's the limit on K6 short decoding*/ -static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) +static int +codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) { - int len = prefixes + 1; /*Opcode*/ - if (deps & MODRM) - { - len++; /*ModR/M*/ - if (deps & HAS_IMM8) - len++; - if (deps & HAS_IMM1632) - len += (op_32 & 0x100) ? 4 : 2; + int len = prefixes + 1; /*Opcode*/ + if (deps & MODRM) { + len++; /*ModR/M*/ + if (deps & HAS_IMM8) + len++; + if (deps & HAS_IMM1632) + len += (op_32 & 0x100) ? 4 : 2; - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /* Has SIB*/ - len++; - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0x700) == 0x500) - len += 4; - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0xc7) == 0x05) - len += 4; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 2; - else if ((fetchdat & 0xc7) == 0x06) - len += 2; - } + if (op_32 & 0x200) { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) { + /* Has SIB*/ + len++; + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0x700) == 0x500) + len += 4; + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0xc7) == 0x05) + len += 4; + } + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 2; + else if ((fetchdat & 0xc7) == 0x06) + len += 2; } + } - return len; + return len; } -static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) +static void +decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) { - uint32_t regmask_required; - uint32_t regmask_modified; - int c, d; - int earliest_start = 0; - decode_type_t decode_type = ins->decode_type; - int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); + uint32_t regmask_required; + uint32_t regmask_modified; + int c; + int d; + int earliest_start = 0; + decode_type_t decode_type = ins->decode_type; + int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); - /*Generate input register mask, and determine the earliest time this - instruction can start. This is not accurate, as this is calculated per - x86 instruction when it should be handled per uop*/ - regmask_required = get_dstdep_mask(deps, fetchdat, bit8); - regmask_required |= get_addr_regmask(deps, fetchdat, op_32); - for (c = 0; c < 8; c++) - { - if (regmask_required & (1 << c)) - { - if (reg_available_timestamp[c] > decode_timestamp) - earliest_start = reg_available_timestamp[c]; - } + /*Generate input register mask, and determine the earliest time this + instruction can start. This is not accurate, as this is calculated per + x86 instruction when it should be handled per uop*/ + regmask_required = get_dstdep_mask(deps, fetchdat, bit8); + regmask_required |= get_addr_regmask(deps, fetchdat, op_32); + for (c = 0; c < 8; c++) { + if (regmask_required & (1 << c)) { + if (reg_available_timestamp[c] > decode_timestamp) + earliest_start = reg_available_timestamp[c]; } - if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) - earliest_start = fpu_st_timestamp[0]; - if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) - earliest_start = fpu_st_timestamp[1]; - if ((deps & FPU_RW_STREG)) - { - int reg = fetchdat & 7; + } + if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) + earliest_start = fpu_st_timestamp[0]; + if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) + earliest_start = fpu_st_timestamp[1]; + if (deps & FPU_RW_STREG) { + int reg = fetchdat & 7; - if (fpu_st_timestamp[reg] > decode_timestamp) - earliest_start = fpu_st_timestamp[reg]; - } + if (fpu_st_timestamp[reg] > decode_timestamp) + earliest_start = fpu_st_timestamp[reg]; + } - /*Short decoders are limited to 7 bytes*/ - if (decode_type == DECODE_SHORT && instr_length > 7) - decode_type = DECODE_LONG; - /*Long decoder is limited to 11 bytes*/ - else if (instr_length > 11) - decode_type = DECODE_VECTOR; + /*Short decoders are limited to 7 bytes*/ + if (decode_type == DECODE_SHORT && instr_length > 7) + decode_type = DECODE_LONG; + /*Long decoder is limited to 11 bytes*/ + else if (instr_length > 11) + decode_type = DECODE_VECTOR; - switch (decode_type) - { - case DECODE_SHORT: - if (decode_buffer.nr_uops) - { - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - if (ins->nr_uops > 1) - { - decode_buffer.uops[decode_buffer.nr_uops+1] = &ins->uop[1]; - decode_buffer.earliest_start[decode_buffer.nr_uops+1] = -1; - } - decode_buffer.nr_uops += ins->nr_uops; - - decode_flush(); + switch (decode_type) { + case DECODE_SHORT: + if (decode_buffer.nr_uops) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + if (ins->nr_uops > 1) { + decode_buffer.uops[decode_buffer.nr_uops + 1] = &ins->uop[1]; + decode_buffer.earliest_start[decode_buffer.nr_uops + 1] = -1; } - else - { - decode_buffer.nr_uops = ins->nr_uops; - decode_buffer.uops[0] = &ins->uop[0]; - decode_buffer.earliest_start[0] = earliest_start; - if (ins->nr_uops > 1) - { - decode_buffer.uops[1] = &ins->uop[1]; - decode_buffer.earliest_start[1] = -1; - } - } - break; + decode_buffer.nr_uops += ins->nr_uops; - case DECODE_LONG: - if (decode_buffer.nr_uops) - decode_flush(); - - decode_buffer.nr_uops = ins->nr_uops; - for (c = 0; c < ins->nr_uops; c++) - { - decode_buffer.uops[c] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[c] = earliest_start; - else - decode_buffer.earliest_start[c] = -1; - } decode_flush(); - break; - - case DECODE_VECTOR: - if (decode_buffer.nr_uops) - decode_flush(); - - decode_timestamp++; - d = 0; - - for (c = 0; c < ins->nr_uops; c++) - { - decode_buffer.uops[d] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[d] = earliest_start; - else - decode_buffer.earliest_start[d] = -1; - d++; - - if (d == 4) - { - d = 0; - decode_buffer.nr_uops = 4; - decode_flush(); - } + } else { + decode_buffer.nr_uops = ins->nr_uops; + decode_buffer.uops[0] = &ins->uop[0]; + decode_buffer.earliest_start[0] = earliest_start; + if (ins->nr_uops > 1) { + decode_buffer.uops[1] = &ins->uop[1]; + decode_buffer.earliest_start[1] = -1; } - if (d) - { - decode_buffer.nr_uops = d; - decode_flush(); - } - break; - } + } + break; - /*Update write timestamps for any output registers*/ - regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); - for (c = 0; c < 8; c++) - { - if (regmask_modified & (1 << c)) - reg_available_timestamp[c] = last_complete_timestamp; - } - if (deps & FPU_POP) - { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c+1]; - fpu_st_timestamp[7] = 0; - } - if (deps & FPU_POP2) - { - for (c = 0; c < 6; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c+2]; - fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; - } - if (deps & FPU_PUSH) - { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c+1] = fpu_st_timestamp[c]; - fpu_st_timestamp[0] = 0; - } - if (deps & FPU_WRITE_ST0) - fpu_st_timestamp[0] = last_complete_timestamp; - if (deps & FPU_WRITE_ST1) - fpu_st_timestamp[1] = last_complete_timestamp; - if (deps & FPU_WRITE_STREG) - { - int reg = fetchdat & 7; - if (deps & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps & FPU_WRITE_ST0)) && - !(reg == 1 && (deps & FPU_WRITE_ST1))) - fpu_st_timestamp[reg] = last_complete_timestamp; - } -} + case DECODE_LONG: + if (decode_buffer.nr_uops) + decode_flush(); -void codegen_timing_k6_block_start(void) -{ - int c; - - for (c = 0; c < nr_units; c++) - units[c].first_available_cycle = 0; - - mul_first_available_cycle = 0; - shift_first_available_cycle = 0; - m3dnow_first_available_cycle = 0; - - decode_timestamp = 0; - last_complete_timestamp = 0; - - for (c = 0; c < NR_OPQUADS; c++) - opquad_completion_timestamp[c] = 0; - next_opquad = 0; - - for (c = 0; c < NR_REGS; c++) - reg_available_timestamp[c] = 0; - for (c = 0; c < 8; c++) - fpu_st_timestamp[c] = 0; -} - -void codegen_timing_k6_start(void) -{ - if (cpu_s->cpu_type == CPU_K6) - { - units = k6_units; - nr_units = NR_K6_UNITS; - } - else - { - units = k6_2_units; - nr_units = NR_K6_2_UNITS; - } - last_prefix = 0; - prefixes = 0; -} - -void codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) -{ - if (prefix != 0x0f) - decode_timestamp++; - - last_prefix = prefix; - prefixes++; -} - -void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) -{ - const risc86_instruction_t **ins_table; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int old_last_complete_timestamp = last_complete_timestamp; - int bit8 = !(opcode & 1); - - switch (last_prefix) - { - case 0x0f: - if (opcode == 0x0f) - { - /*3DNow has the actual opcode after ModR/M, SIB and any offset*/ - uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/ - uint8_t modrm = fetchdat & 0xff; - uint8_t sib = (fetchdat >> 8) & 0xff; - - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 7) == 4) - { - /* Has SIB*/ - opcode_pc++; - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((sib & 0x07) == 0x05) - opcode_pc += 4; - } - else - { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((modrm & 0xc7) == 0x05) - opcode_pc += 4; - } - } - else - { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 2; - else if ((modrm & 0xc7) == 0x06) - opcode_pc += 2; - } - } - - opcode = fastreadb(cs + opcode_pc); - - ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f; - deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; - } + decode_buffer.nr_uops = ins->nr_uops; + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[c] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[c] = earliest_start; else - { - ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - } - break; + decode_buffer.earliest_start[c] = -1; + } + decode_flush(); + break; - case 0xd8: - ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; + case DECODE_VECTOR: + if (decode_buffer.nr_uops) + decode_flush(); + + decode_timestamp++; + d = 0; + + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[d] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[d] = earliest_start; + else + decode_buffer.earliest_start[d] = -1; + d++; + + if (d == 4) { + d = 0; + decode_buffer.nr_uops = 4; + decode_flush(); + } + } + if (d) { + decode_buffer.nr_uops = d; + decode_flush(); + } + break; + } + + /*Update write timestamps for any output registers*/ + regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); + for (c = 0; c < 8; c++) { + if (regmask_modified & (1 << c)) + reg_available_timestamp[c] = last_complete_timestamp; + } + if (deps & FPU_POP) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 1]; + fpu_st_timestamp[7] = 0; + } + if (deps & FPU_POP2) { + for (c = 0; c < 6; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 2]; + fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; + } + if (deps & FPU_PUSH) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c + 1] = fpu_st_timestamp[c]; + fpu_st_timestamp[0] = 0; + } + if (deps & FPU_WRITE_ST0) + fpu_st_timestamp[0] = last_complete_timestamp; + if (deps & FPU_WRITE_ST1) + fpu_st_timestamp[1] = last_complete_timestamp; + if (deps & FPU_WRITE_STREG) { + int reg = fetchdat & 7; + if (deps & FPU_POP) + reg--; + if (reg >= 0 && !(reg == 0 && (deps & FPU_WRITE_ST0)) && !(reg == 1 && (deps & FPU_WRITE_ST1))) + fpu_st_timestamp[reg] = last_complete_timestamp; + } +} + +void +codegen_timing_k6_block_start(void) +{ + int c; + + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = 0; + + mul_first_available_cycle = 0; + shift_first_available_cycle = 0; + m3dnow_first_available_cycle = 0; + + decode_timestamp = 0; + last_complete_timestamp = 0; + + for (c = 0; c < NR_OPQUADS; c++) + opquad_completion_timestamp[c] = 0; + next_opquad = 0; + + for (c = 0; c < NR_REGS; c++) + reg_available_timestamp[c] = 0; + for (c = 0; c < 8; c++) + fpu_st_timestamp[c] = 0; +} + +void +codegen_timing_k6_start(void) +{ + if (cpu_s->cpu_type == CPU_K6) { + units = k6_units; + nr_units = NR_K6_UNITS; + } else { + units = k6_2_units; + nr_units = NR_K6_2_UNITS; + } + last_prefix = 0; + prefixes = 0; +} + +void +codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) +{ + if (prefix != 0x0f) + decode_timestamp++; + + last_prefix = prefix; + prefixes++; +} + +void +codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +{ + const risc86_instruction_t **ins_table; + const uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int old_last_complete_timestamp = last_complete_timestamp; + int bit8 = !(opcode & 1); + + switch (last_prefix) { + case 0x0f: + if (opcode == 0x0f) { + /*3DNow has the actual opcode after ModR/M, SIB and any offset*/ + uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/ + uint8_t modrm = fetchdat & 0xff; + uint8_t sib = (fetchdat >> 8) & 0xff; + + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 7) == 4) { + /* Has SIB*/ + opcode_pc++; + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((sib & 0x07) == 0x05) + opcode_pc += 4; + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((modrm & 0xc7) == 0x05) + opcode_pc += 4; + } + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } + } + + opcode = fastreadb(cs + opcode_pc); + + ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f; + deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; + } else { + ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + } + break; + + case 0xd8: + ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + case 0x83: + ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xd0: + case 0xd2: + ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc1: + case 0xd1: + case 0xd3: + ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: - ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: case 0x83: - ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } - case 0xc0: case 0xd0: case 0xd2: - ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; + if (ins_table[opcode]) + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); + else + decode_instruction(&vector_alu1_op, 0, fetchdat, op_32, bit8); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); +} - case 0xc1: case 0xd1: case 0xd3: - ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - if (ins_table[opcode]) - decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); - else - decode_instruction(&vector_alu1_op, 0, fetchdat, op_32, bit8); +void +codegen_timing_k6_block_end(void) +{ + if (decode_buffer.nr_uops) { + int old_last_complete_timestamp = last_complete_timestamp; + decode_flush(); codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + } } -void codegen_timing_k6_block_end(void) +int +codegen_timing_k6_jump_cycles(void) { - if (decode_buffer.nr_uops) - { - int old_last_complete_timestamp = last_complete_timestamp; - decode_flush(); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); - } + if (decode_buffer.nr_uops) + return 1; + return 0; } -int codegen_timing_k6_jump_cycles(void) -{ - if (decode_buffer.nr_uops) - return 1; - return 0; -} - -codegen_timing_t codegen_timing_k6 = -{ - codegen_timing_k6_start, - codegen_timing_k6_prefix, - codegen_timing_k6_opcode, - codegen_timing_k6_block_start, - codegen_timing_k6_block_end, - codegen_timing_k6_jump_cycles +codegen_timing_t codegen_timing_k6 = { + codegen_timing_k6_start, + codegen_timing_k6_prefix, + codegen_timing_k6_opcode, + codegen_timing_k6_block_start, + codegen_timing_k6_block_end, + codegen_timing_k6_jump_cycles }; diff --git a/src/cpu/codegen_timing_p6.c b/src/cpu/codegen_timing_p6.c index cf40e084e..008e36594 100644 --- a/src/cpu/codegen_timing_p6.c +++ b/src/cpu/codegen_timing_p6.c @@ -8,6 +8,7 @@ #include "cpu.h" #include <86box/mem.h> #include <86box/machine.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_ops.h" @@ -17,893 +18,775 @@ #include "codegen_ops.h" #include "codegen_timing_common.h" -typedef enum uop_type_t -{ - UOP_ALU = 0, /*Executes in Port 0 or 1 ALU units*/ - UOP_ALUP0, /*Executes in Port 0 ALU unit*/ - UOP_LOAD, /*Executes in Load unit*/ - UOP_STORED, /*Executes in Data Store unit*/ - UOP_STOREA, /*Executes in Address Store unit*/ - UOP_FLOAD, /*Executes in Load unit*/ - UOP_FSTORED, /*Executes in Data Store unit*/ - UOP_FSTOREA, /*Executes in Address Store unit*/ - UOP_MLOAD, /*Executes in Load unit*/ - UOP_MSTORED, /*Executes in Data Store unit*/ - UOP_MSTOREA, /*Executes in Address Store unit*/ - UOP_FLOAT, /*Executes in Floating Point unit*/ - UOP_MMX, /*Executes in Port 0 or 1 ALU units as MMX*/ - UOP_MMX_SHIFT, /*Executes in Port 1 ALU unit. Uses MMX shifter*/ - UOP_MMX_MUL, /*Executes in Port 0 ALU unit. Uses MMX multiplier*/ - UOP_BRANCH, /*Executes in Branch unit*/ - UOP_FXCH /*Does not require an execution unit*/ +typedef enum uop_type_t { + UOP_ALU = 0, /*Executes in Port 0 or 1 ALU units*/ + UOP_ALUP0, /*Executes in Port 0 ALU unit*/ + UOP_LOAD, /*Executes in Load unit*/ + UOP_STORED, /*Executes in Data Store unit*/ + UOP_STOREA, /*Executes in Address Store unit*/ + UOP_FLOAD, /*Executes in Load unit*/ + UOP_FSTORED, /*Executes in Data Store unit*/ + UOP_FSTOREA, /*Executes in Address Store unit*/ + UOP_MLOAD, /*Executes in Load unit*/ + UOP_MSTORED, /*Executes in Data Store unit*/ + UOP_MSTOREA, /*Executes in Address Store unit*/ + UOP_FLOAT, /*Executes in Floating Point unit*/ + UOP_MMX, /*Executes in Port 0 or 1 ALU units as MMX*/ + UOP_MMX_SHIFT, /*Executes in Port 1 ALU unit. Uses MMX shifter*/ + UOP_MMX_MUL, /*Executes in Port 0 ALU unit. Uses MMX multiplier*/ + UOP_BRANCH, /*Executes in Branch unit*/ + UOP_FXCH /*Does not require an execution unit*/ } uop_type_t; -typedef enum decode_type_t -{ - DECODE_SIMPLE, - DECODE_COMPLEX, +typedef enum decode_type_t { + DECODE_SIMPLE, + DECODE_COMPLEX, } decode_type_t; #define MAX_UOPS 10 -typedef struct p6_uop_t -{ - uop_type_t type; - int latency; +typedef struct p6_uop_t { + uop_type_t type; + int latency; } p6_uop_t; -typedef struct macro_op_t -{ - int nr_uops; - decode_type_t decode_type; - p6_uop_t uop[MAX_UOPS]; +typedef struct macro_op_t { + int nr_uops; + decode_type_t decode_type; + p6_uop_t uop[MAX_UOPS]; } macro_op_t; -static const macro_op_t alu_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t alu_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALU, .latency = 1} }; -static const macro_op_t alup0_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t alup0_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t load_alu_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t load_alu_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t load_alup0_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t load_alup0_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t alu_store_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} +static const macro_op_t alu_store_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_STORED, .latency = 1}, + .uop[3] = { .type = UOP_STOREA, .latency = 1} }; -static const macro_op_t alup0_store_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} +static const macro_op_t alup0_store_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_STORED, .latency = 1}, + .uop[3] = { .type = UOP_STOREA, .latency = 1} }; -static const macro_op_t branch_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_BRANCH, .latency = 2} +static const macro_op_t branch_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_BRANCH, .latency = 2} }; -static const macro_op_t fxch_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FXCH, .latency = 1} +static const macro_op_t fxch_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FXCH, .latency = 1} }; -static const macro_op_t load_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_LOAD, .latency = 1} +static const macro_op_t load_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_LOAD, .latency = 1} }; -static const macro_op_t store_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 1}, - .uop[1] = {.type = UOP_STOREA, .latency = 1} +static const macro_op_t store_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 1}, + .uop[1] = { .type = UOP_STOREA, .latency = 1} }; - -static const macro_op_t bswap_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, +static const macro_op_t bswap_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, }; -static const macro_op_t leave_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t leave_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t lods_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t lods_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t loop_op = -{ - .nr_uops = 5, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1}, - .uop[4] = {.type = UOP_BRANCH, .latency = 1} +static const macro_op_t loop_op = { + .nr_uops = 5, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1}, + .uop[4] = { .type = UOP_BRANCH, .latency = 1} }; -static const macro_op_t mov_reg_seg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, +static const macro_op_t mov_reg_seg_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, }; -static const macro_op_t movs_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t movs_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t pop_reg_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t pop_reg_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t pop_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t pop_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t push_imm_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 1}, - .uop[1] = {.type = UOP_STOREA, .latency = 1}, +static const macro_op_t push_imm_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 1}, + .uop[1] = { .type = UOP_STOREA, .latency = 1}, }; -static const macro_op_t push_mem_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1} +static const macro_op_t push_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1} }; -static const macro_op_t push_seg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t push_seg_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t stos_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t stos_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[1] = {.type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t test_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t test_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1} }; -static const macro_op_t test_reg_b_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t test_reg_b_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t test_mem_imm_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t test_mem_imm_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t test_mem_imm_b_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t test_mem_imm_b_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t xchg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t xchg_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} }; - -static const macro_op_t mmx_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX, .latency = 1} +static const macro_op_t mmx_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_MMX, .latency = 1} }; -static const macro_op_t mmx_mul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} +static const macro_op_t mmx_mul_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} }; -static const macro_op_t mmx_shift_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_SHIFT, .latency = 1} +static const macro_op_t mmx_shift_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_MMX_SHIFT, .latency = 1} }; -static const macro_op_t load_mmx_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 2}, - .uop[1] = {.type = UOP_MMX, .latency = 2} +static const macro_op_t load_mmx_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = { .type = UOP_MMX, .latency = 2} }; -static const macro_op_t load_mmx_mul_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 2}, - .uop[1] = {.type = UOP_MMX_MUL, .latency = 2} +static const macro_op_t load_mmx_mul_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = { .type = UOP_MMX_MUL, .latency = 2} }; -static const macro_op_t load_mmx_shift_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 2}, - .uop[1] = {.type = UOP_MMX_SHIFT, .latency = 2} +static const macro_op_t load_mmx_shift_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = { .type = UOP_MMX_SHIFT, .latency = 2} }; -static const macro_op_t mload_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_MLOAD, .latency = 1}, +static const macro_op_t mload_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_MLOAD, .latency = 1}, }; -static const macro_op_t mstore_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_MSTORED, .latency = 1}, - .uop[1] = {.type = UOP_MSTOREA, .latency = 1} +static const macro_op_t mstore_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_MSTORED, .latency = 1}, + .uop[1] = { .type = UOP_MSTOREA, .latency = 1} }; -static const macro_op_t pmul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} +static const macro_op_t pmul_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} }; -static const macro_op_t pmul_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 2}, - .uop[1] = {.type = UOP_MMX_MUL, .latency = 2} +static const macro_op_t pmul_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = { .type = UOP_MMX_MUL, .latency = 2} }; -static const macro_op_t float_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 1} +static const macro_op_t float_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 1} }; -static const macro_op_t fadd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 2} +static const macro_op_t fadd_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 2} }; -static const macro_op_t fmul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALUP0, .latency = 3} +static const macro_op_t fmul_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALUP0, .latency = 3} }; -static const macro_op_t float2_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 1} +static const macro_op_t float2_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 1}, + .uop[1] = { .type = UOP_FLOAT, .latency = 1} }; -static const macro_op_t fchs_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .latency = 2}, - .uop[2] = {.type = UOP_FLOAT, .latency = 2} +static const macro_op_t fchs_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 2}, + .uop[1] = { .type = UOP_FLOAT, .latency = 2}, + .uop[2] = { .type = UOP_FLOAT, .latency = 2} }; -static const macro_op_t load_float_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 1} +static const macro_op_t load_float_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1}, + .uop[1] = { .type = UOP_FLOAT, .latency = 1} }; -static const macro_op_t load_fadd_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 2} +static const macro_op_t load_fadd_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1}, + .uop[1] = { .type = UOP_FLOAT, .latency = 2} }; -static const macro_op_t load_fmul_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 4} +static const macro_op_t load_fmul_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 4} }; -static const macro_op_t fstore_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FSTORED, .latency = 1}, - .uop[1] = {.type = UOP_FSTOREA, .latency = 1}, +static const macro_op_t fstore_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FSTORED, .latency = 1}, + .uop[1] = { .type = UOP_FSTOREA, .latency = 1}, }; -static const macro_op_t load_fiadd_op = -{ - .nr_uops = 7, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 1}, - .uop[2] = {.type = UOP_FLOAT, .latency = 1}, - .uop[3] = {.type = UOP_FLOAT, .latency = 1}, - .uop[4] = {.type = UOP_FLOAT, .latency = 1}, - .uop[5] = {.type = UOP_FLOAT, .latency = 1}, - .uop[6] = {.type = UOP_FLOAT, .latency = 1} +static const macro_op_t load_fiadd_op = { + .nr_uops = 7, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1}, + .uop[1] = { .type = UOP_FLOAT, .latency = 1}, + .uop[2] = { .type = UOP_FLOAT, .latency = 1}, + .uop[3] = { .type = UOP_FLOAT, .latency = 1}, + .uop[4] = { .type = UOP_FLOAT, .latency = 1}, + .uop[5] = { .type = UOP_FLOAT, .latency = 1}, + .uop[6] = { .type = UOP_FLOAT, .latency = 1} }; -static const macro_op_t fdiv_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 37} +static const macro_op_t fdiv_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 37} }; -static const macro_op_t fdiv_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .latency = 37} +static const macro_op_t fdiv_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1 }, + .uop[1] = { .type = UOP_FLOAT, .latency = 37} }; -static const macro_op_t fsin_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 62} +static const macro_op_t fsin_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 62} }; -static const macro_op_t fsqrt_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 69} +static const macro_op_t fsqrt_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 69} }; -static const macro_op_t fldcw_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 10} +static const macro_op_t fldcw_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 10} }; -static const macro_op_t complex_float_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 1} +static const macro_op_t complex_float_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 1} }; -static const macro_op_t complex_float_l_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 50} +static const macro_op_t complex_float_l_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 50} }; -static const macro_op_t flde_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAD, .latency = 1}, - .uop[1] = {.type = UOP_FLOAD, .latency = 1}, - .uop[2] = {.type = UOP_FLOAT, .latency = 2} +static const macro_op_t flde_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAD, .latency = 1}, + .uop[1] = { .type = UOP_FLOAD, .latency = 1}, + .uop[2] = { .type = UOP_FLOAT, .latency = 2} }; -static const macro_op_t fste_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 2}, - .uop[1] = {.type = UOP_FSTORED, .latency = 1}, - .uop[2] = {.type = UOP_FSTOREA, .latency = 1} +static const macro_op_t fste_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_FLOAT, .latency = 2}, + .uop[1] = { .type = UOP_FSTORED, .latency = 1}, + .uop[2] = { .type = UOP_FSTOREA, .latency = 1} }; -static const macro_op_t complex_alu1_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t complex_alu1_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1} }; -static const macro_op_t alu2_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t alu2_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t alu3_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t alu3_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t alu6_op = -{ - .nr_uops = 6, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1}, - .uop[4] = {.type = UOP_ALU, .latency = 1}, - .uop[5] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t alu6_op = { + .nr_uops = 6, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1}, + .uop[4] = { .type = UOP_ALU, .latency = 1}, + .uop[5] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t complex_alup0_1_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t complex_alup0_1_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t alup0_3_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t alup0_3_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t alup0_6_op = -{ - .nr_uops = 6, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALUP0, .latency = 1}, - .uop[3] = {.type = UOP_ALUP0, .latency = 1}, - .uop[4] = {.type = UOP_ALUP0, .latency = 1}, - .uop[5] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t alup0_6_op = { + .nr_uops = 6, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALUP0, .latency = 1}, + .uop[3] = { .type = UOP_ALUP0, .latency = 1}, + .uop[4] = { .type = UOP_ALUP0, .latency = 1}, + .uop[5] = { .type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t arpl_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 3}, - .uop[1] = {.type = UOP_ALU, .latency = 3} +static const macro_op_t arpl_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 3}, + .uop[1] = { .type = UOP_ALU, .latency = 3} }; -static const macro_op_t bound_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t bound_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t bsx_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 10} +static const macro_op_t bsx_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 10} }; -static const macro_op_t call_far_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 3}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_BRANCH, .latency = 1} +static const macro_op_t call_far_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 3}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_BRANCH, .latency = 1} }; -static const macro_op_t cli_sti_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 7} +static const macro_op_t cli_sti_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 7} }; -static const macro_op_t cmps_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t cmps_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t cmpsb_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t cmpsb_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t cmpxchg_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} +static const macro_op_t cmpxchg_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1}, + .uop[2] = { .type = UOP_STORED, .latency = 1}, + .uop[3] = { .type = UOP_STOREA, .latency = 1} }; -static const macro_op_t cmpxchg_b_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} +static const macro_op_t cmpxchg_b_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_STORED, .latency = 1}, + .uop[3] = { .type = UOP_STOREA, .latency = 1} }; -static const macro_op_t complex_push_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 1}, - .uop[1] = {.type = UOP_STOREA, .latency = 1} +static const macro_op_t complex_push_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 1}, + .uop[1] = { .type = UOP_STOREA, .latency = 1} }; -static const macro_op_t cpuid_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 23} +static const macro_op_t cpuid_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 23} }; -static const macro_op_t div16_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 21} +static const macro_op_t div16_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 21} }; -static const macro_op_t div16_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 21} +static const macro_op_t div16_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1 }, + .uop[1] = { .type = UOP_ALUP0, .latency = 21} }; -static const macro_op_t div32_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 37} +static const macro_op_t div32_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 37} }; -static const macro_op_t div32_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 37} +static const macro_op_t div32_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1 }, + .uop[1] = { .type = UOP_ALUP0, .latency = 37} }; -static const macro_op_t emms_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 50} +static const macro_op_t emms_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 50} }; -static const macro_op_t enter_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 1}, - .uop[1] = {.type = UOP_STOREA, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 10} +static const macro_op_t enter_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 1 }, + .uop[1] = { .type = UOP_STOREA, .latency = 1 }, + .uop[2] = { .type = UOP_ALU, .latency = 10} }; -static const macro_op_t femms_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 6} +static const macro_op_t femms_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 6} }; -static const macro_op_t in_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 18} +static const macro_op_t in_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 18} }; -static const macro_op_t ins_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 18}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t ins_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 18}, + .uop[1] = { .type = UOP_STORED, .latency = 1 }, + .uop[2] = { .type = UOP_STOREA, .latency = 1 }, + .uop[3] = { .type = UOP_ALU, .latency = 1 } }; -static const macro_op_t int_op = -{ - .nr_uops = 8, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 20}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_STORED, .latency = 1}, - .uop[4] = {.type = UOP_STOREA, .latency = 1}, - .uop[5] = {.type = UOP_STORED, .latency = 1}, - .uop[6] = {.type = UOP_STOREA, .latency = 1}, - .uop[7] = {.type = UOP_BRANCH, .latency = 1} +static const macro_op_t int_op = { + .nr_uops = 8, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 20}, + .uop[1] = { .type = UOP_STORED, .latency = 1 }, + .uop[2] = { .type = UOP_STOREA, .latency = 1 }, + .uop[3] = { .type = UOP_STORED, .latency = 1 }, + .uop[4] = { .type = UOP_STOREA, .latency = 1 }, + .uop[5] = { .type = UOP_STORED, .latency = 1 }, + .uop[6] = { .type = UOP_STOREA, .latency = 1 }, + .uop[7] = { .type = UOP_BRANCH, .latency = 1 } }; -static const macro_op_t iret_op = -{ - .nr_uops = 5, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_LOAD, .latency = 3}, - .uop[2] = {.type = UOP_LOAD, .latency = 3}, - .uop[3] = {.type = UOP_ALU, .latency = 20}, - .uop[4] = {.type = UOP_BRANCH, .latency = 1} +static const macro_op_t iret_op = { + .nr_uops = 5, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 3 }, + .uop[1] = { .type = UOP_LOAD, .latency = 3 }, + .uop[2] = { .type = UOP_LOAD, .latency = 3 }, + .uop[3] = { .type = UOP_ALU, .latency = 20}, + .uop[4] = { .type = UOP_BRANCH, .latency = 1 } }; -static const macro_op_t invd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 500} +static const macro_op_t invd_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 500} }; -static const macro_op_t jmp_far_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 3}, - .uop[1] = {.type = UOP_BRANCH, .latency = 1} +static const macro_op_t jmp_far_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 3}, + .uop[1] = { .type = UOP_BRANCH, .latency = 1} }; -static const macro_op_t lss_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 3} +static const macro_op_t lss_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 3} }; -static const macro_op_t mov_mem_seg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, +static const macro_op_t mov_mem_seg_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, }; -static const macro_op_t mov_seg_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 3} +static const macro_op_t mov_seg_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 3} }; -static const macro_op_t mov_seg_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 3} +static const macro_op_t mov_seg_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 3} }; -static const macro_op_t mul_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t mul_op = { + .nr_uops = 1, + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t mul_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t mul_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t mul64_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t mul64_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t mul64_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALUP0, .latency = 1}, - .uop[3] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t mul64_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALUP0, .latency = 1}, + .uop[3] = { .type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t out_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 18} +static const macro_op_t out_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 18} }; -static const macro_op_t outs_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 18} +static const macro_op_t outs_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1 }, + .uop[1] = { .type = UOP_ALU, .latency = 18} }; -static const macro_op_t pusha_op = -{ - .nr_uops = 8, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 2}, - .uop[1] = {.type = UOP_STOREA, .latency = 2}, - .uop[2] = {.type = UOP_STORED, .latency = 2}, - .uop[3] = {.type = UOP_STOREA, .latency = 2}, - .uop[4] = {.type = UOP_STORED, .latency = 2}, - .uop[5] = {.type = UOP_STOREA, .latency = 2}, - .uop[6] = {.type = UOP_STORED, .latency = 2}, - .uop[7] = {.type = UOP_STOREA, .latency = 2} +static const macro_op_t pusha_op = { + .nr_uops = 8, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_STORED, .latency = 2}, + .uop[1] = { .type = UOP_STOREA, .latency = 2}, + .uop[2] = { .type = UOP_STORED, .latency = 2}, + .uop[3] = { .type = UOP_STOREA, .latency = 2}, + .uop[4] = { .type = UOP_STORED, .latency = 2}, + .uop[5] = { .type = UOP_STOREA, .latency = 2}, + .uop[6] = { .type = UOP_STORED, .latency = 2}, + .uop[7] = { .type = UOP_STOREA, .latency = 2} }; -static const macro_op_t popa_op = -{ - .nr_uops = 8, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .latency = 1}, - .uop[2] = {.type = UOP_LOAD, .latency = 1}, - .uop[3] = {.type = UOP_LOAD, .latency = 1}, - .uop[4] = {.type = UOP_LOAD, .latency = 1}, - .uop[5] = {.type = UOP_LOAD, .latency = 1}, - .uop[6] = {.type = UOP_LOAD, .latency = 1}, - .uop[7] = {.type = UOP_LOAD, .latency = 1} +static const macro_op_t popa_op = { + .nr_uops = 8, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .latency = 1}, + .uop[2] = { .type = UOP_LOAD, .latency = 1}, + .uop[3] = { .type = UOP_LOAD, .latency = 1}, + .uop[4] = { .type = UOP_LOAD, .latency = 1}, + .uop[5] = { .type = UOP_LOAD, .latency = 1}, + .uop[6] = { .type = UOP_LOAD, .latency = 1}, + .uop[7] = { .type = UOP_LOAD, .latency = 1} }; -static const macro_op_t popf_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 6}, - .uop[2] = {.type = UOP_ALUP0, .latency = 10} +static const macro_op_t popf_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1 }, + .uop[1] = { .type = UOP_ALU, .latency = 6 }, + .uop[2] = { .type = UOP_ALUP0, .latency = 10} }; -static const macro_op_t pushf_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1} +static const macro_op_t pushf_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1} }; -static const macro_op_t ret_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .latency = 1} +static const macro_op_t ret_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_BRANCH, .latency = 1} }; -static const macro_op_t retf_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 3}, - .uop[2] = {.type = UOP_BRANCH, .latency = 1} +static const macro_op_t retf_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 3}, + .uop[2] = { .type = UOP_BRANCH, .latency = 1} }; -static const macro_op_t scas_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t scas_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t scasb_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t scasb_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t setcc_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_FSTORED, .latency = 1}, - .uop[3] = {.type = UOP_FSTOREA, .latency = 1} +static const macro_op_t setcc_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_FSTORED, .latency = 1}, + .uop[3] = { .type = UOP_FSTOREA, .latency = 1} }; -static const macro_op_t setcc_reg_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUP0, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t setcc_reg_op = { + .nr_uops = 3, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t test_mem_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t test_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t test_mem_b_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUP0, .latency = 1} +static const macro_op_t test_mem_b_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_ALUP0, .latency = 1} }; -static const macro_op_t xchg_mem_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .latency = 1} +static const macro_op_t xchg_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = { .type = UOP_STORED, .latency = 1}, + .uop[2] = { .type = UOP_STOREA, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .latency = 1} }; -static const macro_op_t xlat_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .latency = 1} +static const macro_op_t xlat_op = { + .nr_uops = 2, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .latency = 1} }; -static const macro_op_t wbinvd_op = -{ - .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 10000} +static const macro_op_t wbinvd_op = { + .nr_uops = 1, + .decode_type = DECODE_COMPLEX, + .uop[0] = {.type = UOP_ALU, .latency = 10000} }; #define INVALID NULL -static const macro_op_t *opcode_timings[256] = -{ +static const macro_op_t *opcode_timings[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* ADD ADD PUSH ES POP ES*/ @@ -1036,10 +919,11 @@ static const macro_op_t *opcode_timings[256] = &complex_alu1_op, &complex_alu1_op, &cli_sti_op, &cli_sti_op, /* CLD STD INCDEC*/ &complex_alu1_op, &complex_alu1_op, &alup0_store_op, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_mod3[256] = -{ +static const macro_op_t *opcode_timings_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alup0_op, &alu_op, &alup0_op, &alu_op, /* ADD ADD PUSH ES POP ES*/ @@ -1173,10 +1057,11 @@ static const macro_op_t *opcode_timings_mod3[256] = &complex_alu1_op, &complex_alu1_op, &cli_sti_op, &cli_sti_op, /* CLD STD INCDEC*/ &complex_alu1_op, &complex_alu1_op, &complex_alup0_1_op, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_0f[256] = -{ +static const macro_op_t *opcode_timings_0f[256] = { + // clang-format off /*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, INVALID, &alu6_op, &alu6_op, INVALID, &invd_op, &wbinvd_op, INVALID, INVALID, @@ -1256,9 +1141,10 @@ static const macro_op_t *opcode_timings_0f[256] = INVALID, &pmul_mem_op, INVALID, INVALID, &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, + // clang-format on }; -static const macro_op_t *opcode_timings_0f_mod3[256] = -{ +static const macro_op_t *opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, INVALID, &alu6_op, &alu6_op, INVALID, &invd_op, &wbinvd_op, INVALID, INVALID, @@ -1342,113 +1228,131 @@ static const macro_op_t *opcode_timings_0f_mod3[256] = static const macro_op_t *opcode_timings_shift[8] = { + // clang-format off &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op + // clang-format on }; -static const macro_op_t *opcode_timings_shift_b[8] = -{ +static const macro_op_t *opcode_timings_shift_b[8] = { + // clang-format off &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op + // clang-format on }; -static const macro_op_t *opcode_timings_shift_mod3[8] = -{ +static const macro_op_t *opcode_timings_shift_mod3[8] = { + // clang-format off &complex_alu1_op, &complex_alu1_op, &complex_alu1_op, &complex_alu1_op, &alu_op, &alu_op, &alu_op, &alu_op + // clang-format on }; -static const macro_op_t *opcode_timings_shift_b_mod3[8] = -{ +static const macro_op_t *opcode_timings_shift_b_mod3[8] = { + // clang-format off &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, &alup0_op, &alup0_op, &alup0_op, &alup0_op + // clang-format on }; -static const macro_op_t *opcode_timings_80[8] = -{ +static const macro_op_t *opcode_timings_80[8] = { + // clang-format off &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, + // clang-format on }; -static const macro_op_t *opcode_timings_80_mod3[8] = -{ +static const macro_op_t *opcode_timings_80_mod3[8] = { + // clang-format off &alup0_op, &alup0_op, &alup0_store_op, &alup0_store_op, &alup0_op, &alup0_op, &alup0_op, &alup0_op, + // clang-format on }; -static const macro_op_t *opcode_timings_8x[8] = -{ +static const macro_op_t *opcode_timings_8x[8] = { + // clang-format off &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, + // clang-format on }; -static const macro_op_t *opcode_timings_8x_mod3[8] = -{ +static const macro_op_t *opcode_timings_8x_mod3[8] = { + // clang-format off &alu_op, &alu_op, &alu_store_op, &alu_store_op, &alu_op, &alu_op, &alu_op, &alu_op, + // clang-format on }; -static const macro_op_t *opcode_timings_f6[8] = -{ +static const macro_op_t *opcode_timings_f6[8] = { + // clang-format off /* TST NOT NEG*/ &test_mem_imm_b_op, INVALID, &alup0_store_op, &alup0_store_op, /* MUL IMUL DIV IDIV*/ &mul_mem_op, &mul_mem_op, &div16_mem_op, &div16_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_f6_mod3[8] = -{ +static const macro_op_t *opcode_timings_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ &test_reg_b_op, INVALID, &alup0_op, &alup0_op, /* MUL IMUL DIV IDIV*/ &mul_op, &mul_op, &div16_op, &div16_op, + // clang-format on }; -static const macro_op_t *opcode_timings_f7[8] = -{ +static const macro_op_t *opcode_timings_f7[8] = { + // clang-format off /* TST NOT NEG*/ &test_mem_imm_op, INVALID, &alu_store_op, &alu_store_op, /* MUL IMUL DIV IDIV*/ &mul64_mem_op, &mul64_mem_op, &div32_mem_op, &div32_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_f7_mod3[8] = -{ +static const macro_op_t *opcode_timings_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ &test_reg_op, INVALID, &alu_op, &alu_op, /* MUL IMUL DIV IDIV*/ &mul64_op, &mul64_op, &div32_op, &div32_op, + // clang-format on }; -static const macro_op_t *opcode_timings_ff[8] = -{ +static const macro_op_t *opcode_timings_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ &alu_store_op, &alu_store_op, &store_op, &call_far_op, /* JMP JMP far PUSH*/ &branch_op, &jmp_far_op, &push_mem_op, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_ff_mod3[8] = -{ +static const macro_op_t *opcode_timings_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ &complex_alu1_op, &complex_alu1_op, &store_op, &call_far_op, /* JMP JMP far PUSH*/ &branch_op, &jmp_far_op, &complex_push_mem_op, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_d8[8] = -{ +static const macro_op_t *opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ &load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op, /* FSUBs FSUBRs FDIVs FDIVRs*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_d8_mod3[8] = -{ +static const macro_op_t *opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ &fadd_op, &fmul_op, &float_op, &float_op, /* FSUB FSUBR FDIV FDIVR*/ &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on }; -static const macro_op_t *opcode_timings_d9[8] = -{ +static const macro_op_t *opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDENV FLDCW FSTENV FSTCW*/ &complex_float_l_op, &fldcw_op, &complex_float_l_op, &complex_float_op + // clang-format on }; -static const macro_op_t *opcode_timings_d9_mod3[64] = -{ +static const macro_op_t *opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, @@ -1477,31 +1381,35 @@ static const macro_op_t *opcode_timings_d9_mod3[64] = &fdiv_op, INVALID, &fsqrt_op, &fsin_op, /* opFRNDINT opFSCALE opFSIN opFCOS*/ &float_op, &fdiv_op, &fsin_op, &fsin_op + // clang-format on }; -static const macro_op_t *opcode_timings_da[8] = -{ +static const macro_op_t *opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ &load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op, /* FISUBl FISUBRl FIDIVl FIDIVRl*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_da_mod3[8] = -{ +static const macro_op_t *opcode_timings_da_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ INVALID, &float_op, INVALID, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_db[8] = -{ +static const macro_op_t *opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDe FSTPe*/ INVALID, &flde_op, INVALID, &fste_op + // clang-format on }; -static const macro_op_t *opcode_timings_db_mod3[64] = -{ +static const macro_op_t *opcode_timings_db_mod3[64] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1527,153 +1435,152 @@ static const macro_op_t *opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static const macro_op_t *opcode_timings_dc[8] = -{ +static const macro_op_t *opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ &load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op, /* FSUBd FSUBRd FDIVd FDIVRd*/ &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on }; -static const macro_op_t *opcode_timings_dc_mod3[8] = -{ +static const macro_op_t *opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ &fadd_op, &fmul_op, INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ &float_op, &float_op, &fdiv_op, &fdiv_op + // clang-format on }; -static const macro_op_t *opcode_timings_dd[8] = -{ +static const macro_op_t *opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FRSTOR FSAVE FSTSW*/ &complex_float_l_op, INVALID, &complex_float_l_op, &complex_float_l_op + // clang-format on }; -static const macro_op_t *opcode_timings_dd_mod3[8] = -{ +static const macro_op_t *opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ &float_op, INVALID, &float_op, &float_op, /* FUCOM FUCOMP*/ &float_op, &float_op, INVALID, INVALID + // clang-format on }; -static const macro_op_t *opcode_timings_de[8] = -{ +static const macro_op_t *opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, /* FISUBw FISUBRw FIDIVw FIDIVRw*/ &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, + // clang-format on }; -static const macro_op_t *opcode_timings_de_mod3[8] = -{ +static const macro_op_t *opcode_timings_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ &fadd_op, &fmul_op, INVALID, &float_op, /* FSUBP FSUBRP FDIVP FDIVRP*/ &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on }; -static const macro_op_t *opcode_timings_df[8] = -{ +static const macro_op_t *opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FILDiq FBSTP FISTPiq*/ INVALID, &load_float_op, &complex_float_l_op, &fstore_op, + // clang-format on }; -static const macro_op_t *opcode_timings_df_mod3[8] = -{ +static const macro_op_t *opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ &float_op, INVALID, INVALID, INVALID + // clang-format on }; - static uint8_t last_prefix; -static int prefixes; +static int prefixes; static int decode_timestamp; static int last_complete_timestamp; -typedef struct p6_unit_t -{ - uint32_t uop_mask; - double first_available_cycle; +typedef struct p6_unit_t { + uint32_t uop_mask; + double first_available_cycle; } p6_unit_t; -static int nr_units; +static int nr_units; static p6_unit_t *units; /*Pentium Pro has no MMX*/ -static p6_unit_t ppro_units[] = -{ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUP0) | (1 << UOP_FLOAT)}, /*Port 0*/ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH)}, /*Port 1*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD)}, /*Port 2*/ - {.uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED)}, /*Port 3*/ - {.uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA)}, /*Port 4*/ +static p6_unit_t ppro_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUP0) | (1 << UOP_FLOAT) }, /*Port 0*/ + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH) }, /*Port 1*/ + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) }, /*Port 2*/ + { .uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED) }, /*Port 3*/ + { .uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA) }, /*Port 4*/ }; #define NR_PPRO_UNITS (sizeof(ppro_units) / sizeof(p6_unit_t)) /*Pentium II/Celeron assigns the multiplier to port 0, the shifter to port 1, and shares the MMX ALU*/ -static p6_unit_t p2_units[] = -{ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUP0) | (1 << UOP_FLOAT) | /*Port 0*/ - (1 << UOP_MMX) | (1 << UOP_MMX_MUL)}, - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH) | /*Port 1*/ - (1 << UOP_MMX) | (1 << UOP_MMX_SHIFT)}, - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Port 2*/ - {.uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED) | (1 << UOP_MSTORED)}, /*Port 3*/ - {.uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA) | (1 << UOP_MSTOREA)}, /*Port 4*/ +static p6_unit_t p2_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUP0) | (1 << UOP_FLOAT) | /*Port 0*/ + (1 << UOP_MMX) | (1 << UOP_MMX_MUL) }, + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH) | /*Port 1*/ + (1 << UOP_MMX) | (1 << UOP_MMX_SHIFT) }, + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Port 2*/ + { .uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED) | (1 << UOP_MSTORED) }, /*Port 3*/ + { .uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA) | (1 << UOP_MSTOREA) }, /*Port 4*/ }; #define NR_P2_UNITS (sizeof(p2_units) / sizeof(p6_unit_t)) -static int uop_run(const p6_uop_t *uop, int decode_time) +static int +uop_run(const p6_uop_t *uop, int decode_time) { - int c; - p6_unit_t *best_unit = NULL; - int best_start_cycle = 99999; + p6_unit_t *best_unit = NULL; + int best_start_cycle = 99999; - /*UOP_FXCH does not require execution*/ - if (uop->type == UOP_FXCH) - return decode_time; + /*UOP_FXCH does not require execution*/ + if (uop->type == UOP_FXCH) + return decode_time; - /*Find execution unit for this uOP*/ - for (c = 0; c < nr_units; c++) - { - if (units[c].uop_mask & (1 << uop->type)) - { - if (units[c].first_available_cycle < best_start_cycle) - { - best_unit = &units[c]; - best_start_cycle = units[c].first_available_cycle; - } - } + /*Find execution unit for this uOP*/ + for (int c = 0; c < nr_units; c++) { + if (units[c].uop_mask & (1 << uop->type)) { + if (units[c].first_available_cycle < best_start_cycle) { + best_unit = &units[c]; + best_start_cycle = units[c].first_available_cycle; + } } - if (!best_unit) - fatal("uop_run: can not find execution unit\n"); + } + if (!best_unit) + fatal("uop_run: can not find execution unit\n"); - if (best_start_cycle < decode_time) - best_start_cycle = decode_time; - best_unit->first_available_cycle = best_start_cycle + uop->latency; + if (best_start_cycle < decode_time) + best_start_cycle = decode_time; + best_unit->first_available_cycle = best_start_cycle + uop->latency; - - - return best_start_cycle + uop->latency; + return best_start_cycle + uop->latency; } /*The P6 decoders can decode, per clock : - 1 to 3 'simple' instructions, each up to 1 uOP and 7 bytes long - 1 'complex' instruction, up to 4 uOPs or 3 per cycle for instructions longer than 4 uOPs */ -static struct -{ - int nr_uops; - const p6_uop_t *uops[6]; - /*Earliest time a uop can start. If the timestamp is -1, then the uop is - part of a dependency chain and the start time is the completion time of - the previous uop*/ - int earliest_start[6]; +static struct { + int nr_uops; + const p6_uop_t *uops[6]; + /*Earliest time a uop can start. If the timestamp is -1, then the uop is + part of a dependency chain and the start time is the completion time of + the previous uop*/ + int earliest_start[6]; } decode_buffer; #define NR_OPSEQS 3 @@ -1691,421 +1598,400 @@ static int fpu_st_timestamp[8]; dependent uop chains*/ static int last_uop_timestamp = 0; -void decode_flush_p6(void) +void +decode_flush_p6(void) { - int c; - int start_timestamp, uop_timestamp = 0; + int start_timestamp; + int uop_timestamp = 0; - /*Decoded opseq can not be submitted if there are no free spaces in the - opseq buffer*/ - if (decode_timestamp < opseq_completion_timestamp[next_opseq]) - decode_timestamp = opseq_completion_timestamp[next_opseq]; + /*Decoded opseq can not be submitted if there are no free spaces in the + opseq buffer*/ + if (decode_timestamp < opseq_completion_timestamp[next_opseq]) + decode_timestamp = opseq_completion_timestamp[next_opseq]; - /*Ensure that uops can not be submitted before they have been decoded*/ - if (decode_timestamp > last_uop_timestamp) - last_uop_timestamp = decode_timestamp; + /*Ensure that uops can not be submitted before they have been decoded*/ + if (decode_timestamp > last_uop_timestamp) + last_uop_timestamp = decode_timestamp; - /*Submit uops to execution units, and determine the latest completion time*/ - for (c = 0; c < (decode_buffer.nr_uops); c++) - { - if (decode_buffer.earliest_start[c] == -1) - start_timestamp = last_uop_timestamp; - else - start_timestamp = decode_buffer.earliest_start[c]; - - last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); - if (last_uop_timestamp > uop_timestamp) - uop_timestamp = last_uop_timestamp; - } - - /*Calculate opseq completion time. Since opseqs complete in order, it - must be after the last completion.*/ - if (uop_timestamp <= last_complete_timestamp) - last_complete_timestamp = last_complete_timestamp + 1; + /*Submit uops to execution units, and determine the latest completion time*/ + for (int c = 0; c < (decode_buffer.nr_uops); c++) { + if (decode_buffer.earliest_start[c] == -1) + start_timestamp = last_uop_timestamp; else - last_complete_timestamp = uop_timestamp; + start_timestamp = decode_buffer.earliest_start[c]; - /*Advance to next opseq in buffer*/ - opseq_completion_timestamp[next_opseq] = last_complete_timestamp; - next_opseq++; - if (next_opseq == NR_OPSEQS) - next_opseq = 0; + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } - decode_timestamp++; - decode_buffer.nr_uops = 0; + /*Calculate opseq completion time. Since opseqs complete in order, it + must be after the last completion.*/ + if (uop_timestamp <= last_complete_timestamp) + last_complete_timestamp = last_complete_timestamp + 1; + else + last_complete_timestamp = uop_timestamp; + + /*Advance to next opseq in buffer*/ + opseq_completion_timestamp[next_opseq] = last_complete_timestamp; + next_opseq++; + if (next_opseq == NR_OPSEQS) + next_opseq = 0; + + decode_timestamp++; + decode_buffer.nr_uops = 0; } /*The instruction is only of interest here if it's longer than 7 bytes, as that's the limit on P6 simple decoding*/ -static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) +static int +codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) { - int len = prefixes + 1; /*Opcode*/ - if (deps & MODRM) - { - len++; /*ModR/M*/ - if (deps & HAS_IMM8) - len++; - if (deps & HAS_IMM1632) - len += (op_32 & 0x100) ? 4 : 2; + int len = prefixes + 1; /*Opcode*/ + if (deps & MODRM) { + len++; /*ModR/M*/ + if (deps & HAS_IMM8) + len++; + if (deps & HAS_IMM1632) + len += (op_32 & 0x100) ? 4 : 2; - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /* Has SIB*/ - len++; - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0x700) == 0x500) - len += 4; - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0xc7) == 0x05) - len += 4; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 2; - else if ((fetchdat & 0xc7) == 0x06) - len += 2; - } + if (op_32 & 0x200) { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) { + /* Has SIB*/ + len++; + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0x700) == 0x500) + len += 4; + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0xc7) == 0x05) + len += 4; + } + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 2; + else if ((fetchdat & 0xc7) == 0x06) + len += 2; } + } - return len; + return len; } -static void decode_instruction(const macro_op_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) +static void +decode_instruction(const macro_op_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) { - uint32_t regmask_required; - uint32_t regmask_modified; - int c; - int d = 0; /*Complex decoder uOPs*/ - int earliest_start = 0; - decode_type_t decode_type = ins->decode_type; - int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); + uint32_t regmask_required; + uint32_t regmask_modified; + int c; + int d = 0; /*Complex decoder uOPs*/ + int earliest_start = 0; + decode_type_t decode_type = ins->decode_type; + int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); - /*Generate input register mask, and determine the earliest time this - instruction can start. This is not accurate, as this is calculated per - x86 instruction when it should be handled per uop*/ - regmask_required = get_dstdep_mask(deps, fetchdat, bit8); - regmask_required |= get_addr_regmask(deps, fetchdat, op_32); - for (c = 0; c < 8; c++) - { - if (regmask_required & (1 << c)) - { - if (reg_available_timestamp[c] > decode_timestamp) - earliest_start = reg_available_timestamp[c]; - } + /*Generate input register mask, and determine the earliest time this + instruction can start. This is not accurate, as this is calculated per + x86 instruction when it should be handled per uop*/ + regmask_required = get_dstdep_mask(deps, fetchdat, bit8); + regmask_required |= get_addr_regmask(deps, fetchdat, op_32); + for (c = 0; c < 8; c++) { + if (regmask_required & (1 << c)) { + if (reg_available_timestamp[c] > decode_timestamp) + earliest_start = reg_available_timestamp[c]; } - if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) - earliest_start = fpu_st_timestamp[0]; - if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) - earliest_start = fpu_st_timestamp[1]; - if ((deps & FPU_RW_STREG)) - { - int reg = fetchdat & 7; + } + if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) + earliest_start = fpu_st_timestamp[0]; + if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) + earliest_start = fpu_st_timestamp[1]; + if (deps & FPU_RW_STREG) { + int reg = fetchdat & 7; - if (fpu_st_timestamp[reg] > decode_timestamp) - earliest_start = fpu_st_timestamp[reg]; - } + if (fpu_st_timestamp[reg] > decode_timestamp) + earliest_start = fpu_st_timestamp[reg]; + } - /*Simple decoders are limited to 7 bytes & 1 uOP*/ - if ((decode_type == DECODE_SIMPLE && instr_length > 7) || (decode_type == DECODE_SIMPLE && ins->nr_uops > 1)) - decode_type = DECODE_COMPLEX; + /*Simple decoders are limited to 7 bytes & 1 uOP*/ + if ((decode_type == DECODE_SIMPLE && instr_length > 7) || (decode_type == DECODE_SIMPLE && ins->nr_uops > 1)) + decode_type = DECODE_COMPLEX; - switch (decode_type) - { - case DECODE_SIMPLE: - if (decode_buffer.nr_uops - d == 2) - { - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - decode_buffer.nr_uops = 3; - decode_flush_p6(); - } - else if (decode_buffer.nr_uops - d == 1) - { - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - decode_buffer.nr_uops = 2+d; - if (d) - decode_flush_p6(); - } - else if (decode_buffer.nr_uops) - { - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - decode_buffer.nr_uops = 1+d; - } - else - { - decode_buffer.nr_uops = 1; - decode_buffer.uops[0] = &ins->uop[0]; - decode_buffer.earliest_start[0] = earliest_start; - } - break; - - case DECODE_COMPLEX: - if (decode_buffer.nr_uops) - decode_flush_p6(); /*The 4-1-1 arrangement implies that a complex ins. can't be decoded after a simple one*/ - - d = 0; - - for (c = 0; c < ins->nr_uops; c++) - { - decode_buffer.uops[d] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[d] = earliest_start; - else - decode_buffer.earliest_start[d] = -1; - d++; - - if ((d == 3) && (ins->nr_uops > 4)) /*Ins. with >4 uOPs require the use of special units only present on 3 translate PLAs*/ - { - d = 0; - decode_buffer.nr_uops = 3; - decode_flush_p6(); /*The other two decoders are halted to preserve in-order issue*/ - } - } + switch (decode_type) { + case DECODE_SIMPLE: + if (decode_buffer.nr_uops - d == 2) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + decode_buffer.nr_uops = 3; + decode_flush_p6(); + } else if (decode_buffer.nr_uops - d == 1) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + decode_buffer.nr_uops = 2 + d; if (d) - { - decode_buffer.nr_uops = d; + decode_flush_p6(); + } else if (decode_buffer.nr_uops) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + decode_buffer.nr_uops = 1 + d; + } else { + decode_buffer.nr_uops = 1; + decode_buffer.uops[0] = &ins->uop[0]; + decode_buffer.earliest_start[0] = earliest_start; + } + break; + + case DECODE_COMPLEX: + if (decode_buffer.nr_uops) + decode_flush_p6(); /*The 4-1-1 arrangement implies that a complex ins. can't be decoded after a simple one*/ + + d = 0; + + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[d] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[d] = earliest_start; + else + decode_buffer.earliest_start[d] = -1; + d++; + + if ((d == 3) && (ins->nr_uops > 4)) { /*Ins. with >4 uOPs require the use of special units only present on 3 translate PLAs*/ + d = 0; + decode_buffer.nr_uops = 3; + decode_flush_p6(); /*The other two decoders are halted to preserve in-order issue*/ } - break; - } + } + if (d) { + decode_buffer.nr_uops = d; + } + break; + } - /*Update write timestamps for any output registers*/ - regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); - for (c = 0; c < 8; c++) - { - if (regmask_modified & (1 << c)) - reg_available_timestamp[c] = last_complete_timestamp; - } + /*Update write timestamps for any output registers*/ + regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); + for (c = 0; c < 8; c++) { + if (regmask_modified & (1 << c)) + reg_available_timestamp[c] = last_complete_timestamp; + } + if (deps & FPU_POP) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 1]; + fpu_st_timestamp[7] = 0; + } + if (deps & FPU_POP2) { + for (c = 0; c < 6; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 2]; + fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; + } + if (deps & FPU_PUSH) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c + 1] = fpu_st_timestamp[c]; + fpu_st_timestamp[0] = 0; + } + if (deps & FPU_WRITE_ST0) + fpu_st_timestamp[0] = last_complete_timestamp; + if (deps & FPU_WRITE_ST1) + fpu_st_timestamp[1] = last_complete_timestamp; + if (deps & FPU_WRITE_STREG) { + int reg = fetchdat & 7; if (deps & FPU_POP) - { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c+1]; - fpu_st_timestamp[7] = 0; - } - if (deps & FPU_POP2) - { - for (c = 0; c < 6; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c+2]; - fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; - } - if (deps & FPU_PUSH) - { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c+1] = fpu_st_timestamp[c]; - fpu_st_timestamp[0] = 0; - } - if (deps & FPU_WRITE_ST0) - fpu_st_timestamp[0] = last_complete_timestamp; - if (deps & FPU_WRITE_ST1) - fpu_st_timestamp[1] = last_complete_timestamp; - if (deps & FPU_WRITE_STREG) - { - int reg = fetchdat & 7; - if (deps & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps & FPU_WRITE_ST0)) && - !(reg == 1 && (deps & FPU_WRITE_ST1))) - fpu_st_timestamp[reg] = last_complete_timestamp; - } + reg--; + if (reg >= 0 && !(reg == 0 && (deps & FPU_WRITE_ST0)) && !(reg == 1 && (deps & FPU_WRITE_ST1))) + fpu_st_timestamp[reg] = last_complete_timestamp; + } } -void codegen_timing_p6_block_start(void) +void +codegen_timing_p6_block_start(void) { - int c; + int c; - for (c = 0; c < nr_units; c++) - units[c].first_available_cycle = 0; + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = 0; - decode_timestamp = 0; - last_complete_timestamp = 0; + decode_timestamp = 0; + last_complete_timestamp = 0; - for (c = 0; c < NR_OPSEQS; c++) - opseq_completion_timestamp[c] = 0; - next_opseq = 0; + for (c = 0; c < NR_OPSEQS; c++) + opseq_completion_timestamp[c] = 0; + next_opseq = 0; - for (c = 0; c < NR_REGS; c++) - reg_available_timestamp[c] = 0; - for (c = 0; c < 8; c++) - fpu_st_timestamp[c] = 0; + for (c = 0; c < NR_REGS; c++) + reg_available_timestamp[c] = 0; + for (c = 0; c < 8; c++) + fpu_st_timestamp[c] = 0; } -void codegen_timing_p6_start(void) +void +codegen_timing_p6_start(void) { - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - { - units = ppro_units; - nr_units = NR_PPRO_UNITS; - } - else - { - units = p2_units; - nr_units = NR_P2_UNITS; - } - last_prefix = 0; - prefixes = 0; + if (cpu_s->cpu_type == CPU_PENTIUMPRO) { + units = ppro_units; + nr_units = NR_PPRO_UNITS; + } else { + units = p2_units; + nr_units = NR_P2_UNITS; + } + last_prefix = 0; + prefixes = 0; } -void codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) { - if (prefix != 0x0f) - decode_timestamp++; + if (prefix != 0x0f) + decode_timestamp++; - last_prefix = prefix; - prefixes++; + last_prefix = prefix; + prefixes++; } -void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +void +codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) { - const macro_op_t **ins_table; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int old_last_complete_timestamp = last_complete_timestamp; - int bit8 = !(opcode & 1); + const macro_op_t **ins_table; + const uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int old_last_complete_timestamp = last_complete_timestamp; + int bit8 = !(opcode & 1); - switch (last_prefix) - { - case 0x0f: - ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; + switch (last_prefix) { + case 0x0f: + ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; - case 0xd8: - ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; + case 0xd8: + ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + case 0x83: + ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xd0: + case 0xd2: + ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc1: + case 0xd1: + case 0xd3: + ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: - ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: case 0x83: - ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } - case 0xc0: case 0xd0: case 0xd2: - ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; + if (ins_table[opcode]) + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); + else + decode_instruction(&complex_alu1_op, 0, fetchdat, op_32, bit8); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); +} - case 0xc1: case 0xd1: case 0xd3: - ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; - - case 0xf6: - ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - if (ins_table[opcode]) - decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); - else - decode_instruction(&complex_alu1_op, 0, fetchdat, op_32, bit8); +void +codegen_timing_p6_block_end(void) +{ + if (decode_buffer.nr_uops) { + int old_last_complete_timestamp = last_complete_timestamp; + decode_flush_p6(); codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + } } -void codegen_timing_p6_block_end(void) +int +codegen_timing_p6_jump_cycles(void) { - if (decode_buffer.nr_uops) - { - int old_last_complete_timestamp = last_complete_timestamp; - decode_flush_p6(); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); - } + if (decode_buffer.nr_uops) + return 1; + return 0; } -int codegen_timing_p6_jump_cycles(void) -{ - if (decode_buffer.nr_uops) - return 1; - return 0; -} - -codegen_timing_t codegen_timing_p6 = -{ - codegen_timing_p6_start, - codegen_timing_p6_prefix, - codegen_timing_p6_opcode, - codegen_timing_p6_block_start, - codegen_timing_p6_block_end, - codegen_timing_p6_jump_cycles +codegen_timing_t codegen_timing_p6 = { + codegen_timing_p6_start, + codegen_timing_p6_prefix, + codegen_timing_p6_opcode, + codegen_timing_p6_block_start, + codegen_timing_p6_block_end, + codegen_timing_p6_jump_cycles }; diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c index 232455f6d..3951acc94 100644 --- a/src/cpu/codegen_timing_pentium.c +++ b/src/cpu/codegen_timing_pentium.c @@ -14,8 +14,11 @@ #include #include #include <86box/86box.h> -#include <86box/mem.h> #include "cpu.h" +#include <86box/mem.h> +#include <86box/plat_unused.h> +#include + #include "x86.h" #include "x86_ops.h" #include "x87.h" @@ -23,46 +26,45 @@ #include "codegen_ops.h" #include "codegen_timing_common.h" - /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ -#define CYCLES_HAS_MULTI (1 << 28) +#define CYCLES_HAS_MULTI (1 << 28) #define CYCLES_MULTI(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) /*Instruction lasts given number of cycles. Does not pair*/ #define CYCLES(c) (c | PAIR_NP) - -static int pair_timings[4][4] = -{ -/* Reg RM RMW Branch*/ -/*Reg*/ {1, 2, 3, 2}, -/*RM*/ {2, 2, 3, 3}, -/*RMW*/ {3, 4, 5, 4}, -/*Branch*/ {-1, -1, -1, -1} +static int pair_timings[4][4] = { + /* Reg RM RMW Branch*/ + /*Reg*/ {1, 2, 3, 2 }, + /*RM*/ + { 2, 2, 3, 3 }, + /*RMW*/ + { 3, 4, 5, 4 }, + /*Branch*/ + { -1, -1, -1, -1} }; /*Instruction follows either register timing, read-modify, or read-modify-write. May be pairable*/ -#define CYCLES_REG (0ull << 0) -#define CYCLES_RM (1ull << 0) -#define CYCLES_RMW (2ull << 0) +#define CYCLES_REG (0ull << 0) +#define CYCLES_RM (1ull << 0) +#define CYCLES_RMW (2ull << 0) #define CYCLES_BRANCH (3ull << 0) /*Instruction has immediate data. Can only be used with PAIR_U/PAIR_V/PAIR_UV*/ -#define CYCLES_HASIMM (3ull << 2) +#define CYCLES_HASIMM (3ull << 2) #define CYCLES_IMM8 (1ull << 2) #define CYCLES_IMM1632 (2ull << 2) -#define CYCLES_MASK ((1ull << 7) - 1) - +#define CYCLES_MASK ((1ull << 7) - 1) /*Instruction does not pair*/ #define PAIR_NP (0ull << 29) /*Instruction pairs in U pipe only*/ -#define PAIR_U (1ull << 29) +#define PAIR_U (1ull << 29) /*Instruction pairs in V pipe only*/ -#define PAIR_V (2ull << 29) +#define PAIR_V (2ull << 29) /*Instruction pairs in both U and V pipes*/ #define PAIR_UV (3ull << 29) /*Instruction pairs in U pipe only and only with FXCH*/ @@ -70,36 +72,34 @@ static int pair_timings[4][4] = /*Instruction is FXCH and only pairs in V pipe with FX pairable instruction*/ #define PAIR_FXCH (6ull << 29) -#define PAIR_FPU (4ull << 29) +#define PAIR_FPU (4ull << 29) #define PAIR_MASK (7ull << 29) - /*comp_time = cycles until instruction complete i_overlap = cycles that overlap with integer f_overlap = cycles that overlap with subsequent FPU*/ -#define FPU_CYCLES(comp_time, i_overlap, f_overlap) ((uint64_t)comp_time) | ((uint64_t)i_overlap << 41) | ((uint64_t)f_overlap << 49) | PAIR_FPU +#define FPU_CYCLES(comp_time, i_overlap, f_overlap) ((uint64_t) comp_time) | ((uint64_t) i_overlap << 41) | ((uint64_t) f_overlap << 49) | PAIR_FPU -#define FPU_COMP_TIME(timing) (timing & 0xff) -#define FPU_I_OVERLAP(timing) ((timing >> 41) & 0xff) -#define FPU_F_OVERLAP(timing) ((timing >> 49) & 0xff) +#define FPU_COMP_TIME(timing) (timing & 0xff) +#define FPU_I_OVERLAP(timing) ((timing >> 41) & 0xff) +#define FPU_F_OVERLAP(timing) ((timing >> 49) & 0xff) -#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) +#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) -#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) +#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) -#define FPU_RESULT_LATENCY(timing) ((timing >> 41) & 0xff) +#define FPU_RESULT_LATENCY(timing) ((timing >> 41) & 0xff) +#define INVALID 0 -#define INVALID 0 - -static int u_pipe_full; -static uint32_t u_pipe_opcode; +static int u_pipe_full; +static uint32_t u_pipe_opcode; static uint64_t *u_pipe_timings; -static uint32_t u_pipe_op_32; -static uint32_t u_pipe_regmask; -static uint32_t u_pipe_fetchdat; -static int u_pipe_decode_delay_offset; +static uint32_t u_pipe_op_32; +static uint32_t u_pipe_regmask; +static uint32_t u_pipe_fetchdat; +static int u_pipe_decode_delay_offset; static uint64_t *u_pipe_deps; static uint32_t regmask_modified; @@ -109,8 +109,8 @@ static uint32_t addr_regmask; static int fpu_latency; static int fpu_st_latency[8]; -static uint64_t opcode_timings[256] = -{ +static uint64_t opcode_timings[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, /* ADD ADD PUSH ES POP ES*/ @@ -243,10 +243,11 @@ static uint64_t opcode_timings[256] = PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), /* CLD STD INCDEC*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_UV | CYCLES_RMW, INVALID + // clang-format on }; -static uint64_t opcode_timings_mod3[256] = -{ +static uint64_t opcode_timings_mod3[256] = { + // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, /* ADD ADD PUSH ES POP ES*/ @@ -380,10 +381,11 @@ static uint64_t opcode_timings_mod3[256] = PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), /* CLD STD INCDEC*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_UV | CYCLES_REG, INVALID + // clang-format on }; -static uint64_t opcode_timings_0f[256] = -{ +static uint64_t opcode_timings_0f[256] = { + // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, @@ -463,9 +465,10 @@ static uint64_t opcode_timings_0f[256] = INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, + // clang-format on }; -static uint64_t opcode_timings_0f_mod3[256] = -{ +static uint64_t opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, @@ -545,86 +548,98 @@ static uint64_t opcode_timings_0f_mod3[256] = INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, + // clang-format on }; -static uint64_t opcode_timings_shift[8] = -{ +static uint64_t opcode_timings_shift[8] = { + // clang-format off PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, + // clang-format on }; -static uint64_t opcode_timings_shift_mod3[8] = -{ +static uint64_t opcode_timings_shift_mod3[8] = { + // clang-format off PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, + // clang-format on }; -static uint64_t opcode_timings_f6[8] = -{ +static uint64_t opcode_timings_f6[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) + // clang-format on }; -static uint64_t opcode_timings_f6_mod3[8] = -{ +static uint64_t opcode_timings_f6_mod3[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) + // clang-format on }; -static uint64_t opcode_timings_f7[8] = -{ +static uint64_t opcode_timings_f7[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) + // clang-format on }; -static uint64_t opcode_timings_f7_mod3[8] = -{ +static uint64_t opcode_timings_f7_mod3[8] = { + // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) + // clang-format on }; -static uint64_t opcode_timings_ff[8] = -{ +static uint64_t opcode_timings_ff[8] = { + // clang-format off /* INC DEC CALL CALL far*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), /* JMP JMP far PUSH*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID + // clang-format on }; -static uint64_t opcode_timings_ff_mod3[8] = -{ +static uint64_t opcode_timings_ff_mod3[8] = { + // clang-format off /* INC DEC CALL CALL far*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), /* JMP JMP far PUSH*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID + // clang-format on }; -static uint64_t opcode_timings_d8[8] = -{ +static uint64_t opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), /* FSUBs FSUBRs FDIVs FDIVRs*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_d8_mod3[8] = -{ +static uint64_t opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), /* FSUB FSUBR FDIV FDIVR*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_d9[8] = -{ +static uint64_t opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), /* FLDENV FLDCW FSTENV FSTCW*/ PAIR_NP | FPU_CYCLES(32,0,0), PAIR_NP | FPU_CYCLES(8,0,0), PAIR_NP | FPU_CYCLES(48,0,0), PAIR_NP | FPU_CYCLES(2,0,0) + // clang-format on }; -static uint64_t opcode_timings_d9_mod3[64] = -{ +static uint64_t opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), @@ -653,32 +668,35 @@ static uint64_t opcode_timings_d9_mod3[64] = PAIR_NP | FPU_CYCLES(64,2,2), INVALID, PAIR_NP | FPU_CYCLES(70,69,2), PAIR_NP | FPU_CYCLES(89,2,2), /* opFRNDINT opFSCALE opFSIN opFCOS*/ PAIR_NP | FPU_CYCLES(9,0,0), PAIR_NP | FPU_CYCLES(20,5,0), PAIR_NP | FPU_CYCLES(65,2,2), PAIR_NP | FPU_CYCLES(65,2,2) + // clang-format on }; -static uint64_t opcode_timings_da[8] = -{ +static uint64_t opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), /* FISUBl FISUBRl FIDIVl FIDIVRl*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) + // clang-format on }; -static uint64_t opcode_timings_da_mod3[8] = -{ +static uint64_t opcode_timings_da_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ INVALID, PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID + // clang-format on }; - -static uint64_t opcode_timings_db[8] = -{ +static uint64_t opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), /* FLDe FSTPe*/ INVALID, PAIR_NP | FPU_CYCLES(3,0,0), INVALID, PAIR_NP | FPU_CYCLES(3,0,0) + // clang-format on }; -static uint64_t opcode_timings_db_mod3[64] = -{ +static uint64_t opcode_timings_db_mod3[64] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -704,616 +722,606 @@ static uint64_t opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static uint64_t opcode_timings_dc[8] = -{ +static uint64_t opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), /* FSUBd FSUBRd FDIVd FDIVRd*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_dc_mod3[8] = -{ +static uint64_t opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_dd[8] = -{ +static uint64_t opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), /* FRSTOR FSAVE FSTSW*/ PAIR_NP | FPU_CYCLES(70,0,0), INVALID, PAIR_NP | FPU_CYCLES(127,0,0), PAIR_NP | FPU_CYCLES(6,0,0) + // clang-format on }; -static uint64_t opcode_timings_dd_mod3[8] = -{ +static uint64_t opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ PAIR_NP | FPU_CYCLES(2,0,0), INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), /* FUCOM FUCOMP*/ PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID + // clang-format on }; -static uint64_t opcode_timings_de[8] = -{ +static uint64_t opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), /* FISUBw FISUBRw FIDIVw FIDIVRw*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) + // clang-format on }; -static uint64_t opcode_timings_de_mod3[8] = -{ +static uint64_t opcode_timings_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, PAIR_FX | FPU_CYCLES(1,0,0), /* FSUBP FSUBRP FDIVP FDIVRP*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) + // clang-format on }; -static uint64_t opcode_timings_df[8] = -{ +static uint64_t opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), /* FILDiq FBSTP FISTPiq*/ INVALID, PAIR_NP | FPU_CYCLES(3,2,2), PAIR_NP | FPU_CYCLES(148,0,0), PAIR_NP | FPU_CYCLES(6,0,0) + // clang-format on }; -static uint64_t opcode_timings_df_mod3[8] = -{ +static uint64_t opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ PAIR_NP | FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID + // clang-format on }; -static uint64_t opcode_timings_81[8] = -{ +static uint64_t opcode_timings_81[8] = { + // clang-format off PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | CYCLES_IMM1632 + // clang-format on }; -static uint64_t opcode_timings_81_mod3[8] = -{ +static uint64_t opcode_timings_81_mod3[8] = { + // clang-format off PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG + // clang-format on }; -static uint64_t opcode_timings_8x[8] = -{ +static uint64_t opcode_timings_8x[8] = { + // clang-format off PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RM | CYCLES_IMM8 + // clang-format on }; -static uint64_t opcode_timings_8x_mod3[8] = -{ +static uint64_t opcode_timings_8x_mod3[8] = { + // clang-format off PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG + // clang-format on }; -static int decode_delay, decode_delay_offset; +static int decode_delay; +static int decode_delay_offset; static uint8_t last_prefix; -static int prefixes; +static int prefixes; -static inline int COUNT(uint64_t timings, uint64_t deps, int op_32) +static inline int +COUNT(uint64_t timings, uint64_t deps, int op_32) { - if ((timings & PAIR_FPU) && !(deps & FPU_FXCH)) - return FPU_I_LATENCY(timings); - if (timings & CYCLES_HAS_MULTI) - { - if (op_32 & 0x100) - return ((uintptr_t)timings >> 8) & 0xff; - return (uintptr_t)timings & 0xff; - } - if (!(timings & PAIR_MASK)) - return timings & 0xffff; - if ((timings & PAIR_MASK) == PAIR_FX) - return timings & 0xffff; - if ((timings & PAIR_MASK) == PAIR_FXCH) - return timings & 0xffff; - if ((timings & PAIR_UV) && !(timings & PAIR_FPU)) - timings &= 3; - switch (timings & CYCLES_MASK) - { - case CYCLES_REG: + if ((timings & PAIR_FPU) && !(deps & FPU_FXCH)) + return FPU_I_LATENCY(timings); + if (timings & CYCLES_HAS_MULTI) { + if (op_32 & 0x100) + return ((uintptr_t) timings >> 8) & 0xff; + return (uintptr_t) timings & 0xff; + } + if (!(timings & PAIR_MASK)) + return timings & 0xffff; + if ((timings & PAIR_MASK) == PAIR_FX) + return timings & 0xffff; + if ((timings & PAIR_MASK) == PAIR_FXCH) + return timings & 0xffff; + if ((timings & PAIR_UV) && !(timings & PAIR_FPU)) + timings &= 3; + switch (timings & CYCLES_MASK) { + case CYCLES_REG: + return 1; + case CYCLES_RM: + return 2; + case CYCLES_RMW: + return 3; + case CYCLES_BRANCH: + return cpu_has_feature(CPU_FEATURE_MMX) ? 1 : 2; + } + + fatal("Illegal COUNT %016" PRIu64 "\n", timings); + + return timings; +} + +static int +codegen_fpu_latencies(uint64_t deps, int reg) +{ + int latency = fpu_latency; + + if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) + latency = fpu_st_latency[0]; + if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) + latency = fpu_st_latency[1]; + if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) + latency = fpu_st_latency[reg]; + + return latency; +} + +#define SUB_AND_CLAMP(latency, count) \ + latency -= count; \ + if (latency < 0) \ + latency = 0 + +static void +codegen_fpu_latency_clock(int count) +{ + SUB_AND_CLAMP(fpu_latency, count); + SUB_AND_CLAMP(fpu_st_latency[0], count); + SUB_AND_CLAMP(fpu_st_latency[1], count); + SUB_AND_CLAMP(fpu_st_latency[2], count); + SUB_AND_CLAMP(fpu_st_latency[3], count); + SUB_AND_CLAMP(fpu_st_latency[4], count); + SUB_AND_CLAMP(fpu_st_latency[5], count); + SUB_AND_CLAMP(fpu_st_latency[6], count); + SUB_AND_CLAMP(fpu_st_latency[7], count); +} + +static inline int +codegen_timing_has_displacement(uint32_t fetchdat, int op_32) +{ + if (op_32 & 0x200) { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) { + /*Has SIB*/ + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0x700) == 0x500) + return 1; + } else { + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x05) return 1; - case CYCLES_RM: - return 2; - case CYCLES_RMW: - return 3; - case CYCLES_BRANCH: - return cpu_has_feature(CPU_FEATURE_MMX) ? 1 : 2; } - - fatal("Illegal COUNT %016llx\n", timings); - - return timings; -} - -static int codegen_fpu_latencies(uint64_t deps, int reg) -{ - int latency = fpu_latency; - - if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) - latency = fpu_st_latency[0]; - if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) - latency = fpu_st_latency[1]; - if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) - latency = fpu_st_latency[reg]; - - return latency; -} - -#define SUB_AND_CLAMP(latency, count) \ - latency -= count; \ - if (latency < 0) \ - latency = 0 - -static void codegen_fpu_latency_clock(int count) -{ - SUB_AND_CLAMP(fpu_latency, count); - SUB_AND_CLAMP(fpu_st_latency[0], count); - SUB_AND_CLAMP(fpu_st_latency[1], count); - SUB_AND_CLAMP(fpu_st_latency[2], count); - SUB_AND_CLAMP(fpu_st_latency[3], count); - SUB_AND_CLAMP(fpu_st_latency[4], count); - SUB_AND_CLAMP(fpu_st_latency[5], count); - SUB_AND_CLAMP(fpu_st_latency[6], count); - SUB_AND_CLAMP(fpu_st_latency[7], count); -} - -static inline int codegen_timing_has_displacement(uint32_t fetchdat, int op_32) -{ - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /*Has SIB*/ - if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0x700) == 0x500) - return 1; - } - else - { - if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x05) - return 1; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x06) - return 1; - } - return 0; + } else { + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x06) + return 1; + } + return 0; } /*The instruction is only of interest here if it's longer than 7 bytes, as that's the limit on Pentium MMX parallel decoding*/ -static inline int codegen_timing_instr_length(uint64_t timing, uint32_t fetchdat, int op_32) +static inline int +codegen_timing_instr_length(uint64_t timing, uint32_t fetchdat, int op_32) { - int len = prefixes; - if ((timing & CYCLES_MASK) == CYCLES_RM || (timing & CYCLES_MASK) == CYCLES_RMW) - { - len += 2; /*Opcode + ModR/M*/ - if ((timing & CYCLES_HASIMM) == CYCLES_IMM8) - len++; - if ((timing & CYCLES_HASIMM) == CYCLES_IMM1632) - len += (op_32 & 0x100) ? 4 : 2; + int len = prefixes; + if ((timing & CYCLES_MASK) == CYCLES_RM || (timing & CYCLES_MASK) == CYCLES_RMW) { + len += 2; /*Opcode + ModR/M*/ + if ((timing & CYCLES_HASIMM) == CYCLES_IMM8) + len++; + if ((timing & CYCLES_HASIMM) == CYCLES_IMM1632) + len += (op_32 & 0x100) ? 4 : 2; - if (op_32 & 0x200) - { - if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) - { - /* Has SIB*/ - len++; - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0x700) == 0x500) - len += 4; - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 4; - else if ((fetchdat & 0xc7) == 0x05) - len += 4; - } - } - else - { - if ((fetchdat & 0xc0) == 0x40) - len++; - else if ((fetchdat & 0xc0) == 0x80) - len += 2; - else if ((fetchdat & 0xc7) == 0x06) - len += 2; - } + if (op_32 & 0x200) { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) { + /* Has SIB*/ + len++; + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0x700) == 0x500) + len += 4; + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0xc7) == 0x05) + len += 4; + } + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 2; + else if ((fetchdat & 0xc7) == 0x06) + len += 2; } + } - return len; + return len; } -void codegen_timing_pentium_block_start(void) +void +codegen_timing_pentium_block_start(void) { - u_pipe_full = decode_delay = decode_delay_offset = 0; + u_pipe_full = decode_delay = decode_delay_offset = 0; } -void codegen_timing_pentium_start(void) +void +codegen_timing_pentium_start(void) { - last_prefix = 0; - prefixes = 0; + last_prefix = 0; + prefixes = 0; } -void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) { - prefixes++; - if ((prefix & 0xf8) == 0xd8) - { - last_prefix = prefix; - return; - } - if (cpu_has_feature(CPU_FEATURE_MMX) && prefix == 0x0f) - { - /*On Pentium MMX 0fh prefix is 'free'*/ - last_prefix = prefix; - return; - } - if (cpu_has_feature(CPU_FEATURE_MMX) && (prefix == 0x66 || prefix == 0x67)) - { - /*On Pentium MMX 66h and 67h prefixes take 2 clocks*/ - decode_delay_offset += 2; - last_prefix = prefix; - return; - } - if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) - { - /*On Pentium 0fh prefix is 'free' when used on conditional jumps*/ - last_prefix = prefix; - return; - } - /*On Pentium all prefixes take 1 cycle to decode. Decode may be shadowed - by execution of previous instructions*/ - decode_delay_offset++; + prefixes++; + if ((prefix & 0xf8) == 0xd8) { last_prefix = prefix; + return; + } + if (cpu_has_feature(CPU_FEATURE_MMX) && prefix == 0x0f) { + /*On Pentium MMX 0fh prefix is 'free'*/ + last_prefix = prefix; + return; + } + if (cpu_has_feature(CPU_FEATURE_MMX) && (prefix == 0x66 || prefix == 0x67)) { + /*On Pentium MMX 66h and 67h prefixes take 2 clocks*/ + decode_delay_offset += 2; + last_prefix = prefix; + return; + } + if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) { + /*On Pentium 0fh prefix is 'free' when used on conditional jumps*/ + last_prefix = prefix; + return; + } + /*On Pentium all prefixes take 1 cycle to decode. Decode may be shadowed + by execution of previous instructions*/ + decode_delay_offset++; + last_prefix = prefix; } -static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +static int +check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) { - uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); - /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not - cause AGIs with each other, but do with instructions that use it explicitly*/ - if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) - addr_regmask |= (1 << REG_ESP); + /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not + cause AGIs with each other, but do with instructions that use it explicitly*/ + if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) + addr_regmask |= (1 << REG_ESP); - return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; + return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; } -static void codegen_instruction(uint64_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) +static void +codegen_instruction(uint64_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) { - int instr_cycles, latency = 0; + int instr_cycles; + int latency = 0; - if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) - instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); - else - { -/* if (timings[opcode] & FPU_WRITE_ST0) - fatal("FPU_WRITE_ST0\n"); - if (timings[opcode] & FPU_WRITE_ST1) - fatal("FPU_WRITE_ST1\n"); - if (timings[opcode] & FPU_WRITE_STREG) - fatal("FPU_WRITE_STREG\n");*/ - instr_cycles = 0; - } + if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); + else { +#if 0 + if (timings[opcode] & FPU_WRITE_ST0) + fatal("FPU_WRITE_ST0\n"); + if (timings[opcode] & FPU_WRITE_ST1) + fatal("FPU_WRITE_ST1\n"); + if (timings[opcode] & FPU_WRITE_STREG) + fatal("FPU_WRITE_STREG\n");*/ +#endif + instr_cycles = 0; + } - if ((decode_delay + decode_delay_offset) > 0) - codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); - else - codegen_fpu_latency_clock(instr_cycles); - instr_cycles += COUNT(timings[opcode], deps[opcode], op_32); - instr_cycles += exec_delay; - if ((decode_delay + decode_delay_offset) > 0) - codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; - else - codegen_block_cycles += instr_cycles; + if ((decode_delay + decode_delay_offset) > 0) + codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); + else + codegen_fpu_latency_clock(instr_cycles); + instr_cycles += COUNT(timings[opcode], deps[opcode], op_32); + instr_cycles += exec_delay; + if ((decode_delay + decode_delay_offset) > 0) + codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; + else + codegen_block_cycles += instr_cycles; - decode_delay = (-instr_cycles) + 1; + decode_delay = (-instr_cycles) + 1; + if (deps[opcode] & FPU_POP) { + for (uint8_t c = 0; c < 7; c++) + fpu_st_latency[c] = fpu_st_latency[c + 1]; + fpu_st_latency[7] = 0; + } + if (deps[opcode] & FPU_POP2) { + for (uint8_t c = 0; c < 6; c++) + fpu_st_latency[c] = fpu_st_latency[c + 2]; + fpu_st_latency[6] = fpu_st_latency[7] = 0; + } + if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) { + fpu_latency = FPU_F_LATENCY(timings[opcode]); + } + + if (deps[opcode] & FPU_PUSH) { + for (uint8_t c = 0; c < 7; c++) + fpu_st_latency[c + 1] = fpu_st_latency[c]; + fpu_st_latency[0] = 0; + } + if (deps[opcode] & FPU_WRITE_ST0) { +#if 0 + if (fpu_st_latency[0]) + fatal("Bad latency ST0\n");*/ +#endif + fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_ST1) { +#if 0 + if (fpu_st_latency[1]) + fatal("Bad latency ST1\n");*/ +#endif + fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_STREG) { + int reg = fetchdat & 7; if (deps[opcode] & FPU_POP) - { - int c; - - for (c = 0; c < 7; c++) - fpu_st_latency[c] = fpu_st_latency[c+1]; - fpu_st_latency[7] = 0; - } - if (deps[opcode] & FPU_POP2) - { - int c; - - for (c = 0; c < 6; c++) - fpu_st_latency[c] = fpu_st_latency[c+2]; - fpu_st_latency[6] = fpu_st_latency[7] = 0; - } - if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) - { - fpu_latency = FPU_F_LATENCY(timings[opcode]); - } - - if (deps[opcode] & FPU_PUSH) - { - int c; - - for (c = 0; c < 7; c++) - fpu_st_latency[c+1] = fpu_st_latency[c]; - fpu_st_latency[0] = 0; - } - if (deps[opcode] & FPU_WRITE_ST0) - { -/* if (fpu_st_latency[0]) - fatal("Bad latency ST0\n");*/ - fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_ST1) - { -/* if (fpu_st_latency[1]) - fatal("Bad latency ST1\n");*/ - fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_STREG) - { - int reg = fetchdat & 7; - if (deps[opcode] & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && - !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) - { - fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); - } + reg--; + if (reg >= 0 && !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) { + fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); } + } } -void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +void +codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) { - uint64_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - int agi_stall = 0; + uint64_t *timings; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); + int agi_stall = 0; - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + case 0xd0: + case 0xd1: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } - case 0xc0: case 0xc1: case 0xd0: case 0xd1: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; + if (u_pipe_full) { + uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; - opcode = (fetchdat >> 3) & 7; - break; + if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && (timings[opcode] & PAIR_MASK) != PAIR_FXCH) + goto nopair; - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; + if ((timings[opcode] & PAIR_MASK) == PAIR_FXCH && (u_pipe_timings[u_pipe_opcode] & PAIR_MASK) != PAIR_FX) + goto nopair; - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } + if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && (timings[opcode] & PAIR_MASK) == PAIR_FXCH) { + int temp; - if (u_pipe_full) - { - uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - - if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && - (timings[opcode] & PAIR_MASK) != PAIR_FXCH) - goto nopair; - - if ((timings[opcode] & PAIR_MASK) == PAIR_FXCH && - (u_pipe_timings[u_pipe_opcode] & PAIR_MASK) != PAIR_FX) - goto nopair; - - if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && - (timings[opcode] & PAIR_MASK) == PAIR_FXCH) - { - int temp; - - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - - temp = fpu_st_latency[fetchdat & 7]; - fpu_st_latency[fetchdat & 7] = fpu_st_latency[0]; - fpu_st_latency[0] = temp; - - u_pipe_full = 0; - decode_delay_offset = 0; - regmask_modified = u_pipe_regmask; - addr_regmask = 0; - return; - } - - if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && (decode_delay+decode_delay_offset+u_pipe_decode_delay_offset) <= 0) - { - int has_displacement; - - if (timings[opcode] & CYCLES_HASIMM) - has_displacement = codegen_timing_has_displacement(fetchdat, op_32); - else - has_displacement = 0; - - if (!has_displacement && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) - { - int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK; - int t2 = timings[opcode] & CYCLES_MASK; - int t_pair; - uint64_t temp_timing; - uint64_t temp_deps = 0; - - if (!(u_pipe_timings[u_pipe_opcode] & PAIR_FPU)) - t1 &= 3; - if (!(timings[opcode] & PAIR_FPU)) - t2 &= 3; - - if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH) - fatal("Pair out of range\n"); - - t_pair = pair_timings[t1][t2]; - if (t_pair < 1) - fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); - - /*Instruction can pair with previous*/ - temp_timing = t_pair; - if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(&temp_timing, &temp_deps, 0, 0, 0, 0, agi_stall); - u_pipe_full = 0; - decode_delay_offset = 0; - - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; - addr_regmask = 0; - return; - } - } -nopair: - /*Instruction can not pair with previous*/ - /*Run previous now*/ - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - u_pipe_full = 0; - regmask_modified = u_pipe_regmask; - addr_regmask = 0; - } - - if ((timings[opcode] & PAIR_U) && (decode_delay + decode_delay_offset) <= 0) - { - int has_displacement; - - if (timings[opcode] & CYCLES_HASIMM) - has_displacement = codegen_timing_has_displacement(fetchdat, op_32); - else - has_displacement = 0; - - if ((!has_displacement || cpu_has_feature(CPU_FEATURE_MMX)) && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) - { - /*Instruction might pair with next*/ - u_pipe_full = 1; - u_pipe_opcode = opcode; - u_pipe_timings = timings; - u_pipe_op_32 = op_32; - u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); - u_pipe_fetchdat = fetchdat; - u_pipe_decode_delay_offset = decode_delay_offset; - u_pipe_deps = deps; - decode_delay_offset = 0; - return; - } - } - /*Instruction can not pair and must run now*/ - if (check_agi(deps, opcode, fetchdat, op_32)) + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) agi_stall = 1; - codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); - decode_delay_offset = 0; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); - addr_regmask = 0; -} -void codegen_timing_pentium_block_end(void) -{ - if (u_pipe_full) - { - /*Run previous now*/ - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - codegen_block_cycles++; - codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_deps[u_pipe_opcode], u_pipe_op_32) + decode_delay + decode_delay_offset; - u_pipe_full = 0; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); + + temp = fpu_st_latency[fetchdat & 7]; + fpu_st_latency[fetchdat & 7] = fpu_st_latency[0]; + fpu_st_latency[0] = temp; + + u_pipe_full = 0; + decode_delay_offset = 0; + regmask_modified = u_pipe_regmask; + addr_regmask = 0; + return; } + + if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && (decode_delay + decode_delay_offset + u_pipe_decode_delay_offset) <= 0) { + int has_displacement; + + if (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; + + if (!has_displacement && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) { + int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK; + int t2 = timings[opcode] & CYCLES_MASK; + int t_pair; + uint64_t temp_timing; + uint64_t temp_deps = 0; + + if (!(u_pipe_timings[u_pipe_opcode] & PAIR_FPU)) + t1 &= 3; + if (!(timings[opcode] & PAIR_FPU)) + t2 &= 3; + + if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH) + fatal("Pair out of range\n"); + + t_pair = pair_timings[t1][t2]; + if (t_pair < 1) + fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); + + /*Instruction can pair with previous*/ + temp_timing = t_pair; + if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(&temp_timing, &temp_deps, 0, 0, 0, 0, agi_stall); + u_pipe_full = 0; + decode_delay_offset = 0; + + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; + addr_regmask = 0; + return; + } + } +nopair: + /*Instruction can not pair with previous*/ + /*Run previous now*/ + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); + u_pipe_full = 0; + regmask_modified = u_pipe_regmask; + addr_regmask = 0; + } + + if ((timings[opcode] & PAIR_U) && (decode_delay + decode_delay_offset) <= 0) { + int has_displacement; + + if (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; + + if ((!has_displacement || cpu_has_feature(CPU_FEATURE_MMX)) && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) { + /*Instruction might pair with next*/ + u_pipe_full = 1; + u_pipe_opcode = opcode; + u_pipe_timings = timings; + u_pipe_op_32 = op_32; + u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); + u_pipe_fetchdat = fetchdat; + u_pipe_decode_delay_offset = decode_delay_offset; + u_pipe_deps = deps; + decode_delay_offset = 0; + return; + } + } + /*Instruction can not pair and must run now*/ + if (check_agi(deps, opcode, fetchdat, op_32)) + agi_stall = 1; + codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); + decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + addr_regmask = 0; } -codegen_timing_t codegen_timing_pentium = +void +codegen_timing_pentium_block_end(void) { - codegen_timing_pentium_start, - codegen_timing_pentium_prefix, - codegen_timing_pentium_opcode, - codegen_timing_pentium_block_start, - codegen_timing_pentium_block_end, - NULL + if (u_pipe_full) { + /*Run previous now*/ + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + codegen_block_cycles++; + codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_deps[u_pipe_opcode], u_pipe_op_32) + decode_delay + decode_delay_offset; + u_pipe_full = 0; + } +} + +codegen_timing_t codegen_timing_pentium = { + codegen_timing_pentium_start, + codegen_timing_pentium_prefix, + codegen_timing_pentium_opcode, + codegen_timing_pentium_block_start, + codegen_timing_pentium_block_end, + NULL }; diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c index a1ee02b63..11dd912b4 100644 --- a/src/cpu/codegen_timing_winchip.c +++ b/src/cpu/codegen_timing_winchip.c @@ -4,19 +4,21 @@ #include #include <86box/86box.h> #include "cpu.h" +#include <86box/mem.h> +#include <86box/plat_unused.h> + #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include <86box/mem.h> #include "codegen.h" #include "codegen_ops.h" #include "codegen_timing_common.h" -#define CYCLES(c) (int *)c -#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8)) +#define CYCLES(c) (int *) c +#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8)) -static int *opcode_timings[256] = -{ +static int *opcode_timings[256] = { + // clang-format off /*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), /*20*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), @@ -36,10 +38,11 @@ static int *opcode_timings[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL + // clang-format on }; -static int *opcode_timings_mod3[256] = -{ +static int *opcode_timings_mod3[256] = { + // clang-format off /*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), /*20*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(3), @@ -59,10 +62,11 @@ static int *opcode_timings_mod3[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL + // clang-format on }; -static int *opcode_timings_0f[256] = -{ +static int *opcode_timings_0f[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -82,9 +86,10 @@ static int *opcode_timings_0f[256] = /*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, + // clang-format on }; -static int *opcode_timings_0f_mod3[256] = -{ +static int *opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -104,60 +109,72 @@ static int *opcode_timings_0f_mod3[256] = /*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, + // clang-format on }; -static int *opcode_timings_shift[8] = -{ +static int *opcode_timings_shift[8] = { + // clang-format off CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) + // clang-format on }; -static int *opcode_timings_shift_mod3[8] = -{ +static int *opcode_timings_shift_mod3[8] = { + // clang-format off CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) + // clang-format on }; -static int *opcode_timings_f6[8] = -{ +static int *opcode_timings_f6[8] = { + // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static int *opcode_timings_f6_mod3[8] = -{ +static int *opcode_timings_f6_mod3[8] = { + // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static int *opcode_timings_f7[8] = -{ +static int *opcode_timings_f7[8] = { + // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static int *opcode_timings_f7_mod3[8] = -{ +static int *opcode_timings_f7_mod3[8] = { + // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static int *opcode_timings_ff[8] = -{ +static int *opcode_timings_ff[8] = { + // clang-format off &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL + // clang-format on }; -static int *opcode_timings_ff_mod3[8] = -{ +static int *opcode_timings_ff_mod3[8] = { + // clang-format off &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL + // clang-format on }; -static int *opcode_timings_d8[8] = -{ +static int *opcode_timings_d8[8] = { + // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) + // clang-format on }; -static int *opcode_timings_d8_mod3[8] = -{ +static int *opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) + // clang-format on }; -static int *opcode_timings_d9[8] = -{ +static int *opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) + // clang-format on }; -static int *opcode_timings_d9_mod3[64] = -{ +static int *opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), /*FXCH*/ @@ -174,26 +191,29 @@ static int *opcode_timings_d9_mod3[64] = CYCLES(300), CYCLES(58), CYCLES(676), CYCLES(355), NULL, NULL, CYCLES(3), CYCLES(3), /* opFPREM opFSQRT opFSINCOS opFRNDINT opFSCALE opFSIN opFCOS*/ CYCLES(70), NULL, CYCLES(72), CYCLES(292), CYCLES(21), CYCLES(30), CYCLES(474), CYCLES(474) + // clang-format on }; -static int *opcode_timings_da[8] = -{ +static int *opcode_timings_da[8] = { + // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) + // clang-format on }; -static int *opcode_timings_da_mod3[8] = -{ +static int *opcode_timings_da_mod3[8] = { + // clang-format off NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL + // clang-format on }; - -static int *opcode_timings_db[8] = -{ +static int *opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil FLDe FSTPe*/ CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8) + // clang-format on }; -static int *opcode_timings_db_mod3[64] = -{ +static int *opcode_timings_db_mod3[64] = { + // clang-format off NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -203,54 +223,63 @@ static int *opcode_timings_db_mod3[64] = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on }; -static int *opcode_timings_dc[8] = -{ +static int *opcode_timings_dc[8] = { + // clang-format off /* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/ CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74) + // clang-format on }; -static int *opcode_timings_dc_mod3[8] = -{ +static int *opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) + // clang-format on }; -static int *opcode_timings_dd[8] = -{ +static int *opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5) + // clang-format on }; -static int *opcode_timings_dd_mod3[8] = -{ +static int *opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL + // clang-format on }; -static int *opcode_timings_de[8] = -{ +static int *opcode_timings_de[8] = { + // clang-format off /* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) + // clang-format on }; -static int *opcode_timings_de_mod3[8] = -{ +static int *opcode_timings_de_mod3[8] = { + // clang-format off /* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) + // clang-format on }; -static int *opcode_timings_df[8] = -{ +static int *opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8) + // clang-format on }; -static int *opcode_timings_df_mod3[8] = -{ +static int *opcode_timings_df_mod3[8] = { + // clang-format off /* FFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL + // clang-format on }; -static int *opcode_timings_8x[8] = -{ +static int *opcode_timings_8x[8] = { + // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; static int *opcode_timings_8x_mod3[8] = @@ -264,158 +293,169 @@ static int *opcode_timings_81[8] = static int *opcode_timings_81_mod3[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm + // clang-format on }; -static int timing_count; -static uint8_t last_prefix; +static int timing_count; +static uint8_t last_prefix; static uint32_t regmask_modified; -static inline int COUNT(int *c, int op_32) +static inline int +COUNT(int *c, int op_32) { - if ((uintptr_t)c <= 10000) - return (int)(uintptr_t)c; - if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff)) - { - if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; - } - return *c; + if ((uintptr_t) c <= 10000) + return (int) (uintptr_t) c; + if (((uintptr_t) c & ~0xffff) == (-1 & ~0xffff)) { + if (op_32 & 0x100) + return ((uintptr_t) c >> 8) & 0xff; + return (uintptr_t) c & 0xff; + } + return *c; } -void codegen_timing_winchip_block_start(void) +void +codegen_timing_winchip_block_start(void) { - regmask_modified = 0; + regmask_modified = 0; } -void codegen_timing_winchip_start(void) +void +codegen_timing_winchip_start(void) { - timing_count = 0; - last_prefix = 0; + timing_count = 0; + last_prefix = 0; } -void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) +void +codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) { - timing_count += COUNT(opcode_timings[prefix], 0); - last_prefix = prefix; + timing_count += COUNT(opcode_timings[prefix], 0); + last_prefix = prefix; } -void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +void +codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) { - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); + int **timings; + const uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } - case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; + timing_count += COUNT(timings[opcode], op_32); + if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) + timing_count++; /*AGI stall*/ + codegen_block_cycles += timing_count; - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; - - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - timing_count += COUNT(timings[opcode], op_32); - if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) - timing_count++; /*AGI stall*/ - codegen_block_cycles += timing_count; - - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_winchip_block_end(void) +void +codegen_timing_winchip_block_end(void) { + // } -codegen_timing_t codegen_timing_winchip = -{ - codegen_timing_winchip_start, - codegen_timing_winchip_prefix, - codegen_timing_winchip_opcode, - codegen_timing_winchip_block_start, - codegen_timing_winchip_block_end, - NULL +codegen_timing_t codegen_timing_winchip = { + codegen_timing_winchip_start, + codegen_timing_winchip_prefix, + codegen_timing_winchip_opcode, + codegen_timing_winchip_block_start, + codegen_timing_winchip_block_end, + NULL }; diff --git a/src/cpu/codegen_timing_winchip2.c b/src/cpu/codegen_timing_winchip2.c index f96304072..d4e32611e 100644 --- a/src/cpu/codegen_timing_winchip2.c +++ b/src/cpu/codegen_timing_winchip2.c @@ -14,6 +14,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_ops.h" @@ -23,46 +24,46 @@ #include "codegen_timing_common.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ -#define CYCLES_HAS_MULTI (1 << 31) +#define CYCLES_HAS_MULTI (1 << 31) -#define CYCLES_FPU (1 << 30) +#define CYCLES_FPU (1 << 30) #define CYCLES_IS_MMX_MUL (1 << 29) #define CYCLES_IS_MMX_SHIFT (1 << 28) #define CYCLES_IS_MMX_ANY (1 << 27) #define CYCLES_IS_3DNOW (1 << 26) -#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) +#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) #define CYCLES_MMX_SHIFT(c) (CYCLES_IS_MMX_SHIFT | c) -#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) -#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) +#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) +#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) -#define CYCLES_IS_MMX (CYCLES_IS_MMX_MUL | CYCLES_IS_MMX_SHIFT | CYCLES_IS_MMX_ANY | CYCLES_IS_3DNOW) +#define CYCLES_IS_MMX (CYCLES_IS_MMX_MUL | CYCLES_IS_MMX_SHIFT | CYCLES_IS_MMX_ANY | CYCLES_IS_3DNOW) -#define GET_CYCLES(c) (c & ~(CYCLES_HAS_MULTI | CYCLES_FPU | CYCLES_IS_MMX)) +#define GET_CYCLES(c) (c & ~(CYCLES_HAS_MULTI | CYCLES_FPU | CYCLES_IS_MMX)) -#define CYCLES(c) c -#define CYCLES2(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) +#define CYCLES(c) c +#define CYCLES2(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) /*comp_time = cycles until instruction complete i_overlap = cycles that overlap with integer f_overlap = cycles that overlap with subsequent FPU*/ #define FPU_CYCLES(comp_time, i_overlap, f_overlap) (comp_time) | (i_overlap << 8) | (f_overlap << 16) | CYCLES_FPU -#define FPU_COMP_TIME(timing) (timing & 0xff) -#define FPU_I_OVERLAP(timing) ((timing >> 8) & 0xff) -#define FPU_F_OVERLAP(timing) ((timing >> 16) & 0xff) +#define FPU_COMP_TIME(timing) (timing & 0xff) +#define FPU_I_OVERLAP(timing) ((timing >> 8) & 0xff) +#define FPU_F_OVERLAP(timing) ((timing >> 16) & 0xff) -#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) +#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) -#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) +#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) -#define FPU_RESULT_LATENCY(timing) ((timing >> 8) & 0xff) +#define FPU_RESULT_LATENCY(timing) ((timing >> 8) & 0xff) -#define INVALID 0 +#define INVALID 0 -static uint32_t opcode_timings[256] = -{ +static uint32_t opcode_timings[256] = { + // clang-format off /*00*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, /*10*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), /*20*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), @@ -82,10 +83,11 @@ static uint32_t opcode_timings[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID + // clang-format on }; -static uint32_t opcode_timings_mod3[256] = -{ +static uint32_t opcode_timings_mod3[256] = { + // clang-format off /*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, /*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), /*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), @@ -105,10 +107,11 @@ static uint32_t opcode_timings_mod3[256] = /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), /*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID, + // clang-format on }; -static uint32_t opcode_timings_0f[256] = -{ +static uint32_t opcode_timings_0f[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), /*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -128,9 +131,10 @@ static uint32_t opcode_timings_0f[256] = /*d0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), /*e0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), /*f0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, + // clang-format on }; -static uint32_t opcode_timings_0f_mod3[256] = -{ +static uint32_t opcode_timings_0f_mod3[256] = { + // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), /*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -150,66 +154,78 @@ static uint32_t opcode_timings_0f_mod3[256] = /*d0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), /*e0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), /*f0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, + // clang-format on }; -static uint32_t opcode_timings_shift[8] = -{ +static uint32_t opcode_timings_shift[8] = { + // clang-format off CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) + // clang-format on }; -static uint32_t opcode_timings_shift_mod3[8] = -{ +static uint32_t opcode_timings_shift_mod3[8] = { + // clang-format off CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) + // clang-format on }; -static uint32_t opcode_timings_f6[8] = -{ +static uint32_t opcode_timings_f6[8] = { + // clang-format off CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static uint32_t opcode_timings_f6_mod3[8] = -{ +static uint32_t opcode_timings_f6_mod3[8] = { + // clang-format off CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) + // clang-format on }; -static uint32_t opcode_timings_f7[8] = -{ +static uint32_t opcode_timings_f7[8] = { + // clang-format off CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static uint32_t opcode_timings_f7_mod3[8] = -{ +static uint32_t opcode_timings_f7_mod3[8] = { + // clang-format off CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) + // clang-format on }; -static uint32_t opcode_timings_ff[8] = -{ +static uint32_t opcode_timings_ff[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID + // clang-format on }; -static uint32_t opcode_timings_ff_mod3[8] = -{ +static uint32_t opcode_timings_ff_mod3[8] = { + // clang-format off CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID + // clang-format on }; -static uint32_t opcode_timings_d8[8] = -{ +static uint32_t opcode_timings_d8[8] = { + // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), /* FSUBs FSUBRs FDIVs FDIVRs*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_d8_mod3[8] = -{ +static uint32_t opcode_timings_d8_mod3[8] = { + // clang-format off /* FADD FMUL FCOM FCOMP*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), /* FSUB FSUBR FDIV FDIVR*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_d9[8] = -{ +static uint32_t opcode_timings_d9[8] = { + // clang-format off /* FLDs FSTs FSTPs*/ FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), /* FLDENV FLDCW FSTENV FSTCW*/ FPU_CYCLES(32,0,0), FPU_CYCLES(8,0,0), FPU_CYCLES(48,0,0), FPU_CYCLES(2,0,0) + // clang-format on }; -static uint32_t opcode_timings_d9_mod3[64] = -{ +static uint32_t opcode_timings_d9_mod3[64] = { + // clang-format off /*FLD*/ FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), @@ -238,32 +254,35 @@ static uint32_t opcode_timings_d9_mod3[64] = FPU_CYCLES(64,2,2), INVALID, FPU_CYCLES(70,69,2),FPU_CYCLES(89,2,2), /* opFRNDINT opFSCALE opFSIN opFCOS*/ FPU_CYCLES(9,0,0), FPU_CYCLES(20,5,0), FPU_CYCLES(65,2,2), FPU_CYCLES(65,2,2) + // clang-format on }; -static uint32_t opcode_timings_da[8] = -{ +static uint32_t opcode_timings_da[8] = { + // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), /* FISUBl FISUBRl FIDIVl FIDIVRl*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) + // clang-format on }; -static uint32_t opcode_timings_da_mod3[8] = -{ +static uint32_t opcode_timings_da_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ INVALID, FPU_CYCLES(1,0,0), INVALID, INVALID + // clang-format on }; - -static uint32_t opcode_timings_db[8] = -{ +static uint32_t opcode_timings_db[8] = { + // clang-format off /* FLDil FSTil FSTPil*/ FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), /* FLDe FSTPe*/ INVALID, FPU_CYCLES(3,0,0), INVALID, FPU_CYCLES(3,0,0) + // clang-format on }; -static uint32_t opcode_timings_db_mod3[64] = -{ +static uint32_t opcode_timings_db_mod3[64] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -289,455 +308,469 @@ static uint32_t opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + // clang-format on }; -static uint32_t opcode_timings_dc[8] = -{ +static uint32_t opcode_timings_dc[8] = { + // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), /* FSUBd FSUBRd FDIVd FDIVRd*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_dc_mod3[8] = -{ +static uint32_t opcode_timings_dc_mod3[8] = { + // clang-format off /* opFADDr opFMULr*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),INVALID, INVALID, /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_dd[8] = -{ +static uint32_t opcode_timings_dd[8] = { + // clang-format off /* FLDd FSTd FSTPd*/ FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), /* FRSTOR FSAVE FSTSW*/ FPU_CYCLES(70,0,0), INVALID, FPU_CYCLES(127,0,0), FPU_CYCLES(6,0,0) + // clang-format on }; -static uint32_t opcode_timings_dd_mod3[8] = -{ +static uint32_t opcode_timings_dd_mod3[8] = { + // clang-format off /* FFFREE FST FSTP*/ FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), /* FUCOM FUCOMP*/ FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),INVALID, INVALID + // clang-format on }; -static uint32_t opcode_timings_de[8] = -{ +static uint32_t opcode_timings_de[8] = { + // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), /* FISUBw FISUBRw FIDIVw FIDIVRw*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) + // clang-format on }; -static uint32_t opcode_timings_de_mod3[8] = -{ +static uint32_t opcode_timings_de_mod3[8] = { + // clang-format off /* FADDP FMULP FCOMPP*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(1,0,0), /* FSUBP FSUBRP FDIVP FDIVRP*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) + // clang-format on }; -static uint32_t opcode_timings_df[8] = -{ +static uint32_t opcode_timings_df[8] = { + // clang-format off /* FILDiw FISTiw FISTPiw*/ FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), /* FILDiq FBSTP FISTPiq*/ INVALID, FPU_CYCLES(3,2,2), FPU_CYCLES(148,0,0), FPU_CYCLES(6,0,0) + // clang-format on }; -static uint32_t opcode_timings_df_mod3[8] = -{ +static uint32_t opcode_timings_df_mod3[8] = { + // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID + // clang-format on }; -static uint32_t opcode_timings_8x[8] = -{ +static uint32_t opcode_timings_8x[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_8x_mod3[8] = -{ +static uint32_t opcode_timings_8x_mod3[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_81[8] = -{ +static uint32_t opcode_timings_81[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) + // clang-format on }; -static uint32_t opcode_timings_81_mod3[8] = -{ +static uint32_t opcode_timings_81_mod3[8] = { + // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) + // clang-format on }; -static int timing_count; -static uint8_t last_prefix; +static int timing_count; +static uint8_t last_prefix; static uint32_t regmask_modified; -static int decode_delay, decode_delay_offset; -static int fpu_latency; -static int fpu_st_latency[8]; +static int decode_delay; +static int decode_delay_offset; +static int fpu_latency; +static int fpu_st_latency[8]; -static int u_pipe_full; -static uint32_t u_pipe_opcode; +static int u_pipe_full; +static uint32_t u_pipe_opcode; static uint32_t *u_pipe_timings; -static uint32_t u_pipe_op_32; -static uint32_t u_pipe_regmask; -static uint32_t u_pipe_fetchdat; -static int u_pipe_decode_delay_offset; +static uint32_t u_pipe_op_32; +static uint32_t u_pipe_regmask; +static uint32_t u_pipe_fetchdat; +static int u_pipe_decode_delay_offset; static uint64_t *u_pipe_deps; -int can_pair(uint32_t timing_a, uint32_t timing_b, uint8_t regmask_b) +int +can_pair(uint32_t timing_a, uint32_t timing_b, uint8_t regmask_b) { - /*Only MMX/3DNow instructions can pair*/ - if (!(timing_b & CYCLES_IS_MMX)) - return 0; - /*Only one MMX multiply per cycle*/ - if ((timing_a & CYCLES_IS_MMX_MUL) && (timing_b & CYCLES_IS_MMX_MUL)) - return 0; - /*Only one MMX shift/pack per cycle*/ - if ((timing_a & CYCLES_IS_MMX_SHIFT) && (timing_b & CYCLES_IS_MMX_SHIFT)) - return 0; - /*Second instruction can not access registers written by first*/ - if (u_pipe_regmask & regmask_b) - return 0; - /*Must have had enough time to decode prefixes*/ - if ((decode_delay+decode_delay_offset+u_pipe_decode_delay_offset) > 0) - return 0; + /*Only MMX/3DNow instructions can pair*/ + if (!(timing_b & CYCLES_IS_MMX)) + return 0; + /*Only one MMX multiply per cycle*/ + if ((timing_a & CYCLES_IS_MMX_MUL) && (timing_b & CYCLES_IS_MMX_MUL)) + return 0; + /*Only one MMX shift/pack per cycle*/ + if ((timing_a & CYCLES_IS_MMX_SHIFT) && (timing_b & CYCLES_IS_MMX_SHIFT)) + return 0; + /*Second instruction can not access registers written by first*/ + if (u_pipe_regmask & regmask_b) + return 0; + /*Must have had enough time to decode prefixes*/ + if ((decode_delay + decode_delay_offset + u_pipe_decode_delay_offset) > 0) + return 0; - return 1; + return 1; } -static inline int COUNT(uint32_t c, int op_32) +static inline int +COUNT(uint32_t c, int op_32) { - if (c & CYCLES_FPU) - return FPU_I_LATENCY(c); - if (c & CYCLES_HAS_MULTI) - { - if (op_32 & 0x100) - return (c >> 8) & 0xff; - return c & 0xff; - } - return GET_CYCLES(c); + if (c & CYCLES_FPU) + return FPU_I_LATENCY(c); + if (c & CYCLES_HAS_MULTI) { + if (op_32 & 0x100) + return (c >> 8) & 0xff; + return c & 0xff; + } + return GET_CYCLES(c); } -static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +static int +check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) { - uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); - /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not - cause AGIs with each other, but do with instructions that use it explicitly*/ - if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) - addr_regmask |= (1 << REG_ESP); + /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not + cause AGIs with each other, but do with instructions that use it explicitly*/ + if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) + addr_regmask |= (1 << REG_ESP); - return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; + return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; } -static int codegen_fpu_latencies(uint64_t deps, int reg) +static int +codegen_fpu_latencies(uint64_t deps, int reg) { - int latency = fpu_latency; + int latency = fpu_latency; - if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) - latency = fpu_st_latency[0]; - if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) - latency = fpu_st_latency[1]; - if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) - latency = fpu_st_latency[reg]; + if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) + latency = fpu_st_latency[0]; + if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) + latency = fpu_st_latency[1]; + if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) + latency = fpu_st_latency[reg]; - return latency; + return latency; } -#define SUB_AND_CLAMP(latency, count) \ - latency -= count; \ - if (latency < 0) \ - latency = 0 +#define SUB_AND_CLAMP(latency, count) \ + latency -= count; \ + if (latency < 0) \ + latency = 0 -static void codegen_fpu_latency_clock(int count) +static void +codegen_fpu_latency_clock(int count) { - SUB_AND_CLAMP(fpu_latency, count); - SUB_AND_CLAMP(fpu_st_latency[0], count); - SUB_AND_CLAMP(fpu_st_latency[1], count); - SUB_AND_CLAMP(fpu_st_latency[2], count); - SUB_AND_CLAMP(fpu_st_latency[3], count); - SUB_AND_CLAMP(fpu_st_latency[4], count); - SUB_AND_CLAMP(fpu_st_latency[5], count); - SUB_AND_CLAMP(fpu_st_latency[6], count); - SUB_AND_CLAMP(fpu_st_latency[7], count); + SUB_AND_CLAMP(fpu_latency, count); + SUB_AND_CLAMP(fpu_st_latency[0], count); + SUB_AND_CLAMP(fpu_st_latency[1], count); + SUB_AND_CLAMP(fpu_st_latency[2], count); + SUB_AND_CLAMP(fpu_st_latency[3], count); + SUB_AND_CLAMP(fpu_st_latency[4], count); + SUB_AND_CLAMP(fpu_st_latency[5], count); + SUB_AND_CLAMP(fpu_st_latency[6], count); + SUB_AND_CLAMP(fpu_st_latency[7], count); } -static void codegen_instruction(uint32_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) +static void +codegen_instruction(uint32_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) { - int instr_cycles, latency = 0; + int instr_cycles; + int latency = 0; - if ((timings[opcode] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) - instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); - else - instr_cycles = 0; + if ((timings[opcode] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); + else + instr_cycles = 0; - if ((decode_delay + decode_delay_offset) > 0) - codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); - else - codegen_fpu_latency_clock(instr_cycles); - instr_cycles += COUNT(timings[opcode], op_32); - instr_cycles += exec_delay; - if ((decode_delay + decode_delay_offset) > 0) - codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; - else - codegen_block_cycles += instr_cycles; - decode_delay = (-instr_cycles) + 1; + if ((decode_delay + decode_delay_offset) > 0) + codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); + else + codegen_fpu_latency_clock(instr_cycles); + instr_cycles += COUNT(timings[opcode], op_32); + instr_cycles += exec_delay; + if ((decode_delay + decode_delay_offset) > 0) + codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; + else + codegen_block_cycles += instr_cycles; + decode_delay = (-instr_cycles) + 1; + if (deps[opcode] & FPU_POP) { + for (uint8_t c = 0; c < 7; c++) + fpu_st_latency[c] = fpu_st_latency[c + 1]; + fpu_st_latency[7] = 0; + } + if (deps[opcode] & FPU_POP2) { + for (uint8_t c = 0; c < 6; c++) + fpu_st_latency[c] = fpu_st_latency[c + 2]; + fpu_st_latency[6] = fpu_st_latency[7] = 0; + } + if (timings[opcode] & CYCLES_FPU) { +#if 0 + if (fpu_latency) + fatal("Bad latency FPU\n");*/ +#endif + fpu_latency = FPU_F_LATENCY(timings[opcode]); + } + + if (deps[opcode] & FPU_PUSH) { + for (uint8_t c = 0; c < 7; c++) + fpu_st_latency[c + 1] = fpu_st_latency[c]; + fpu_st_latency[0] = 0; + } + if (deps[opcode] & FPU_WRITE_ST0) { +#if 0 + if (fpu_st_latency[0]) + fatal("Bad latency ST0\n");*/ +#endif + fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_ST1) { +#if 0 + if (fpu_st_latency[1]) + fatal("Bad latency ST1\n");*/ +#endif + fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_STREG) { + int reg = fetchdat & 7; if (deps[opcode] & FPU_POP) - { - int c; - - for (c = 0; c < 7; c++) - fpu_st_latency[c] = fpu_st_latency[c+1]; - fpu_st_latency[7] = 0; - } - if (deps[opcode] & FPU_POP2) - { - int c; - - for (c = 0; c < 6; c++) - fpu_st_latency[c] = fpu_st_latency[c+2]; - fpu_st_latency[6] = fpu_st_latency[7] = 0; - } - if (timings[opcode] & CYCLES_FPU) - { - /* if (fpu_latency) - fatal("Bad latency FPU\n");*/ - fpu_latency = FPU_F_LATENCY(timings[opcode]); - } - - if (deps[opcode] & FPU_PUSH) - { - int c; - - for (c = 0; c < 7; c++) - fpu_st_latency[c+1] = fpu_st_latency[c]; - fpu_st_latency[0] = 0; - } - if (deps[opcode] & FPU_WRITE_ST0) - { -/* if (fpu_st_latency[0]) - fatal("Bad latency ST0\n");*/ - fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_ST1) - { -/* if (fpu_st_latency[1]) - fatal("Bad latency ST1\n");*/ - fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); - } - if (deps[opcode] & FPU_WRITE_STREG) - { - int reg = fetchdat & 7; - if (deps[opcode] & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && - !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) - { -/* if (fpu_st_latency[reg]) - fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/ - fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); - } + reg--; + if (reg >= 0 && !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) { +#if 0 + if (fpu_st_latency[reg]) + fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/ +#endif + fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); } + } } -static void codegen_timing_winchip2_block_start(void) +static void +codegen_timing_winchip2_block_start(void) { - regmask_modified = 0; - decode_delay = decode_delay_offset = 0; - u_pipe_full = 0; + regmask_modified = 0; + decode_delay = decode_delay_offset = 0; + u_pipe_full = 0; } -static void codegen_timing_winchip2_start(void) +static void +codegen_timing_winchip2_start(void) { - timing_count = 0; - last_prefix = 0; + timing_count = 0; + last_prefix = 0; } -static void codegen_timing_winchip2_prefix(uint8_t prefix, uint32_t fetchdat) +static void +codegen_timing_winchip2_prefix(uint8_t prefix, uint32_t fetchdat) { - if (prefix == 0x0f) - { - /*0fh prefix is 'free'*/ - last_prefix = prefix; - return; - } - /*On WinChip all prefixes take 1 cycle to decode. Decode may be shadowed - by execution of previous instructions*/ - decode_delay_offset++; + if (prefix == 0x0f) { + /*0fh prefix is 'free'*/ last_prefix = prefix; + return; + } + /*On WinChip all prefixes take 1 cycle to decode. Decode may be shadowed + by execution of previous instructions*/ + decode_delay_offset++; + last_prefix = prefix; } -static void codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +static void +codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) { - uint32_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - int agi_stall = 0; + uint32_t *timings; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); + int agi_stall = 0; - switch (last_prefix) - { - case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + break; - case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; - break; - case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; - break; - case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; - break; - case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; - break; - case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; - break; - case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; - break; - case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; - break; + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xc1: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; default: - switch (opcode) - { - case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; - break; - case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; - deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; - opcode = (fetchdat >> 3) & 7; - break; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } - case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; - break; + if (u_pipe_full) { + uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; - break; - case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; - break; - case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; - break; + if (can_pair(u_pipe_timings[u_pipe_opcode], timings[opcode], regmask)) { + int cycles_a = u_pipe_timings[u_pipe_opcode] & 0xff; + int cycles_b = timings[opcode] & 0xff; + uint32_t timing = (cycles_a > cycles_b) ? u_pipe_timings[u_pipe_opcode] : timings[opcode]; + uint64_t temp_deps = 0; - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - if (u_pipe_full) - { - uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - - if (can_pair(u_pipe_timings[u_pipe_opcode], timings[opcode], regmask)) - { - int cycles_a = u_pipe_timings[u_pipe_opcode] & 0xff; - int cycles_b = timings[opcode] & 0xff; - uint32_t timing = (cycles_a > cycles_b) ? u_pipe_timings[u_pipe_opcode] : timings[opcode]; - uint64_t temp_deps = 0; - - if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - - codegen_instruction(&timing, &temp_deps, 0, 0, 0, 0, agi_stall); - u_pipe_full = 0; - decode_delay_offset = 0; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; - return; - } - else - { - /*No pairing, run first instruction now*/ - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - u_pipe_full = 0; - regmask_modified = u_pipe_regmask; - } - } - if (timings[opcode] & CYCLES_IS_MMX) - { - /*Might pair with next instruction*/ - u_pipe_full = 1; - u_pipe_opcode = opcode; - u_pipe_timings = timings; - u_pipe_op_32 = op_32; - u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); - u_pipe_fetchdat = fetchdat; - u_pipe_decode_delay_offset = decode_delay_offset; - u_pipe_deps = deps; - decode_delay_offset = 0; - return; - } - - if (check_agi(deps, opcode, fetchdat, op_32)) + if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) agi_stall = 1; - codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); - decode_delay_offset = 0; - regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); -} -static void codegen_timing_winchip2_block_end(void) -{ - if (u_pipe_full) - { - int agi_stall = 0; - - if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) - agi_stall = 1; - codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); - u_pipe_full = 0; + codegen_instruction(&timing, &temp_deps, 0, 0, 0, 0, agi_stall); + u_pipe_full = 0; + decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; + return; + } else { + /*No pairing, run first instruction now*/ + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); + u_pipe_full = 0; + regmask_modified = u_pipe_regmask; } + } + if (timings[opcode] & CYCLES_IS_MMX) { + /*Might pair with next instruction*/ + u_pipe_full = 1; + u_pipe_opcode = opcode; + u_pipe_timings = timings; + u_pipe_op_32 = op_32; + u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); + u_pipe_fetchdat = fetchdat; + u_pipe_decode_delay_offset = decode_delay_offset; + u_pipe_deps = deps; + decode_delay_offset = 0; + return; + } + + if (check_agi(deps, opcode, fetchdat, op_32)) + agi_stall = 1; + codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); + decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -codegen_timing_t codegen_timing_winchip2 = +static void +codegen_timing_winchip2_block_end(void) { - codegen_timing_winchip2_start, - codegen_timing_winchip2_prefix, - codegen_timing_winchip2_opcode, - codegen_timing_winchip2_block_start, - codegen_timing_winchip2_block_end, - NULL + if (u_pipe_full) { + int agi_stall = 0; + + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); + u_pipe_full = 0; + } +} + +codegen_timing_t codegen_timing_winchip2 = { + codegen_timing_winchip2_start, + codegen_timing_winchip2_prefix, + codegen_timing_winchip2_opcode, + codegen_timing_winchip2_block_start, + codegen_timing_winchip2_block_end, + NULL }; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 8b2792b75..cbd5ca0ca 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -18,6 +18,7 @@ * Copyright 2016-2020 Miran Grca. * Copyright 2018-2021 Fred N. van Kempen. */ +#include #include #include #include @@ -37,6 +38,9 @@ #include <86box/pic.h> #include <86box/pci.h> #include <86box/gdbstub.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> + #ifdef USE_DYNAREC # include "codegen.h" #endif @@ -125,6 +129,27 @@ const OpFn *x86_opcodes_REPE; const OpFn *x86_opcodes_REPNE; const OpFn *x86_opcodes_3DNOW; +const OpFn *x86_2386_opcodes; +const OpFn *x86_2386_opcodes_0f; +const OpFn *x86_2386_opcodes_d8_a16; +const OpFn *x86_2386_opcodes_d8_a32; +const OpFn *x86_2386_opcodes_d9_a16; +const OpFn *x86_2386_opcodes_d9_a32; +const OpFn *x86_2386_opcodes_da_a16; +const OpFn *x86_2386_opcodes_da_a32; +const OpFn *x86_2386_opcodes_db_a16; +const OpFn *x86_2386_opcodes_db_a32; +const OpFn *x86_2386_opcodes_dc_a16; +const OpFn *x86_2386_opcodes_dc_a32; +const OpFn *x86_2386_opcodes_dd_a16; +const OpFn *x86_2386_opcodes_dd_a32; +const OpFn *x86_2386_opcodes_de_a16; +const OpFn *x86_2386_opcodes_de_a32; +const OpFn *x86_2386_opcodes_df_a16; +const OpFn *x86_2386_opcodes_df_a32; +const OpFn *x86_2386_opcodes_REPE; +const OpFn *x86_2386_opcodes_REPNE; + uint16_t cpu_fast_off_count; uint16_t cpu_fast_off_val; uint16_t temp_seg_data[4] = { 0, 0, 0, 0 }; @@ -216,7 +241,7 @@ uint32_t cache_index = 0; uint8_t _cache[2048]; uint64_t cpu_CR4_mask; -uint64_t tsc = 0; +uint64_t tsc = 0; uint64_t pmc[2] = { 0, 0 }; double cpu_dmulti; @@ -229,7 +254,7 @@ cyrix_t cyrix; cpu_family_t *cpu_f; CPU *cpu_s; -uint8_t do_translate = 0; +uint8_t do_translate = 0; uint8_t do_translate2 = 0; void (*cpu_exec)(int cycs); @@ -455,7 +480,7 @@ SF_FPU_reset(void) fpu_state.fcs = 0; fpu_state.fds = 0; fpu_state.fdp = 0; - memset(fpu_state.st_space, 0, sizeof(floatx80)*8); + memset(fpu_state.st_space, 0, sizeof(floatx80) * 8); } } @@ -541,9 +566,12 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_386_0f); #endif - x86_opcodes_REPE = ops_REPE; - x86_opcodes_REPNE = ops_REPNE; - x86_opcodes_3DNOW = ops_3DNOW; + x86_setopcodes_2386(ops_2386_386, ops_2386_386_0f); + x86_opcodes_REPE = ops_REPE; + x86_opcodes_REPNE = ops_REPNE; + x86_2386_opcodes_REPE = ops_2386_REPE; + x86_2386_opcodes_REPNE = ops_2386_REPNE; + x86_opcodes_3DNOW = ops_3DNOW; #ifdef USE_DYNAREC x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; @@ -605,6 +633,23 @@ cpu_set(void) x86_opcodes_de_a32 = ops_sf_fpu_de_a32; x86_opcodes_df_a16 = ops_sf_fpu_df_a16; x86_opcodes_df_a32 = ops_sf_fpu_df_a32; + + x86_2386_opcodes_d8_a16 = ops_2386_sf_fpu_d8_a16; + x86_2386_opcodes_d8_a32 = ops_2386_sf_fpu_d8_a32; + x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_df_a32; } else { x86_opcodes_d8_a16 = ops_fpu_d8_a16; x86_opcodes_d8_a32 = ops_fpu_d8_a32; @@ -622,6 +667,23 @@ cpu_set(void) x86_opcodes_de_a32 = ops_fpu_de_a32; x86_opcodes_df_a16 = ops_fpu_df_a16; x86_opcodes_df_a32 = ops_fpu_df_a32; + + x86_2386_opcodes_d8_a16 = ops_2386_fpu_d8_a16; + x86_2386_opcodes_d8_a32 = ops_2386_fpu_d8_a32; + x86_2386_opcodes_d9_a16 = ops_2386_fpu_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_fpu_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_fpu_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_fpu_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_fpu_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_fpu_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_fpu_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_fpu_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_fpu_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_fpu_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_fpu_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_fpu_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_fpu_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_fpu_df_a32; } } else { #ifdef USE_DYNAREC @@ -658,6 +720,23 @@ cpu_set(void) x86_opcodes_de_a32 = ops_nofpu_a32; x86_opcodes_df_a16 = ops_nofpu_a16; x86_opcodes_df_a32 = ops_nofpu_a32; + + x86_2386_opcodes_d8_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_d8_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_d9_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_d9_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_da_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_da_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_db_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_db_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_dc_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_dc_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_dd_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_dd_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_de_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_de_a32 = ops_2386_nofpu_a32; + x86_2386_opcodes_df_a16 = ops_2386_nofpu_a16; + x86_2386_opcodes_df_a32 = ops_2386_nofpu_a32; } #ifdef USE_DYNAREC @@ -684,6 +763,7 @@ cpu_set(void) #else x86_setopcodes(ops_186, ops_186_0f); #endif + x86_setopcodes_2386(ops_2386_186, ops_2386_186_0f); break; case CPU_286: @@ -692,6 +772,7 @@ cpu_set(void) #else x86_setopcodes(ops_286, ops_286_0f); #endif + x86_setopcodes_2386(ops_2386_286, ops_2386_286_0f); if (fpu_type == FPU_287) { #ifdef USE_DYNAREC @@ -742,6 +823,21 @@ cpu_set(void) x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32; x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16; x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32; + + x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_287_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_287_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_287_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_287_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_287_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_287_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_287_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_287_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_287_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_287_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_287_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_287_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_287_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_287_df_a32; } else { x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; @@ -757,6 +853,21 @@ cpu_set(void) x86_opcodes_de_a32 = ops_fpu_287_de_a32; x86_opcodes_df_a16 = ops_fpu_287_df_a16; x86_opcodes_df_a32 = ops_fpu_287_df_a32; + + x86_2386_opcodes_d9_a16 = ops_2386_fpu_287_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_fpu_287_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_fpu_287_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_fpu_287_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_fpu_287_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_fpu_287_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_fpu_287_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_fpu_287_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_fpu_287_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_fpu_287_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_fpu_287_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_fpu_287_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_fpu_287_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_fpu_287_df_a32; } } @@ -799,11 +910,13 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_ibm486_0f); #endif + x86_setopcodes_2386(ops_2386_386, ops_2386_ibm486_0f); cpu_features = CPU_FEATURE_MSR; - /* FALLTHROUGH */ + fallthrough; case CPU_386SX: case CPU_386DX: - if (fpu_type == FPU_287) { /* In case we get Deskpro 386 emulation */ + /* In case we get Deskpro 386 emulation */ + if (fpu_type == FPU_287) { #ifdef USE_DYNAREC if (fpu_softfloat) { x86_dynarec_opcodes_d9_a16 = dynarec_ops_sf_fpu_287_d9_a16; @@ -852,6 +965,21 @@ cpu_set(void) x86_opcodes_de_a32 = ops_sf_fpu_287_de_a32; x86_opcodes_df_a16 = ops_sf_fpu_287_df_a16; x86_opcodes_df_a32 = ops_sf_fpu_287_df_a32; + + x86_2386_opcodes_d9_a16 = ops_2386_sf_fpu_287_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_sf_fpu_287_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_sf_fpu_287_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_sf_fpu_287_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_sf_fpu_287_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_sf_fpu_287_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_sf_fpu_287_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_sf_fpu_287_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_sf_fpu_287_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_sf_fpu_287_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_sf_fpu_287_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_sf_fpu_287_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_sf_fpu_287_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_sf_fpu_287_df_a32; } else { x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; @@ -867,6 +995,21 @@ cpu_set(void) x86_opcodes_de_a32 = ops_fpu_287_de_a32; x86_opcodes_df_a16 = ops_fpu_287_df_a16; x86_opcodes_df_a32 = ops_fpu_287_df_a32; + + x86_2386_opcodes_d9_a16 = ops_2386_fpu_287_d9_a16; + x86_2386_opcodes_d9_a32 = ops_2386_fpu_287_d9_a32; + x86_2386_opcodes_da_a16 = ops_2386_fpu_287_da_a16; + x86_2386_opcodes_da_a32 = ops_2386_fpu_287_da_a32; + x86_2386_opcodes_db_a16 = ops_2386_fpu_287_db_a16; + x86_2386_opcodes_db_a32 = ops_2386_fpu_287_db_a32; + x86_2386_opcodes_dc_a16 = ops_2386_fpu_287_dc_a16; + x86_2386_opcodes_dc_a32 = ops_2386_fpu_287_dc_a32; + x86_2386_opcodes_dd_a16 = ops_2386_fpu_287_dd_a16; + x86_2386_opcodes_dd_a32 = ops_2386_fpu_287_dd_a32; + x86_2386_opcodes_de_a16 = ops_2386_fpu_287_de_a16; + x86_2386_opcodes_de_a32 = ops_2386_fpu_287_de_a32; + x86_2386_opcodes_df_a16 = ops_2386_fpu_287_df_a16; + x86_2386_opcodes_df_a32 = ops_2386_fpu_287_df_a32; } } @@ -913,6 +1056,7 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_486_0f); #endif + x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f); timing_rr = 1; /* register dest - register src */ timing_rm = 3; /* register dest - memory src */ @@ -952,6 +1096,7 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_486_0f); #endif + x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f); timing_rr = 1; /* register dest - register src */ timing_rm = 3; /* register dest - memory src */ @@ -990,7 +1135,7 @@ cpu_set(void) case CPU_i486DX_SLENH: cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; - /* FALLTHROUGH */ + fallthrough; case CPU_RAPIDCAD: case CPU_i486SX: case CPU_i486DX: @@ -1004,6 +1149,7 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_486_0f); #endif + x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f); timing_rr = 1; /* register dest - register src */ timing_rm = 2; /* register dest - memory src */ @@ -1302,7 +1448,9 @@ cpu_set(void) x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); else x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); - // x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); +# if 0 + x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); +# endif # else if (cpu_s->cpu_type == CPU_Cx6x86MX) x86_setopcodes(ops_386, ops_c6x86mx_0f); @@ -1310,7 +1458,9 @@ cpu_set(void) x86_setopcodes(ops_386, ops_pentium_0f); else x86_setopcodes(ops_386, ops_c6x86mx_0f); - // x86_setopcodes(ops_386, ops_c6x86_0f); +# if 0 + x86_setopcodes(ops_386, ops_c6x86_0f); +# endif # endif timing_rr = 1; /* register dest - register src */ @@ -1615,7 +1765,7 @@ cpu_set(void) break; default: - fatal("cpu_set : unknown CPU type %llu\n", cpu_s->cpu_type); + fatal("cpu_set : unknown CPU type %" PRIu64 "\n", cpu_s->cpu_type); } switch (fpu_type) { @@ -1647,9 +1797,13 @@ cpu_set(void) cpu_exec = exec386_dynarec; else #endif - cpu_exec = exec386; + /* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */ + if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type > CPU_486DLC)) + cpu_exec = exec386; + else + cpu_exec = exec386_2386; } else if (cpu_s->cpu_type >= CPU_286) - cpu_exec = exec386; + cpu_exec = exec386_2386; else cpu_exec = execx86; mmx_init(); @@ -2324,7 +2478,7 @@ cpu_ven_reset(void) case CPU_K6_3: case CPU_K6_2C: msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL; - /* FALLTHROUGH */ + fallthrough; case CPU_K6_2: #if defined(DEV_BRANCH) && defined(USE_AMD_K5) case CPU_K5: @@ -2338,7 +2492,6 @@ cpu_ven_reset(void) case CPU_PENTIUM2: case CPU_PENTIUM2D: msr.mtrr_cap = 0x00000508ULL; - /* FALLTHROUGH */ break; } } @@ -2741,6 +2894,10 @@ amd_k_invalid_rdmsr: EAX = msr.ecx187 & 0xffffffff; EDX = msr.ecx187 >> 32; break; + case 0x1d9: + EAX = msr.debug_ctl & 0xffffffff; + EDX = msr.debug_ctl >> 32; + break; case 0x1e0: EAX = msr.ecx1e0 & 0xffffffff; EDX = msr.ecx1e0 >> 32; @@ -3121,7 +3278,9 @@ amd_k_invalid_wrmsr: break; case 0x1b: cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); - // msr.apic_base = EAX | ((uint64_t) EDX << 32); +#if 0 + msr.apic_base = EAX | ((uint64_t) EDX << 32); +#endif break; case 0x2a: break; @@ -3192,6 +3351,9 @@ amd_k_invalid_wrmsr: case 0x187: msr.ecx187 = EAX | ((uint64_t) EDX << 32); break; + case 0x1d9: + msr.debug_ctl = EAX | ((uint64_t) EDX << 32); + break; case 0x1e0: msr.ecx1e0 = EAX | ((uint64_t) EDX << 32); break; @@ -3300,7 +3462,7 @@ i686_invalid_wrmsr: } static void -cpu_write(uint16_t addr, uint8_t val, void *priv) +cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { if (addr == 0xf0) { /* Writes to F0 clear FPU error and deassert the interrupt. */ @@ -3382,7 +3544,7 @@ cpu_write(uint16_t addr, uint8_t val, void *priv) } static uint8_t -cpu_read(uint16_t addr, void *priv) +cpu_read(uint16_t addr, UNUSED(void *priv)) { if (addr == 0xf007) return 0x7f; @@ -3438,11 +3600,18 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, #else x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f) { - x86_opcodes = opcodes; + x86_opcodes = opcodes; x86_opcodes_0f = opcodes_0f; } #endif +void +x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f) +{ + x86_2386_opcodes = opcodes; + x86_2386_opcodes_0f = opcodes_0f; +} + void cpu_update_waitstates(void) { diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 32155491e..ca4d0180a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -280,11 +280,12 @@ typedef struct { /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ + uint64_t ecx186; /* 0x00000186, 0x00000187 */ + uint64_t ecx187; /* 0x00000186, 0x00000187 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx186; /* 0x00000186, 0x00000187 */ - uint64_t ecx187; /* 0x00000186, 0x00000187 */ - uint64_t ecx1e0; /* 0x000001e0 */ + uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */ + uint64_t ecx1e0; /* 0x000001e0 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also on the VIA Cyrix III */ @@ -393,8 +394,13 @@ typedef struct { MMX_REG MM[8]; #ifdef USE_NEW_DYNAREC +# if defined(__APPLE__) && defined(__aarch64__) + uint64_t old_fp_control; + uint64_t new_fp_control; +# else uint32_t old_fp_control; uint32_t new_fp_control; +# endif # if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 uint16_t old_fp_control2; uint16_t new_fp_control2; @@ -426,15 +432,15 @@ typedef struct { } cpu_state_t; typedef struct { - uint16_t cwd; - uint16_t swd; - uint16_t tag; - uint16_t foo; - uint32_t fip; - uint32_t fdp; - uint16_t fcs; - uint16_t fds; - floatx80 st_space[8]; + uint16_t cwd; + uint16_t swd; + uint16_t tag; + uint16_t foo; + uint32_t fip; + uint32_t fdp; + uint16_t fcs; + uint16_t fds; + floatx80 st_space[8]; unsigned char tos; unsigned char align1; unsigned char align2; @@ -444,7 +450,7 @@ typedef struct { #define in_smm cpu_state._in_smm #define smi_line cpu_state._smi_line -#define smbase cpu_state._smbase +#define smbase cpu_state._smbase /*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block to be valid*/ @@ -454,9 +460,9 @@ typedef struct { #define CPU_STATUS_V86 (1 << 3) #define CPU_STATUS_SMM (1 << 4) #ifdef USE_NEW_DYNAREC -#define CPU_STATUS_FLAGS 0xff +# define CPU_STATUS_FLAGS 0xff #else -#define CPU_STATUS_FLAGS 0xffff +# define CPU_STATUS_FLAGS 0xffff #endif /*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status. @@ -615,8 +621,8 @@ extern uint64_t star; #define FPU_CW_Reserved_Bits (0xe0c0) -#define cr0 cpu_state.CR0.l -#define msw cpu_state.CR0.w +#define cr0 cpu_state.CR0.l +#define msw cpu_state.CR0.w extern uint32_t cr2; extern uint32_t cr3; extern uint32_t cr4; @@ -720,8 +726,8 @@ extern void loadseg_dynarec(uint16_t seg, x86seg *s); extern int loadseg(uint16_t seg, x86seg *s); extern void loadcs(uint16_t seg); #else -extern void loadseg(uint16_t seg, x86seg *s); -extern void loadcs(uint16_t seg); +extern void loadseg(uint16_t seg, x86seg *s); +extern void loadcs(uint16_t seg); #endif extern char *cpu_current_pc(char *bufp); @@ -748,6 +754,7 @@ extern void execx86(int cycs); extern void enter_smm(int in_hlt); extern void enter_smm_check(int in_hlt); extern void leave_smm(void); +extern void exec386_2386(int cycs); extern void exec386(int cycs); extern void exec386_dynarec(int cycs); extern int idivl(int32_t val); @@ -758,11 +765,11 @@ extern void pmodeint(int num, int soft); extern void pmoderetf(int is32, uint16_t off); extern void pmodeiret(int is32); #else -extern void loadcscall(uint16_t seg); -extern void loadcsjmp(uint16_t seg, uint32_t old_pc); -extern void pmodeint(int num, int soft); -extern void pmoderetf(int is32, uint16_t off); -extern void pmodeiret(int is32); +extern void loadcscall(uint16_t seg); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); #endif extern void resetmcr(void); extern void resetx86(void); @@ -831,6 +838,8 @@ extern int hlt_reset_pending; extern cyrix_t cyrix; +extern int prefetch_prefixes; + extern uint8_t use_custom_nmi_vector; extern uint32_t custom_nmi_vector; @@ -851,9 +860,12 @@ extern void cpu_fast_off_reset(void); extern void smi_raise(void); extern void nmi_raise(void); -extern MMX_REG *MMP[8]; +extern MMX_REG *MMP[8]; extern uint16_t *MMEP[8]; extern void mmx_init(void); +extern void prefetch_flush(void); + +extern void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32); #endif /*EMU_CPU_H*/ diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 76101c344..f994e1946 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -59,10 +59,12 @@ uint32_t rmdat; uint64_t xt_cpu_multi; /* Variables for handling the non-maskable interrupts. */ -int nmi = 0, nmi_auto_clear = 0; +int nmi = 0; +int nmi_auto_clear = 0; /* Was the CPU ever reset? */ -int x86_was_reset = 0, soft_reset_pci = 0; +int x86_was_reset = 0; +int soft_reset_pci = 0; /* Is the TRAP flag on? */ int trap = 0; @@ -71,7 +73,8 @@ int trap = 0; uint32_t easeg; /* This is for the OPTI 283 special reset handling mode. */ -int reset_on_hlt, hlt_reset_pending; +int reset_on_hlt; +int hlt_reset_pending; #ifdef ENABLE_X86_LOG void dumpregs(int); @@ -171,7 +174,10 @@ makemod1table(void) static void makeznptable(void) { - int c, d, e; + int c; + int d; + int e; + for (c = 0; c < 256; c++) { d = 0; for (e = 0; e < 8; e++) { @@ -267,7 +273,7 @@ reset_common(int hard) loadcs(0xF000); cpu_state.pc = 0xFFF0; if (hard) { - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; if (is6117) rammask |= 0x03000000; mem_a20_key = mem_a20_alt = mem_a20_state = 0; diff --git a/src/cpu/x86.h b/src/cpu/x86.h index 337619fa4..77d9329fe 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -9,30 +9,44 @@ that we don't end up with an unnecessarily short block*/ #define ABRT_EXPECTED 0x80 -extern uint8_t opcode, opcode2; +extern uint8_t opcode; +extern uint8_t opcode2; extern uint8_t flags_p; extern uint8_t znptable8[256]; -extern uint16_t zero, oldcs; -extern uint16_t lastcs, lastpc; +extern uint16_t zero; +extern uint16_t oldcs; +extern uint16_t lastcs; +extern uint16_t lastpc; extern uint16_t *mod1add[2][8]; extern uint16_t znptable16[65536]; -extern int x86_was_reset, trap; -extern int codegen_flat_ss, codegen_flat_ds; -extern int timetolive, keyboardtimer, trap; -extern int optype, stack32; -extern int oldcpl, cgate32, cpl_override; +extern int x86_was_reset; +extern int trap; +extern int codegen_flat_ss; +extern int codegen_flat_ds; +extern int timetolive; +extern int keyboardtimer; +extern int trap; +extern int optype; +extern int stack32; +extern int oldcpl; +extern int cgate32; +extern int cpl_override; extern int nmi_enable; -extern int oddeven, inttype; +extern int oddeven; +extern int inttype; extern uint32_t use32; -extern uint32_t rmdat, easeg; -extern uint32_t oxpc, flags_zn; +extern uint32_t rmdat; +extern uint32_t easeg; +extern uint32_t oxpc; +extern uint32_t flags_zn; extern uint32_t abrt_error; extern uint32_t backupregs[16]; extern uint32_t *mod1seg[8]; -extern uint32_t *eal_r, *eal_w; +extern uint32_t *eal_r; +extern uint32_t *eal_w; #define fetchdat rmdat @@ -68,13 +82,13 @@ extern uint32_t *eal_r, *eal_w; enum { ABRT_NONE = 0, - ABRT_GEN, - ABRT_TS = 0xA, - ABRT_NP = 0xB, - ABRT_SS = 0xC, - ABRT_GPF = 0xD, - ABRT_PF = 0xE, - ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ + ABRT_GEN = 1, + ABRT_TS = 0xA, + ABRT_NP = 0xB, + ABRT_SS = 0xC, + ABRT_GPF = 0xD, + ABRT_PF = 0xE, + ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ }; extern void x86_doabrt(int x86_abrt); diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index 0cd449236..6fb9b7a22 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.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,10 +187,9 @@ extern const OpFn dynarec_ops_REPNE[1024]; extern const OpFn dynarec_ops_3DNOW[256]; extern const OpFn dynarec_ops_3DNOWE[256]; #else -void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f); +extern void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f); #endif - extern const OpFn *x86_opcodes; extern const OpFn *x86_opcodes_0f; extern const OpFn *x86_opcodes_d8_a16; @@ -330,6 +329,111 @@ extern const OpFn ops_REPNE[1024]; extern const OpFn ops_3DNOW[256]; extern const OpFn ops_3DNOWE[256]; +extern void x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f); + +extern const OpFn *x86_2386_opcodes; +extern const OpFn *x86_2386_opcodes_0f; +extern const OpFn *x86_2386_opcodes_d8_a16; +extern const OpFn *x86_2386_opcodes_d8_a32; +extern const OpFn *x86_2386_opcodes_d9_a16; +extern const OpFn *x86_2386_opcodes_d9_a32; +extern const OpFn *x86_2386_opcodes_da_a16; +extern const OpFn *x86_2386_opcodes_da_a32; +extern const OpFn *x86_2386_opcodes_db_a16; +extern const OpFn *x86_2386_opcodes_db_a32; +extern const OpFn *x86_2386_opcodes_dc_a16; +extern const OpFn *x86_2386_opcodes_dc_a32; +extern const OpFn *x86_2386_opcodes_dd_a16; +extern const OpFn *x86_2386_opcodes_dd_a32; +extern const OpFn *x86_2386_opcodes_de_a16; +extern const OpFn *x86_2386_opcodes_de_a32; +extern const OpFn *x86_2386_opcodes_df_a16; +extern const OpFn *x86_2386_opcodes_df_a32; +extern const OpFn *x86_2386_opcodes_REPE; +extern const OpFn *x86_2386_opcodes_REPNE; + +extern const OpFn ops_2386_186[1024]; +extern const OpFn ops_2386_186_0f[1024]; + +extern const OpFn ops_2386_286[1024]; +extern const OpFn ops_2386_286_0f[1024]; + +extern const OpFn ops_2386_386[1024]; +extern const OpFn ops_2386_386_0f[1024]; + +extern const OpFn ops_2386_486_0f[1024]; +extern const OpFn ops_2386_ibm486_0f[1024]; + +extern const OpFn ops_2386_sf_fpu_287_d9_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_d9_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_da_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_da_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_db_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_db_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_dc_a16[32]; +extern const OpFn ops_2386_sf_fpu_287_dc_a32[32]; +extern const OpFn ops_2386_sf_fpu_287_dd_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_dd_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_de_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_de_a32[256]; +extern const OpFn ops_2386_sf_fpu_287_df_a16[256]; +extern const OpFn ops_2386_sf_fpu_287_df_a32[256]; + +extern const OpFn ops_2386_sf_fpu_d8_a16[32]; +extern const OpFn ops_2386_sf_fpu_d8_a32[32]; +extern const OpFn ops_2386_sf_fpu_d9_a16[256]; +extern const OpFn ops_2386_sf_fpu_d9_a32[256]; +extern const OpFn ops_2386_sf_fpu_da_a16[256]; +extern const OpFn ops_2386_sf_fpu_da_a32[256]; +extern const OpFn ops_2386_sf_fpu_db_a16[256]; +extern const OpFn ops_2386_sf_fpu_db_a32[256]; +extern const OpFn ops_2386_sf_fpu_dc_a16[32]; +extern const OpFn ops_2386_sf_fpu_dc_a32[32]; +extern const OpFn ops_2386_sf_fpu_dd_a16[256]; +extern const OpFn ops_2386_sf_fpu_dd_a32[256]; +extern const OpFn ops_2386_sf_fpu_de_a16[256]; +extern const OpFn ops_2386_sf_fpu_de_a32[256]; +extern const OpFn ops_2386_sf_fpu_df_a16[256]; +extern const OpFn ops_2386_sf_fpu_df_a32[256]; + +extern const OpFn ops_2386_fpu_287_d9_a16[256]; +extern const OpFn ops_2386_fpu_287_d9_a32[256]; +extern const OpFn ops_2386_fpu_287_da_a16[256]; +extern const OpFn ops_2386_fpu_287_da_a32[256]; +extern const OpFn ops_2386_fpu_287_db_a16[256]; +extern const OpFn ops_2386_fpu_287_db_a32[256]; +extern const OpFn ops_2386_fpu_287_dc_a16[32]; +extern const OpFn ops_2386_fpu_287_dc_a32[32]; +extern const OpFn ops_2386_fpu_287_dd_a16[256]; +extern const OpFn ops_2386_fpu_287_dd_a32[256]; +extern const OpFn ops_2386_fpu_287_de_a16[256]; +extern const OpFn ops_2386_fpu_287_de_a32[256]; +extern const OpFn ops_2386_fpu_287_df_a16[256]; +extern const OpFn ops_2386_fpu_287_df_a32[256]; + +extern const OpFn ops_2386_fpu_d8_a16[32]; +extern const OpFn ops_2386_fpu_d8_a32[32]; +extern const OpFn ops_2386_fpu_d9_a16[256]; +extern const OpFn ops_2386_fpu_d9_a32[256]; +extern const OpFn ops_2386_fpu_da_a16[256]; +extern const OpFn ops_2386_fpu_da_a32[256]; +extern const OpFn ops_2386_fpu_db_a16[256]; +extern const OpFn ops_2386_fpu_db_a32[256]; +extern const OpFn ops_2386_fpu_dc_a16[32]; +extern const OpFn ops_2386_fpu_dc_a32[32]; +extern const OpFn ops_2386_fpu_dd_a16[256]; +extern const OpFn ops_2386_fpu_dd_a32[256]; +extern const OpFn ops_2386_fpu_de_a16[256]; +extern const OpFn ops_2386_fpu_de_a32[256]; +extern const OpFn ops_2386_fpu_df_a16[256]; +extern const OpFn ops_2386_fpu_df_a32[256]; +extern const OpFn ops_2386_nofpu_a16[256]; +extern const OpFn ops_2386_nofpu_a32[256]; + +extern const OpFn ops_2386_REPE[1024]; +extern const OpFn ops_2386_REPNE[1024]; +extern const OpFn ops_2386_3DNOW[256]; + #define C0 (1 << 8) #define C1 (1 << 9) #define C2 (1 << 10) diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index ff657d708..b72cbc06c 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -35,7 +35,7 @@ opFEMMS(uint32_t fetchdat) static int opPAVGUSB(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -56,7 +56,7 @@ opPAVGUSB(uint32_t fetchdat) static int opPF2ID(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -71,7 +71,7 @@ opPF2ID(uint32_t fetchdat) static int opPF2IW(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -86,9 +86,9 @@ opPF2IW(uint32_t fetchdat) static int opPFACC(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); - float tempf; + float tempf; MMX_GETSRC(); @@ -103,9 +103,9 @@ opPFACC(uint32_t fetchdat) static int opPFNACC(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); - float tempf; + float tempf; MMX_GETSRC(); @@ -120,9 +120,9 @@ opPFNACC(uint32_t fetchdat) static int opPFPNACC(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); - float tempf; + float tempf; MMX_GETSRC(); @@ -137,9 +137,10 @@ opPFPNACC(uint32_t fetchdat) static int opPSWAPD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); - float tempf, tempf2; + float tempf; + float tempf2; MMX_GETSRC(); @@ -156,7 +157,7 @@ opPSWAPD(uint32_t fetchdat) static int opPFADD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -171,7 +172,7 @@ opPFADD(uint32_t fetchdat) static int opPFCMPEQ(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -186,7 +187,7 @@ opPFCMPEQ(uint32_t fetchdat) static int opPFCMPGE(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -201,7 +202,7 @@ opPFCMPGE(uint32_t fetchdat) static int opPFCMPGT(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -216,7 +217,7 @@ opPFCMPGT(uint32_t fetchdat) static int opPFMAX(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -233,7 +234,7 @@ opPFMAX(uint32_t fetchdat) static int opPFMIN(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -250,7 +251,7 @@ opPFMIN(uint32_t fetchdat) static int opPFMUL(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -294,7 +295,7 @@ opPFRCP(uint32_t fetchdat) static int opPFRCPIT1(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -309,7 +310,7 @@ opPFRCPIT1(uint32_t fetchdat) static int opPFRCPIT2(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -363,7 +364,7 @@ opPFRSQIT1(uint32_t fetchdat) static int opPFSUB(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -378,7 +379,7 @@ opPFSUB(uint32_t fetchdat) static int opPFSUBR(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -393,7 +394,7 @@ opPFSUBR(uint32_t fetchdat) static int opPI2FD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -408,7 +409,7 @@ opPI2FD(uint32_t fetchdat) static int opPI2FW(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -423,7 +424,7 @@ opPI2FW(uint32_t fetchdat) static int opPMULHRW(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { diff --git a/src/cpu/x86_ops_arith.h b/src/cpu/x86_ops_arith.h index 41c655d09..4e3f74e36 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu/x86_ops_arith.h @@ -340,6 +340,7 @@ static int opCMP_b_rmw_a16(uint32_t fetchdat) { uint8_t dst; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -359,6 +360,7 @@ static int opCMP_b_rmw_a32(uint32_t fetchdat) { uint8_t dst; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -379,6 +381,7 @@ static int opCMP_w_rmw_a16(uint32_t fetchdat) { uint16_t dst; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -398,6 +401,7 @@ static int opCMP_w_rmw_a32(uint32_t fetchdat) { uint16_t dst; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -418,6 +422,7 @@ static int opCMP_l_rmw_a16(uint32_t fetchdat) { uint32_t dst; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -437,6 +442,7 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat) { uint32_t dst; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -457,6 +463,7 @@ static int opCMP_b_rm_a16(uint32_t fetchdat) { uint8_t src; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -472,6 +479,7 @@ static int opCMP_b_rm_a32(uint32_t fetchdat) { uint8_t src; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -488,6 +496,7 @@ static int opCMP_w_rm_a16(uint32_t fetchdat) { uint16_t src; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -503,6 +512,7 @@ static int opCMP_w_rm_a32(uint32_t fetchdat) { uint16_t src; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -519,6 +529,7 @@ static int opCMP_l_rm_a16(uint32_t fetchdat) { uint32_t src; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -534,6 +545,7 @@ static int opCMP_l_rm_a32(uint32_t fetchdat) { uint32_t src; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -550,6 +562,7 @@ static int opCMP_AL_imm(uint32_t fetchdat) { uint8_t src = getbytef(); + setsub8(AL, src); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); @@ -560,6 +573,7 @@ static int opCMP_AX_imm(uint32_t fetchdat) { uint16_t src = getwordf(); + setsub16(AX, src); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); @@ -570,6 +584,7 @@ static int opCMP_EAX_imm(uint32_t fetchdat) { uint32_t src = getlong(); + if (cpu_state.abrt) return 1; setsub32(EAX, src); @@ -581,7 +596,9 @@ opCMP_EAX_imm(uint32_t fetchdat) static int opTEST_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2; + uint8_t temp; + uint8_t temp2; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -601,7 +618,9 @@ opTEST_b_a16(uint32_t fetchdat) static int opTEST_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2; + uint8_t temp; + uint8_t temp2; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -622,7 +641,9 @@ opTEST_b_a32(uint32_t fetchdat) static int opTEST_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2; + uint16_t temp; + uint16_t temp2; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -642,7 +663,9 @@ opTEST_w_a16(uint32_t fetchdat) static int opTEST_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2; + uint16_t temp; + uint16_t temp2; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -663,7 +686,9 @@ opTEST_w_a32(uint32_t fetchdat) static int opTEST_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2; + uint32_t temp; + uint32_t temp2; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -683,7 +708,9 @@ opTEST_l_a16(uint32_t fetchdat) static int opTEST_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2; + uint32_t temp; + uint32_t temp2; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); @@ -803,7 +830,8 @@ opTEST_EAX(uint32_t fetchdat) static int op80_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src; + uint8_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -823,7 +851,8 @@ op80_a16(uint32_t fetchdat) static int op80_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src; + uint8_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -843,7 +872,8 @@ op80_a32(uint32_t fetchdat) static int op81_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -863,7 +893,8 @@ op81_w_a16(uint32_t fetchdat) static int op81_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -883,7 +914,8 @@ op81_w_a32(uint32_t fetchdat) static int op81_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -903,7 +935,8 @@ op81_l_a16(uint32_t fetchdat) static int op81_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -924,7 +957,8 @@ op81_l_a32(uint32_t fetchdat) static int op83_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -946,7 +980,8 @@ op83_w_a16(uint32_t fetchdat) static int op83_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -969,7 +1004,8 @@ op83_w_a32(uint32_t fetchdat) static int op83_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -991,7 +1027,8 @@ op83_l_a16(uint32_t fetchdat) static int op83_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) diff --git a/src/cpu/x86_ops_atomic.h b/src/cpu/x86_ops_atomic.h index 7c7b409d2..43a3708e0 100644 --- a/src/cpu/x86_ops_atomic.h +++ b/src/cpu/x86_ops_atomic.h @@ -1,7 +1,9 @@ static int opCMPXCHG_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; + uint8_t temp; + uint8_t temp2 = AL; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); @@ -20,7 +22,9 @@ opCMPXCHG_b_a16(uint32_t fetchdat) static int opCMPXCHG_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; + uint8_t temp; + uint8_t temp2 = AL; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); @@ -40,7 +44,9 @@ opCMPXCHG_b_a32(uint32_t fetchdat) static int opCMPXCHG_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; + uint16_t temp; + uint16_t temp2 = AX; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); @@ -59,7 +65,9 @@ opCMPXCHG_w_a16(uint32_t fetchdat) static int opCMPXCHG_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; + uint16_t temp; + uint16_t temp2 = AX; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); @@ -79,7 +87,9 @@ opCMPXCHG_w_a32(uint32_t fetchdat) static int opCMPXCHG_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; + uint32_t temp; + uint32_t temp2 = EAX; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); @@ -98,7 +108,9 @@ opCMPXCHG_l_a16(uint32_t fetchdat) static int opCMPXCHG_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; + uint32_t temp; + uint32_t temp2 = EAX; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); @@ -115,10 +127,15 @@ opCMPXCHG_l_a32(uint32_t fetchdat) return 0; } +#ifndef OPS_286_386 static int opCMPXCHG8B_a16(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + uint32_t temp; + uint32_t temp_hi; + uint32_t temp2 = EAX; + uint32_t temp2_hi = EDX; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); @@ -145,7 +162,11 @@ opCMPXCHG8B_a16(uint32_t fetchdat) static int opCMPXCHG8B_a32(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + uint32_t temp; + uint32_t temp_hi; + uint32_t temp2 = EAX; + uint32_t temp2_hi = EDX; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); @@ -169,13 +190,16 @@ opCMPXCHG8B_a32(uint32_t fetchdat) cycles -= (cpu_mod == 3) ? 6 : 10; return 0; } +#endif /* dest = eab, src = r8 */ static int opXADD_b_a16(uint32_t fetchdat) { uint8_t temp; - uint8_t src, dest; + uint8_t src; + uint8_t dest; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = getr8(cpu_reg); @@ -195,7 +219,9 @@ static int opXADD_b_a32(uint32_t fetchdat) { uint8_t temp; - uint8_t src, dest; + uint8_t src; + uint8_t dest; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = getr8(cpu_reg); @@ -216,7 +242,9 @@ static int opXADD_w_a16(uint32_t fetchdat) { uint16_t temp; - uint16_t src, dest; + uint16_t src; + uint16_t dest; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = cpu_state.regs[cpu_reg].w; @@ -236,7 +264,9 @@ static int opXADD_w_a32(uint32_t fetchdat) { uint16_t temp; - uint16_t src, dest; + uint16_t src; + uint16_t dest; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = cpu_state.regs[cpu_reg].w; @@ -257,7 +287,9 @@ static int opXADD_l_a16(uint32_t fetchdat) { uint32_t temp; - uint32_t src, dest; + uint32_t src; + uint32_t dest; + fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = cpu_state.regs[cpu_reg].l; @@ -277,7 +309,9 @@ static int opXADD_l_a32(uint32_t fetchdat) { uint32_t temp; - uint32_t src, dest; + uint32_t src; + uint32_t dest; + fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); src = cpu_state.regs[cpu_reg].l; diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index d3ff97ead..b4779ab3e 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -19,6 +19,7 @@ static int opAAD(uint32_t fetchdat) { int base = getbytef(); + if (!cpu_isintel) base = 10; AL = (AH * base) + AL; @@ -33,6 +34,7 @@ static int opAAM(uint32_t fetchdat) { int base = getbytef(); + if (!base || !cpu_isintel) base = 10; AH = AL / base; @@ -63,7 +65,9 @@ opAAS(uint32_t fetchdat) static int opDAA(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw; + uint16_t old_AL; + uint16_t old_CF; flags_rebuild(); old_AL = AL; @@ -98,7 +102,9 @@ opDAA(uint32_t fetchdat) static int opDAS(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw; + uint16_t old_AL; + uint16_t old_CF; flags_rebuild(); old_AL = AL; diff --git a/src/cpu/x86_ops_bit.h b/src/cpu/x86_ops_bit.h index 8514e8e1c..b72142b5a 100644 --- a/src/cpu/x86_ops_bit.h +++ b/src/cpu/x86_ops_bit.h @@ -201,13 +201,17 @@ opBT_l_r_a32(uint32_t fetchdat) return 0; \ } +// clang-format off opBT(C, ^=) - opBT(R, &= ~) - opBT(S, |=) +opBT(R, &= ~) +opBT(S, |=) + // clang-format on - static int opBA_w_a16(uint32_t fetchdat) +static int +opBA_w_a16(uint32_t fetchdat) { - int tempc, count; + int tempc; + int count; uint16_t temp; fetch_ea_16(fetchdat); @@ -258,7 +262,8 @@ opBT(C, ^=) static int opBA_w_a32(uint32_t fetchdat) { - int tempc, count; + int tempc; + int count; uint16_t temp; fetch_ea_32(fetchdat); @@ -310,7 +315,8 @@ opBA_w_a32(uint32_t fetchdat) static int opBA_l_a16(uint32_t fetchdat) { - int tempc, count; + int tempc; + int count; uint32_t temp; fetch_ea_16(fetchdat); @@ -361,7 +367,8 @@ opBA_l_a16(uint32_t fetchdat) static int opBA_l_a32(uint32_t fetchdat) { - int tempc, count; + int tempc; + int count; uint32_t temp; fetch_ea_32(fetchdat); diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index 88899cef8..731f58ec8 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -189,8 +189,10 @@ static int opCALL_far_w(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint16_t new_cs, new_pc; + uint32_t old_cs; + uint32_t old_pc; + uint16_t new_cs; + uint16_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -209,8 +211,10 @@ opCALL_far_w(uint32_t fetchdat) static int opCALL_far_l(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint32_t new_cs, new_pc; + uint32_t old_cs; + uint32_t old_pc; + uint32_t new_cs; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -230,8 +234,10 @@ opCALL_far_l(uint32_t fetchdat) static int opFF_w_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; + uint16_t old_cs; + uint16_t new_cs; + uint32_t old_pc; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -392,8 +398,10 @@ opFF_w_a16(uint32_t fetchdat) static int opFF_w_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; + uint16_t old_cs; + uint16_t new_cs; + uint32_t old_pc; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -555,8 +563,10 @@ opFF_w_a32(uint32_t fetchdat) static int opFF_l_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; + uint16_t old_cs; + uint16_t new_cs; + uint32_t old_pc; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); @@ -717,8 +727,10 @@ opFF_l_a16(uint32_t fetchdat) static int opFF_l_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; + uint16_t old_cs; + uint16_t new_cs; + uint32_t old_pc; + uint32_t new_pc; int cycles_old = cycles; UN_USED(cycles_old); diff --git a/src/cpu/x86_ops_fpu.h b/src/cpu/x86_ops_fpu.h index 29e999941..849e24e3d 100644 --- a/src/cpu/x86_ops_fpu.h +++ b/src/cpu/x86_ops_fpu.h @@ -97,7 +97,9 @@ opWAIT(uint32_t fetchdat) return 1; } - // if (!cpu_use_dynarec && fpu_softfloat) { +#if 0 + if (!cpu_use_dynarec && fpu_softfloat) { +#endif if (fpu_softfloat) { if (fpu_state.swd & FPU_SW_Summary) { if (cr0 & 0x20) { diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index f2b07a1c4..ab9d02d25 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -46,10 +46,10 @@ opSYSEXIT(uint32_t fetchdat) static int sf_fx_save_stor_common(uint32_t fetchdat, int bits) { - uint8_t fxinst = 0; - uint32_t tag_byte; - unsigned index; - floatx80 reg; + uint8_t fxinst = 0; + uint32_t tag_byte; + unsigned index; + floatx80 reg; if (CPUID < 0x650) return ILLEGAL(fetchdat); @@ -129,33 +129,33 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits) /* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */ writememw(easeg, cpu_state.eaaddr + 6, fpu_state.foo); - /* - * x87 FPU IP Offset (32/64 bits) - * The contents of this field differ depending on the current - * addressing mode (16/32/64 bit) when the FXSAVE instruction was executed: - * + 64-bit mode - 64-bit IP offset - * + 32-bit mode - 32-bit IP offset - * + 16-bit mode - low 16 bits are IP offset; high 16 bits are reserved. - * x87 CS FPU IP Selector - * + 16 bit, in 16/32 bit mode only - */ + /* + * x87 FPU IP Offset (32/64 bits) + * The contents of this field differ depending on the current + * addressing mode (16/32/64 bit) when the FXSAVE instruction was executed: + * + 64-bit mode - 64-bit IP offset + * + 32-bit mode - 32-bit IP offset + * + 16-bit mode - low 16 bits are IP offset; high 16 bits are reserved. + * x87 CS FPU IP Selector + * + 16 bit, in 16/32 bit mode only + */ writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip); writememl(easeg, cpu_state.eaaddr + 12, fpu_state.fcs); - /* - * x87 FPU Instruction Operand (Data) Pointer Offset (32/64 bits) - * The contents of this field differ depending on the current - * addressing mode (16/32 bit) when the FXSAVE instruction was executed: - * + 64-bit mode - 64-bit offset - * + 32-bit mode - 32-bit offset - * + 16-bit mode - low 16 bits are offset; high 16 bits are reserved. - * x87 DS FPU Instruction Operand (Data) Pointer Selector - * + 16 bit, in 16/32 bit mode only - */ + /* + * x87 FPU Instruction Operand (Data) Pointer Offset (32/64 bits) + * The contents of this field differ depending on the current + * addressing mode (16/32 bit) when the FXSAVE instruction was executed: + * + 64-bit mode - 64-bit offset + * + 32-bit mode - 32-bit offset + * + 16-bit mode - low 16 bits are offset; high 16 bits are reserved. + * x87 DS FPU Instruction Operand (Data) Pointer Selector + * + 16 bit, in 16/32 bit mode only + */ writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp); writememl(easeg, cpu_state.eaaddr + 20, fpu_state.fds); - /* store i387 register file */ + /* store i387 register file */ for (index = 0; index < 8; index++) { const floatx80 fp = FPU_read_regi(index); @@ -172,70 +172,72 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits) static int fx_save_stor_common(uint32_t fetchdat, int bits) { - uint8_t fxinst = 0; - uint16_t twd = x87_gettag(); - uint32_t old_eaaddr = 0; - uint8_t ftwb = 0; - uint16_t rec_ftw = 0; - uint16_t fpus = 0; - int i, mmx_tags = 0; - uint16_t exp = 0x0000; - uint64_t mant = 0x0000000000000000ULL; - uint64_t fraction; - uint8_t jm, valid; - /* Exp_all_1 Exp_all_0 Frac_all_0 J M FTW_Valid | Ent - ----------------------------------------------+------ */ - uint8_t ftw_table_idx; - uint8_t ftw_table[48] = { 0x03, /* 0 0 0 0 0 0 | 0x00 */ - 0x02, /* 0 0 0 0 0 1 | 0x01 */ - 0x03, /* 0 0 0 0 0 0 | 0x02 */ - 0x02, /* 0 0 0 0 1 1 | 0x03 */ - 0x03, /* 0 0 0 1 0 0 | 0x04 */ - 0x00, /* 0 0 0 1 0 1 | 0x05 */ - 0x03, /* 0 0 0 1 1 0 | 0x06 */ - 0x00, /* 0 0 0 1 1 1 | 0x07 */ - 0x03, /* 0 0 1 0 0 0 | 0x08 */ - 0x02, /* 0 0 1 0 0 1 | 0x09 */ - 0x03, /* 0 0 1 0 1 0 | 0x0a - Impossible */ - 0x03, /* 0 0 1 0 1 1 | 0x0b - Impossible */ - 0x03, /* 0 0 1 1 0 0 | 0x0c */ - 0x02, /* 0 0 1 1 0 1 | 0x0d */ - 0x03, /* 0 0 1 1 1 0 | 0x0e - Impossible */ - 0x03, /* 0 0 1 1 1 1 | 0x0f - Impossible */ - 0x03, /* 0 1 0 0 0 0 | 0x10 */ - 0x02, /* 0 1 0 0 0 1 | 0x11 */ - 0x03, /* 0 1 0 0 1 0 | 0x12 */ - 0x02, /* 0 1 0 0 1 1 | 0x13 */ - 0x03, /* 0 1 0 1 0 0 | 0x14 */ - 0x02, /* 0 1 0 1 0 1 | 0x15 */ - 0x03, /* 0 1 0 1 1 0 | 0x16 */ - 0x02, /* 0 1 0 1 1 1 | 0x17 */ - 0x03, /* 0 1 1 0 0 0 | 0x18 */ - 0x01, /* 0 1 1 0 0 1 | 0x19 */ - 0x03, /* 0 1 1 0 1 0 | 0x1a - Impossible */ - 0x03, /* 0 1 1 0 1 1 | 0x1b - Impossible */ - 0x03, /* 0 1 1 1 0 0 | 0x1c */ - 0x01, /* 0 1 1 1 0 1 | 0x1d */ - 0x03, /* 0 1 1 1 1 0 | 0x1e - Impossible */ - 0x03, /* 0 1 1 1 1 1 | 0x1f - Impossible */ - 0x03, /* 1 0 0 0 0 0 | 0x20 */ - 0x02, /* 1 0 0 0 0 1 | 0x21 */ - 0x03, /* 1 0 0 0 1 0 | 0x22 */ - 0x02, /* 1 0 0 0 1 1 | 0x23 */ - 0x03, /* 1 0 0 1 0 0 | 0x24 */ - 0x02, /* 1 0 0 1 0 1 | 0x25 */ - 0x03, /* 1 0 0 1 1 0 | 0x26 */ - 0x02, /* 1 0 0 1 1 1 | 0x27 */ - 0x03, /* 1 0 1 0 0 0 | 0x28 */ - 0x02, /* 1 0 1 0 0 1 | 0x29 */ - 0x03, /* 1 0 1 0 1 0 | 0x2a - Impossible */ - 0x03, /* 1 0 1 0 1 1 | 0x2b - Impossible */ - 0x03, /* 1 0 1 1 0 0 | 0x2c */ - 0x02, /* 1 0 1 1 0 1 | 0x2d */ - 0x03, /* 1 0 1 1 1 0 | 0x2e - Impossible */ - 0x03 }; /* 1 0 1 1 1 1 | 0x2f - Impossible */ - /* M is the most significant bit of the franction, so it is impossible - for M to o be 1 when the fraction is all 0's. */ + uint8_t fxinst = 0; + uint16_t twd = x87_gettag(); + uint32_t old_eaaddr = 0; + uint8_t ftwb = 0; + uint16_t rec_ftw = 0; + uint16_t fpus = 0; + int i; + int mmx_tags = 0; + uint16_t exp = 0x0000; + uint64_t mant = 0x0000000000000000ULL; + uint64_t fraction; + uint8_t jm; + uint8_t valid; + /* Exp_all_1 Exp_all_0 Frac_all_0 J M FTW_Valid | Ent + ----------------------------------------------+------ */ + uint8_t ftw_table_idx; + uint8_t ftw_table[48] = { 0x03, /* 0 0 0 0 0 0 | 0x00 */ + 0x02, /* 0 0 0 0 0 1 | 0x01 */ + 0x03, /* 0 0 0 0 0 0 | 0x02 */ + 0x02, /* 0 0 0 0 1 1 | 0x03 */ + 0x03, /* 0 0 0 1 0 0 | 0x04 */ + 0x00, /* 0 0 0 1 0 1 | 0x05 */ + 0x03, /* 0 0 0 1 1 0 | 0x06 */ + 0x00, /* 0 0 0 1 1 1 | 0x07 */ + 0x03, /* 0 0 1 0 0 0 | 0x08 */ + 0x02, /* 0 0 1 0 0 1 | 0x09 */ + 0x03, /* 0 0 1 0 1 0 | 0x0a - Impossible */ + 0x03, /* 0 0 1 0 1 1 | 0x0b - Impossible */ + 0x03, /* 0 0 1 1 0 0 | 0x0c */ + 0x02, /* 0 0 1 1 0 1 | 0x0d */ + 0x03, /* 0 0 1 1 1 0 | 0x0e - Impossible */ + 0x03, /* 0 0 1 1 1 1 | 0x0f - Impossible */ + 0x03, /* 0 1 0 0 0 0 | 0x10 */ + 0x02, /* 0 1 0 0 0 1 | 0x11 */ + 0x03, /* 0 1 0 0 1 0 | 0x12 */ + 0x02, /* 0 1 0 0 1 1 | 0x13 */ + 0x03, /* 0 1 0 1 0 0 | 0x14 */ + 0x02, /* 0 1 0 1 0 1 | 0x15 */ + 0x03, /* 0 1 0 1 1 0 | 0x16 */ + 0x02, /* 0 1 0 1 1 1 | 0x17 */ + 0x03, /* 0 1 1 0 0 0 | 0x18 */ + 0x01, /* 0 1 1 0 0 1 | 0x19 */ + 0x03, /* 0 1 1 0 1 0 | 0x1a - Impossible */ + 0x03, /* 0 1 1 0 1 1 | 0x1b - Impossible */ + 0x03, /* 0 1 1 1 0 0 | 0x1c */ + 0x01, /* 0 1 1 1 0 1 | 0x1d */ + 0x03, /* 0 1 1 1 1 0 | 0x1e - Impossible */ + 0x03, /* 0 1 1 1 1 1 | 0x1f - Impossible */ + 0x03, /* 1 0 0 0 0 0 | 0x20 */ + 0x02, /* 1 0 0 0 0 1 | 0x21 */ + 0x03, /* 1 0 0 0 1 0 | 0x22 */ + 0x02, /* 1 0 0 0 1 1 | 0x23 */ + 0x03, /* 1 0 0 1 0 0 | 0x24 */ + 0x02, /* 1 0 0 1 0 1 | 0x25 */ + 0x03, /* 1 0 0 1 1 0 | 0x26 */ + 0x02, /* 1 0 0 1 1 1 | 0x27 */ + 0x03, /* 1 0 1 0 0 0 | 0x28 */ + 0x02, /* 1 0 1 0 0 1 | 0x29 */ + 0x03, /* 1 0 1 0 1 0 | 0x2a - Impossible */ + 0x03, /* 1 0 1 0 1 1 | 0x2b - Impossible */ + 0x03, /* 1 0 1 1 0 0 | 0x2c */ + 0x02, /* 1 0 1 1 0 1 | 0x2d */ + 0x03, /* 1 0 1 1 1 0 | 0x2e - Impossible */ + 0x03 }; /* 1 0 1 1 1 1 | 0x2f - Impossible */ + /* M is the most significant bit of the franction, so it is impossible + for M to o be 1 when the fraction is all 0's. */ if (CPUID < 0x650) return ILLEGAL(fetchdat); @@ -285,11 +287,11 @@ fx_save_stor_common(uint32_t fetchdat, int bits) for (i = 0; i <= 7; i++) { cpu_state.eaaddr = old_eaaddr + 32 + (i << 4); - mant = readmemq(easeg, cpu_state.eaaddr); - fraction = mant & 0x7fffffffffffffffULL; - exp = readmemw(easeg, cpu_state.eaaddr + 8); - jm = (mant >> 62) & 0x03; - valid = !(ftwb & (1 << i)); + mant = readmemq(easeg, cpu_state.eaaddr); + fraction = mant & 0x7fffffffffffffffULL; + exp = readmemw(easeg, cpu_state.eaaddr + 8); + jm = (mant >> 62) & 0x03; + valid = !(ftwb & (1 << i)); ftw_table_idx = (!!(exp == 0x1111)) << 5; ftw_table_idx |= (!!(exp == 0x0000)) << 4; @@ -379,7 +381,7 @@ fx_save_stor_common(uint32_t fetchdat, int bits) static int opFXSAVESTOR_a16(uint32_t fetchdat) { - if (fpu_softfloat) + if (fpu_softfloat) return sf_fx_save_stor_common(fetchdat, 16); return fx_save_stor_common(fetchdat, 16); diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index a1503a75e..091e0da35 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -86,9 +86,10 @@ opJ(L) opJ(NL) opJ(LE) opJ(NLE) -// clang-format on + // clang-format on - static int opLOOPNE_w(uint32_t fetchdat) +static int +opLOOPNE_w(uint32_t fetchdat) { int8_t offset = (int8_t) getbytef(); CX--; @@ -271,8 +272,10 @@ opJMP_r32(uint32_t fetchdat) static int opJMP_far_a16(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; uint32_t old_pc; + addr = getwordf(); seg = getword(); if (cpu_state.abrt) @@ -289,7 +292,9 @@ static int opJMP_far_a32(uint32_t fetchdat) { uint16_t seg; - uint32_t addr, old_pc; + uint32_t addr; + uint32_t old_pc; + addr = getlong(); seg = getword(); if (cpu_state.abrt) @@ -307,6 +312,7 @@ static int opCALL_r16(uint32_t fetchdat) { int16_t addr = (int16_t) getwordf(); + PUSH_W(cpu_state.pc); cpu_state.pc += addr; cpu_state.pc &= 0xffff; @@ -320,6 +326,7 @@ static int opCALL_r32(uint32_t fetchdat) { int32_t addr = getlong(); + if (cpu_state.abrt) return 1; PUSH_L(cpu_state.pc); diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index e49076388..49e7cbe3b 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -55,7 +55,8 @@ opF6_a16(uint32_t fetchdat) int tempws2 = 0; uint16_t tempw = 0; uint16_t src16; - uint8_t src, dst; + uint8_t src; + uint8_t dst; int8_t temps; fetch_ea_16(fetchdat); @@ -173,7 +174,8 @@ opF6_a32(uint32_t fetchdat) int tempws2 = 0; uint16_t tempw = 0; uint16_t src16; - uint8_t src, dst; + uint8_t src; + uint8_t dst; int8_t temps; fetch_ea_32(fetchdat); @@ -287,7 +289,7 @@ static int opF7_w_a16(uint32_t fetchdat) { uint32_t templ; - uint32_t templ2 = 0; + uint32_t templ2 = 0; int tempws; int tempws2 = 0; int16_t temps16; @@ -400,11 +402,12 @@ static int opF7_w_a32(uint32_t fetchdat) { uint32_t templ; - uint32_t templ2 = 0; + uint32_t templ2 = 0; int tempws; int tempws2 = 1; int16_t temps16; - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -514,7 +517,8 @@ static int opF7_l_a16(uint32_t fetchdat) { uint64_t temp64; - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -606,7 +610,8 @@ static int opF7_l_a32(uint32_t fetchdat) { uint64_t temp64; - uint32_t src, dst; + uint32_t src; + uint32_t dst; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -739,7 +744,8 @@ opLOCK(uint32_t fetchdat) static int opBOUND_w_a16(uint32_t fetchdat) { - int16_t low, high; + int16_t low; + int16_t high; fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -761,7 +767,8 @@ opBOUND_w_a16(uint32_t fetchdat) static int opBOUND_w_a32(uint32_t fetchdat) { - int16_t low, high; + int16_t low; + int16_t high; fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -784,7 +791,8 @@ opBOUND_w_a32(uint32_t fetchdat) static int opBOUND_l_a16(uint32_t fetchdat) { - int32_t low, high; + int32_t low; + int32_t high; fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -806,7 +814,8 @@ opBOUND_l_a16(uint32_t fetchdat) static int opBOUND_l_a32(uint32_t fetchdat) { - int32_t low, high; + int32_t low; + int32_t high; fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); diff --git a/src/cpu/x86_ops_mmx.c b/src/cpu/x86_ops_mmx.c index 1afc4fba2..6d4dd5557 100644 --- a/src/cpu/x86_ops_mmx.c +++ b/src/cpu/x86_ops_mmx.c @@ -27,7 +27,7 @@ #include "x86_flags.h" #include "x86seg.h" -MMX_REG *MMP[8]; +MMX_REG *MMP[8]; uint16_t *MMEP[8]; static uint16_t MME[8]; @@ -40,10 +40,10 @@ mmx_init(void) for (uint8_t i = 0; i < 8; i++) { if (fpu_softfloat) { - MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction; + MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction; MMEP[i] = (uint16_t *) &fpu_state.st_space[i].exp; } else { - MMP[i] = &(cpu_state.MM[i]); + MMP[i] = &(cpu_state.MM[i]); MMEP[i] = &(MME[i]); } } diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index 47751d059..ab5e19762 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -1,12 +1,12 @@ -#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val))) -#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val))) -#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) -#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) +#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val))) +#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val))) +#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) +#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) #define MMX_GETREGP(r) MMP[r] -#define MMX_GETREG(r) *(MMP[r]) +#define MMX_GETREG(r) *(MMP[r]) -#define MMX_SETEXP(r) \ +#define MMX_SETEXP(r) \ *(MMEP[r]) = 0xffff #define MMX_GETSRC() \ diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index 642e99c8a..099789970 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -1,7 +1,7 @@ static int opPADDB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -27,7 +27,7 @@ opPADDB_a16(uint32_t fetchdat) static int opPADDB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -54,7 +54,7 @@ opPADDB_a32(uint32_t fetchdat) static int opPADDW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -76,7 +76,7 @@ opPADDW_a16(uint32_t fetchdat) static int opPADDW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -99,7 +99,7 @@ opPADDW_a32(uint32_t fetchdat) static int opPADDD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -119,7 +119,7 @@ opPADDD_a16(uint32_t fetchdat) static int opPADDD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -140,7 +140,7 @@ opPADDD_a32(uint32_t fetchdat) static int opPADDSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -166,7 +166,7 @@ opPADDSB_a16(uint32_t fetchdat) static int opPADDSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -193,7 +193,7 @@ opPADDSB_a32(uint32_t fetchdat) static int opPADDUSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -219,7 +219,7 @@ opPADDUSB_a16(uint32_t fetchdat) static int opPADDUSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -246,7 +246,7 @@ opPADDUSB_a32(uint32_t fetchdat) static int opPADDSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -268,7 +268,7 @@ opPADDSW_a16(uint32_t fetchdat) static int opPADDSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -291,7 +291,7 @@ opPADDSW_a32(uint32_t fetchdat) static int opPADDUSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -313,7 +313,7 @@ opPADDUSW_a16(uint32_t fetchdat) static int opPADDUSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -336,7 +336,7 @@ opPADDUSW_a32(uint32_t fetchdat) static int opPMADDWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -363,7 +363,7 @@ opPMADDWD_a16(uint32_t fetchdat) static int opPMADDWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -391,7 +391,7 @@ opPMADDWD_a32(uint32_t fetchdat) static int opPMULLW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -422,7 +422,7 @@ opPMULLW_a16(uint32_t fetchdat) static int opPMULLW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -454,7 +454,7 @@ opPMULLW_a32(uint32_t fetchdat) static int opPMULHW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -485,7 +485,7 @@ opPMULHW_a16(uint32_t fetchdat) static int opPMULHW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -517,7 +517,7 @@ opPMULHW_a32(uint32_t fetchdat) static int opPSUBB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -543,7 +543,7 @@ opPSUBB_a16(uint32_t fetchdat) static int opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -570,7 +570,7 @@ opPSUBB_a32(uint32_t fetchdat) static int opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -592,7 +592,7 @@ opPSUBW_a16(uint32_t fetchdat) static int opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -615,7 +615,7 @@ opPSUBW_a32(uint32_t fetchdat) static int opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -635,7 +635,7 @@ opPSUBD_a16(uint32_t fetchdat) static int opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -656,7 +656,7 @@ opPSUBD_a32(uint32_t fetchdat) static int opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -682,7 +682,7 @@ opPSUBSB_a16(uint32_t fetchdat) static int opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -709,7 +709,7 @@ opPSUBSB_a32(uint32_t fetchdat) static int opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -735,7 +735,7 @@ opPSUBUSB_a16(uint32_t fetchdat) static int opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -762,7 +762,7 @@ opPSUBUSB_a32(uint32_t fetchdat) static int opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -784,7 +784,7 @@ opPSUBSW_a16(uint32_t fetchdat) static int opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -807,7 +807,7 @@ opPSUBSW_a32(uint32_t fetchdat) static int opPSUBUSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -829,7 +829,7 @@ opPSUBUSW_a16(uint32_t fetchdat) static int opPSUBUSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index b3081b8e8..141dba6bc 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -1,7 +1,7 @@ static int opPCMPEQB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -27,7 +27,7 @@ opPCMPEQB_a16(uint32_t fetchdat) static int opPCMPEQB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -54,7 +54,7 @@ opPCMPEQB_a32(uint32_t fetchdat) static int opPCMPGTB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -80,7 +80,7 @@ opPCMPGTB_a16(uint32_t fetchdat) static int opPCMPGTB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -107,7 +107,7 @@ opPCMPGTB_a32(uint32_t fetchdat) static int opPCMPEQW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -129,7 +129,7 @@ opPCMPEQW_a16(uint32_t fetchdat) static int opPCMPEQW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -152,7 +152,7 @@ opPCMPEQW_a32(uint32_t fetchdat) static int opPCMPGTW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -174,7 +174,7 @@ opPCMPGTW_a16(uint32_t fetchdat) static int opPCMPGTW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -197,7 +197,7 @@ opPCMPGTW_a32(uint32_t fetchdat) static int opPCMPEQD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -217,7 +217,7 @@ opPCMPEQD_a16(uint32_t fetchdat) static int opPCMPEQD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -238,7 +238,7 @@ opPCMPEQD_a32(uint32_t fetchdat) static int opPCMPGTD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -258,7 +258,7 @@ opPCMPGTD_a16(uint32_t fetchdat) static int opPCMPGTD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index 26d7c1693..617219845 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -1,7 +1,7 @@ static int opPAND_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -20,7 +20,7 @@ opPAND_a16(uint32_t fetchdat) static int opPAND_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -40,7 +40,7 @@ opPAND_a32(uint32_t fetchdat) static int opPANDN_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -59,7 +59,7 @@ opPANDN_a16(uint32_t fetchdat) static int opPANDN_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -79,7 +79,7 @@ opPANDN_a32(uint32_t fetchdat) static int opPOR_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -98,7 +98,7 @@ opPOR_a16(uint32_t fetchdat) static int opPOR_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -118,7 +118,7 @@ opPOR_a32(uint32_t fetchdat) static int opPXOR_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -137,7 +137,7 @@ opPXOR_a16(uint32_t fetchdat) static int opPXOR_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index 65bbb0c01..c72c8143d 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -115,7 +115,7 @@ opMOVD_mm_l_a32(uint32_t fetchdat) static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) { - MMX_REG *op; + const MMX_REG *op; if (in_smm) return opSMINT(fetchdat); @@ -144,7 +144,7 @@ opMOVD_mm_l_a16_cx(uint32_t fetchdat) static int opMOVD_mm_l_a32_cx(uint32_t fetchdat) { - MMX_REG *op; + const MMX_REG *op; if (in_smm) return opSMINT(fetchdat); @@ -176,14 +176,14 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat) { uint64_t dst; - MMX_REG src; + MMX_REG src; MMX_REG *op; MMX_ENTER(); fetch_ea_16(fetchdat); src = MMX_GETREG(cpu_rm); - op = MMX_GETREGP(cpu_reg); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { op->q = src.q; @@ -206,14 +206,14 @@ static int opMOVQ_q_mm_a32(uint32_t fetchdat) { uint64_t dst; - MMX_REG src; + MMX_REG src; MMX_REG *op; MMX_ENTER(); fetch_ea_32(fetchdat); src = MMX_GETREG(cpu_rm); - op = MMX_GETREGP(cpu_reg); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { op->q = src.q; @@ -236,7 +236,7 @@ opMOVQ_q_mm_a32(uint32_t fetchdat) static int opMOVQ_mm_q_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -266,7 +266,7 @@ opMOVQ_mm_q_a16(uint32_t fetchdat) static int opMOVQ_mm_q_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index 90590638b..90ed1b6d2 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -2,7 +2,7 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat) { uint32_t usrc; - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -32,7 +32,7 @@ static int opPUNPCKLDQ_a32(uint32_t fetchdat) { uint32_t usrc; - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -62,7 +62,7 @@ opPUNPCKLDQ_a32(uint32_t fetchdat) static int opPUNPCKHDQ_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -82,7 +82,7 @@ opPUNPCKHDQ_a16(uint32_t fetchdat) static int opPUNPCKHDQ_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -103,7 +103,7 @@ opPUNPCKHDQ_a32(uint32_t fetchdat) static int opPUNPCKLBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -129,7 +129,7 @@ opPUNPCKLBW_a16(uint32_t fetchdat) static int opPUNPCKLBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -156,7 +156,7 @@ opPUNPCKLBW_a32(uint32_t fetchdat) static int opPUNPCKHBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -182,7 +182,7 @@ opPUNPCKHBW_a16(uint32_t fetchdat) static int opPUNPCKHBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -209,7 +209,7 @@ opPUNPCKHBW_a32(uint32_t fetchdat) static int opPUNPCKLWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -231,7 +231,7 @@ opPUNPCKLWD_a16(uint32_t fetchdat) static int opPUNPCKLWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -254,7 +254,7 @@ opPUNPCKLWD_a32(uint32_t fetchdat) static int opPUNPCKHWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -276,7 +276,7 @@ opPUNPCKHWD_a16(uint32_t fetchdat) static int opPUNPCKHWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -299,7 +299,7 @@ opPUNPCKHWD_a32(uint32_t fetchdat) static int opPACKSSWB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -325,7 +325,7 @@ opPACKSSWB_a16(uint32_t fetchdat) static int opPACKSSWB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -352,7 +352,7 @@ opPACKSSWB_a32(uint32_t fetchdat) static int opPACKUSWB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -378,7 +378,7 @@ opPACKUSWB_a16(uint32_t fetchdat) static int opPACKUSWB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -405,14 +405,14 @@ opPACKUSWB_a32(uint32_t fetchdat) static int opPACKSSDW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; - MMX_REG dst2; + MMX_REG dst2; MMX_ENTER(); fetch_ea_16(fetchdat); - dst = MMX_GETREGP(cpu_reg); + dst = MMX_GETREGP(cpu_reg); dst2 = *dst; MMX_GETSRC(); @@ -429,14 +429,14 @@ opPACKSSDW_a16(uint32_t fetchdat) static int opPACKSSDW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; - MMX_REG dst2; + MMX_REG dst2; MMX_ENTER(); fetch_ea_32(fetchdat); - dst = MMX_GETREGP(cpu_reg); + dst = MMX_GETREGP(cpu_reg); dst2 = *dst; MMX_GETSRC(); diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index c0c80e87e..04aeb8a9a 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -13,9 +13,9 @@ static int opPSxxW_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; MMX_REG *dst; cpu_state.pc += 2; @@ -67,7 +67,7 @@ static int opPSLLW_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -94,7 +94,7 @@ static int opPSLLW_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -122,7 +122,7 @@ static int opPSRLW_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -149,7 +149,7 @@ static int opPSRLW_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -177,7 +177,7 @@ static int opPSRAW_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -203,7 +203,7 @@ static int opPSRAW_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -229,9 +229,9 @@ opPSRAW_a32(uint32_t fetchdat) static int opPSxxD_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; MMX_REG *dst; cpu_state.pc += 2; @@ -278,7 +278,7 @@ static int opPSLLD_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -303,7 +303,7 @@ static int opPSLLD_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -329,7 +329,7 @@ static int opPSRLD_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -354,7 +354,7 @@ static int opPSRLD_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -380,7 +380,7 @@ static int opPSRAD_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -404,7 +404,7 @@ static int opPSRAD_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -428,9 +428,9 @@ opPSRAD_a32(uint32_t fetchdat) static int opPSxxQ_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; MMX_REG *dst; cpu_state.pc += 2; @@ -474,7 +474,7 @@ static int opPSLLQ_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -497,7 +497,7 @@ static int opPSLLQ_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -521,7 +521,7 @@ static int opPSRLQ_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -544,7 +544,7 @@ static int opPSRLQ_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index 063a33516..e77876d5c 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -769,83 +769,84 @@ opMOV_r_l_a32(uint32_t fetchdat) return 0; } -#define opCMOV(condition) \ - static int opCMOV##condition##_w_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_##condition) { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ - temp = geteaw(); \ - if (cpu_state.abrt) \ - return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV##condition##_w_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_##condition) { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ - temp = geteaw(); \ - if (cpu_state.abrt) \ - return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV##condition##_l_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_##condition) { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - temp = geteal(); \ - if (cpu_state.abrt) \ - return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV##condition##_l_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_##condition) { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else { \ - uint32_t temp; \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - temp = geteal(); \ - if (cpu_state.abrt) \ - return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } +#ifndef OPS_286_386 +# define opCMOV(condition) \ + static int opCMOV##condition##_w_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_w_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } // clang-format off opCMOV(O) @@ -865,3 +866,4 @@ opCMOV(NL) opCMOV(LE) opCMOV(NLE) // clang-format on +#endif diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index d95116c93..b0c841f83 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -251,12 +251,17 @@ opMOV_DRx_r_a32(uint32_t fetchdat) static void opMOV_r_TRx(void) { - // uint32_t base; +#if 0 + uint32_t base; + + base = _tr[4] & 0xfffff800; +#endif - // base = _tr[4] & 0xfffff800; switch (cpu_reg) { case 3: - // pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); +#if 0 + pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); +#endif _tr[3] = *(uint32_t *) &(_cache[cache_index]); cache_index = (cache_index + 4) & 0xf; break; @@ -293,42 +298,57 @@ static void opMOV_TRx_r(void) { uint32_t base; - int i, ctl; + int i; + int ctl; _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; base = _tr[4] & 0xfffff800; ctl = _tr[5] & 3; switch (cpu_reg) { case 3: - // pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); +#if 0 + pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); +#endif *(uint32_t *) &(_cache[cache_index]) = _tr[3]; cache_index = (cache_index + 4) & 0xf; break; case 4: - // if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) - // pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); +#if 0 + if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) + pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); +#endif break; case 5: - // pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); +#if 0 + pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); +#endif if (!(_tr[5] & (1 << 19))) { switch (ctl) { case 0: - // pclog(" Cache fill or read...\n", base); +#if 0 + pclog(" Cache fill or read...\n", base); +#endif break; case 1: base += (_tr[5] & 0x7f0); - // pclog(" Writing 16 bytes to %08X...\n", base); +#if 0 + pclog(" Writing 16 bytes to %08X...\n", base); +#endif for (i = 0; i < 16; i += 4) mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); break; case 2: base += (_tr[5] & 0x7f0); - // pclog(" Reading 16 bytes from %08X...\n", base); +#if 0 + pclog(" Reading 16 bytes from %08X...\n", base); +#endif for (i = 0; i < 16; i += 4) *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); break; case 3: - // pclog(" Cache invalidate/flush...\n", base); +#if 0 + pclog(" Cache invalidate/flush...\n", base); +#endif break; } } diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index c6bfd9933..2498a7d90 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -258,7 +258,8 @@ opMOV_seg_w_a32(uint32_t fetchdat) static int opLDS_w_a16(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -280,7 +281,8 @@ opLDS_w_a16(uint32_t fetchdat) static int opLDS_w_a32(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -349,7 +351,8 @@ opLDS_l_a32(uint32_t fetchdat) static int opLSS_w_a16(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -371,7 +374,8 @@ opLSS_w_a16(uint32_t fetchdat) static int opLSS_w_a32(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr; + uint16_t seg; fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); @@ -532,4 +536,4 @@ opLSS_l_a32(uint32_t fetchdat) opLsel(ES, cpu_state.seg_es) opLsel(FS, cpu_state.seg_fs) opLsel(GS, cpu_state.seg_gs) -// clang-format on + // clang-format on diff --git a/src/cpu/x86_ops_mul.h b/src/cpu/x86_ops_mul.h index 552a9973a..aa7526e75 100644 --- a/src/cpu/x86_ops_mul.h +++ b/src/cpu/x86_ops_mul.h @@ -2,7 +2,8 @@ static int opIMUL_w_iw_a16(uint32_t fetchdat) { int32_t templ; - int16_t tempw, tempw2; + int16_t tempw; + int16_t tempw2; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -31,7 +32,8 @@ static int opIMUL_w_iw_a32(uint32_t fetchdat) { int32_t templ; - int16_t tempw, tempw2; + int16_t tempw; + int16_t tempw2; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -61,7 +63,8 @@ static int opIMUL_l_il_a16(uint32_t fetchdat) { int64_t temp64; - int32_t templ, templ2; + int32_t templ; + int32_t templ2; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -90,7 +93,8 @@ static int opIMUL_l_il_a32(uint32_t fetchdat) { int64_t temp64; - int32_t templ, templ2; + int32_t templ; + int32_t templ2; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -120,7 +124,8 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat) { int32_t templ; - int16_t tempw, tempw2; + int16_t tempw; + int16_t tempw2; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -151,7 +156,8 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat) { int32_t templ; - int16_t tempw, tempw2; + int16_t tempw; + int16_t tempw2; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -183,7 +189,8 @@ static int opIMUL_l_ib_a16(uint32_t fetchdat) { int64_t temp64; - int32_t templ, templ2; + int32_t templ; + int32_t templ2; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -214,7 +221,8 @@ static int opIMUL_l_ib_a32(uint32_t fetchdat) { int64_t temp64; - int32_t templ, templ2; + int32_t templ; + int32_t templ2; fetch_ea_32(fetchdat); if (cpu_mod != 3) diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index c8e146450..1254d7289 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -179,10 +179,16 @@ opLAR(w_a16, fetch_ea_16, 0, 0) static int op0F00_common(uint32_t fetchdat, int ea32) { - int dpl, valid, granularity; - uint32_t addr, base, limit; - uint16_t desc, sel; - uint8_t access, ar_high; + int dpl; + int valid; + int granularity; + uint32_t addr; + uint32_t base; + uint32_t limit; + uint16_t desc; + uint16_t sel; + uint8_t access; + uint8_t ar_high; switch (rmdat & 0x38) { case 0x00: /*SLDT*/ @@ -356,7 +362,9 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { uint32_t base; - uint16_t limit, tempw; + uint16_t limit; + uint16_t tempw; + switch (rmdat & 0x38) { case 0x00: /*SGDT*/ if (cpu_mod != 3) diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu/x86_ops_prefix.h index eba59c17a..8a7357386 100644 --- a/src/cpu/x86_ops_prefix.h +++ b/src/cpu/x86_ops_prefix.h @@ -88,9 +88,10 @@ op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes) op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes) op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) -// clang-format on + // clang-format on - static int op_66(uint32_t fetchdat) /*Data size select*/ +static int +op_66(uint32_t fetchdat) /*Data size select*/ { fetchdat = fastreadl(cs + cpu_state.pc); if (cpu_state.abrt) diff --git a/src/cpu/x86_ops_rep_2386.h b/src/cpu/x86_ops_rep_2386.h new file mode 100644 index 000000000..b6f64e90d --- /dev/null +++ b/src/cpu/x86_ops_rep_2386.h @@ -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); +} diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index ec200f2d7..64da566d3 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -190,7 +190,9 @@ opIRET(uint32_t fetchdat) if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { if (cr4 & CR4_VME) { - uint16_t new_pc, new_cs, new_flags; + uint16_t new_pc; + uint16_t new_cs; + uint16_t new_flags; new_pc = readmemw(ss, SP); new_cs = readmemw(ss, ((SP + 2) & 0xffff)); diff --git a/src/cpu/x86_ops_set.h b/src/cpu/x86_ops_set.h index 30c076a6e..75caa4491 100644 --- a/src/cpu/x86_ops_set.h +++ b/src/cpu/x86_ops_set.h @@ -36,4 +36,4 @@ opSET(L) opSET(NL) opSET(LE) opSET(NLE) -// clang-format on + // clang-format on diff --git a/src/cpu/x86_ops_shift.h b/src/cpu/x86_ops_shift.h index 9c11a32f0..1394cf420 100644 --- a/src/cpu/x86_ops_shift.h +++ b/src/cpu/x86_ops_shift.h @@ -605,7 +605,8 @@ opC0_a16(uint32_t fetchdat) { int c; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -624,7 +625,8 @@ opC0_a32(uint32_t fetchdat) { int c; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -643,7 +645,8 @@ opC1_w_a16(uint32_t fetchdat) { int c; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -662,7 +665,8 @@ opC1_w_a32(uint32_t fetchdat) { int c; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -681,7 +685,8 @@ opC1_l_a16(uint32_t fetchdat) { int c; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -700,7 +705,8 @@ opC1_l_a32(uint32_t fetchdat) { int c; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -720,7 +726,8 @@ opD0_a16(uint32_t fetchdat) { int c = 1; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -736,7 +743,8 @@ opD0_a32(uint32_t fetchdat) { int c = 1; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -752,7 +760,8 @@ opD1_w_a16(uint32_t fetchdat) { int c = 1; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -768,7 +777,8 @@ opD1_w_a32(uint32_t fetchdat) { int c = 1; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -784,7 +794,8 @@ opD1_l_a16(uint32_t fetchdat) { int c = 1; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -800,7 +811,8 @@ opD1_l_a32(uint32_t fetchdat) { int c = 1; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -817,7 +829,8 @@ opD2_a16(uint32_t fetchdat) { int c; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -834,7 +847,8 @@ opD2_a32(uint32_t fetchdat) { int c; int tempc; - uint8_t temp, temp2 = 0; + uint8_t temp; + uint8_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -851,7 +865,8 @@ opD3_w_a16(uint32_t fetchdat) { int c; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -868,7 +883,8 @@ opD3_w_a32(uint32_t fetchdat) { int c; int tempc; - uint16_t temp, temp2 = 0; + uint16_t temp; + uint16_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -885,7 +901,8 @@ opD3_l_a16(uint32_t fetchdat) { int c; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -902,7 +919,8 @@ opD3_l_a32(uint32_t fetchdat) { int c; int tempc; - uint32_t temp, temp2 = 0; + uint32_t temp; + uint32_t temp2 = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) @@ -1053,4 +1071,4 @@ opSHxD(SHLD_w) opSHxD(SHLD_l) opSHxD(SHRD_w) opSHxD(SHRD_l) -// clang-format on + // clang-format on diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 8217a9e5a..8fa66e082 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -189,22 +189,50 @@ static int opPOPA_l(uint32_t fetchdat) { if (stack32) { - EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ESP + 16); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ESP + 20); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1; + EDI = readmeml(ss, ESP); + if (cpu_state.abrt) + return 1; + ESI = readmeml(ss, ESP + 4); + if (cpu_state.abrt) + return 1; + EBP = readmeml(ss, ESP + 8); + if (cpu_state.abrt) + return 1; + EBX = readmeml(ss, ESP + 16); + if (cpu_state.abrt) + return 1; + EDX = readmeml(ss, ESP + 20); + if (cpu_state.abrt) + return 1; + ECX = readmeml(ss, ESP + 24); + if (cpu_state.abrt) + return 1; + EAX = readmeml(ss, ESP + 28); + if (cpu_state.abrt) + return 1; ESP += 32; } else { - EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (cpu_state.abrt) return 1; + EDI = readmeml(ss, ((SP) &0xFFFF)); + if (cpu_state.abrt) + return 1; + ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); + if (cpu_state.abrt) + return 1; SP += 32; } CLOCK_CYCLES((is486) ? 9 : 24); @@ -379,9 +407,13 @@ opENTER_w(uint32_t fetchdat) { uint16_t offset; int count; - uint32_t tempEBP, tempESP, frame_ptr; + uint32_t tempEBP; + uint32_t tempESP; + uint32_t frame_ptr; #ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; + int reads = 0; + int writes = 1; + int instr_cycles = 0; #endif uint16_t tempw; @@ -448,9 +480,13 @@ opENTER_l(uint32_t fetchdat) { uint16_t offset; int count; - uint32_t tempEBP, tempESP, frame_ptr; + uint32_t tempEBP; + uint32_t tempESP; + uint32_t frame_ptr; #ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; + int reads = 0; + int writes = 1; + int instr_cycles = 0; #endif uint32_t templ; diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index c9ba94760..619386fcb 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -219,7 +219,8 @@ opMOVSL_a32(uint32_t fetchdat) static int opCMPSB_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src; + uint8_t dst; addr64 = addr64_2 = 0x00000000; @@ -259,7 +260,8 @@ opCMPSB_a16(uint32_t fetchdat) static int opCMPSB_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src; + uint8_t dst; addr64 = addr64_2 = 0x00000000; @@ -300,7 +302,8 @@ opCMPSB_a32(uint32_t fetchdat) static int opCMPSW_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; addr64a[0] = addr64a[1] = 0x00000000; addr64a_2[0] = addr64a_2[1] = 0x00000000; @@ -341,7 +344,8 @@ opCMPSW_a16(uint32_t fetchdat) static int opCMPSW_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src; + uint16_t dst; addr64a[0] = addr64a[1] = 0x00000000; addr64a_2[0] = addr64a_2[1] = 0x00000000; @@ -383,7 +387,8 @@ opCMPSW_a32(uint32_t fetchdat) static int opCMPSL_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; @@ -424,7 +429,8 @@ opCMPSL_a16(uint32_t fetchdat) static int opCMPSL_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src; + uint32_t dst; addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; diff --git a/src/cpu/x86_ops_string_2386.h b/src/cpu/x86_ops_string_2386.h new file mode 100644 index 000000000..98875e54f --- /dev/null +++ b/src/cpu/x86_ops_string_2386.h @@ -0,0 +1,1061 @@ +static int +opMOVSB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + addr64 = addr64_2 = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + + do_mmut_wb(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, DI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opMOVSB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + addr64 = addr64_2 = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + do_mmut_wb(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, EDI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opMOVSW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_ww(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opMOVSW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_ww(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opMOVSL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_wl(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 0); + return 0; +} +static int +opMOVSL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_wl(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 1); + return 0; +} + +static int +opCMPSB_a16(uint32_t fetchdat) +{ + uint8_t src; + uint8_t dst; + + addr64 = addr64_2 = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI); + CHECK_READ(&cpu_state.seg_es, DI, DI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + do_mmut_rb2(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + dst = readmemb_n(es, DI, addr64_2); + if (cpu_state.abrt) + return 1; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; +} +static int +opCMPSB_a32(uint32_t fetchdat) +{ + uint8_t src; + uint8_t dst; + + addr64 = addr64_2 = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + do_mmut_rb2(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + dst = readmemb_n(es, EDI, addr64_2); + if (cpu_state.abrt) + return 1; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; +} + +static int +opCMPSW_a16(uint32_t fetchdat) +{ + uint16_t src; + uint16_t dst; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_rw2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + dst = readmemw_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; +} +static int +opCMPSW_a32(uint32_t fetchdat) +{ + uint16_t src; + uint16_t dst; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_rw2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + dst = readmemw_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; +} + +static int +opCMPSL_a16(uint32_t fetchdat) +{ + uint32_t src; + uint32_t dst; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_rl2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + dst = readmeml_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 0); + return 0; +} +static int +opCMPSL_a32(uint32_t fetchdat) +{ + uint32_t src; + uint32_t dst; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + do_mmut_rl2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + dst = readmeml_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 1); + return 0; +} + +static int +opSTOSB_a16(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + writememb(es, DI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; +} +static int +opSTOSB_a32(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + writememb(es, EDI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; +} + +static int +opSTOSW_a16(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + writememw(es, DI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; +} +static int +opSTOSW_a32(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + writememw(es, EDI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; +} + +static int +opSTOSL_a16(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + writememl(es, DI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return 0; +} +static int +opSTOSL_a32(uint32_t fetchdat) +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + writememl(es, EDI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 1); + return 0; +} + +static int +opLODSB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opLODSB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opLODSW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opLODSW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opLODSL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); + return 0; +} +static int +opLODSL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 1); + return 0; +} + +static int +opSCASB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI); + temp = readmemb(es, DI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opSCASB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + temp = readmemb(es, EDI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opSCASW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + temp = readmemw(es, DI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opSCASW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + temp = readmemw(es, EDI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opSCASL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + temp = readmeml(es, DI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 0); + return 0; +} +static int +opSCASL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + temp = readmeml(es, EDI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 1); + return 0; +} + +static int +opINSB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + addr64 = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 1); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + high_page = 0; + do_mmut_wb(es, DI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, DI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opINSB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + addr64 = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 1); + high_page = 0; + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + do_mmut_wb(es, EDI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, EDI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opINSW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + addr64a[0] = addr64a[1] = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 2); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + high_page = 0; + do_mmut_ww(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opINSW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + addr64a[0] = addr64a[1] = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + high_page = 0; + check_io_perm(DX, 2); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_ww(es, EDI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opINSL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 4); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 0); + return 0; +} +static int +opINSL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX, 4); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 1); + return 0; +} + +static int +opOUTSB_a16(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 1); + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opOUTSB_a32(uint32_t fetchdat) +{ + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 1); + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opOUTSW_a16(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 2); + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; +} +static int +opOUTSW_a32(uint32_t fetchdat) +{ + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 2); + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; +} + +static int +opOUTSL_a16(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 4); + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 0); + return 0; +} +static int +opOUTSL_a32(uint32_t fetchdat) +{ + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX, 4); + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 1); + return 0; +} diff --git a/src/cpu/x86_ops_xchg.h b/src/cpu/x86_ops_xchg.h index c5ce08999..70e7be58c 100644 --- a/src/cpu/x86_ops_xchg.h +++ b/src/cpu/x86_ops_xchg.h @@ -275,4 +275,4 @@ opBSWAP(ESI) opBSWAP(EDI) opBSWAP(EBP) opBSWAP(ESP) -// clang-format on + // clang-format on diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 7f630275c..3c4847a36 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -31,13 +31,17 @@ #include <86box/machine.h> #include <86box/mem.h> #include <86box/nvr.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> + #include "x86.h" #include "x86_flags.h" #include "386_common.h" uint8_t opcode2; -int cgate16, cgate32; +int cgate16; +int cgate32; int intgatesize; void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); @@ -157,7 +161,7 @@ x86_doabrt(int x86_abrt) } void -x86de(char *s, uint16_t error) +x86de(UNUSED(char *s), UNUSED(uint16_t error)) { #ifdef BAD_CODE cpu_state.abrt = ABRT_DE; @@ -168,35 +172,35 @@ x86de(char *s, uint16_t error) } void -x86gpf(char *s, uint16_t error) +x86gpf(UNUSED(char *s), uint16_t error) { cpu_state.abrt = ABRT_GPF; abrt_error = error; } void -x86gpf_expected(char *s, uint16_t error) +x86gpf_expected(UNUSED(char *s), uint16_t error) { cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; abrt_error = error; } void -x86ss(char *s, uint16_t error) +x86ss(UNUSED(char *s), uint16_t error) { cpu_state.abrt = ABRT_SS; abrt_error = error; } void -x86ts(char *s, uint16_t error) +x86ts(UNUSED(char *s), uint16_t error) { cpu_state.abrt = ABRT_TS; abrt_error = error; } void -x86np(char *s, uint16_t error) +x86np(UNUSED(char *s), uint16_t error) { cpu_state.abrt = ABRT_NP; abrt_error = error; @@ -272,9 +276,9 @@ do_seg_v86_init(x86seg *s) static void check_seg_valid(x86seg *s) { - int dpl = (s->access >> 5) & 3; - int valid = 1; - x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; + int dpl = (s->access >> 5) & 3; + int valid = 1; + const x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; if (((s->seg & 0xfff8UL) + 7UL) > dt->limit) valid = 0; @@ -334,10 +338,11 @@ void #endif loadseg(uint16_t seg, x86seg *s) { - uint16_t segdat[4]; - uint32_t addr, *segdat32 = (uint32_t *) segdat; - int dpl; - x86seg *dt; + uint16_t segdat[4]; + uint32_t addr; + uint32_t *segdat32 = (uint32_t *) segdat; + int dpl; + const x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { if (!(seg & 0xfffc)) { @@ -531,9 +536,10 @@ loadseg(uint16_t seg, x86seg *s) void loadcs(uint16_t seg) { - uint16_t segdat[4]; - uint32_t addr, *segdat32 = (uint32_t *) segdat; - x86seg *dt; + uint16_t segdat[4]; + uint32_t addr; + uint32_t *segdat32 = (uint32_t *) segdat; + const x86seg *dt; x86seg_log("Load CS %04X\n", seg); @@ -619,11 +625,13 @@ loadcs(uint16_t seg) void loadcsjmp(uint16_t seg, uint32_t old_pc) { - uint16_t type, seg2; - uint16_t segdat[4]; - uint32_t addr, newpc; - uint32_t *segdat32 = (uint32_t *) segdat; - x86seg *dt; + uint16_t type; + uint16_t seg2; + uint16_t segdat[4]; + uint32_t addr; + uint32_t newpc; + uint32_t *segdat32 = (uint32_t *) segdat; + const x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { if (!(seg & 0xfffc)) { @@ -743,7 +751,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc) x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc); return; } - /*FALLTHROUGH*/ + fallthrough; case 0x1c00: case 0x1d00: case 0x1e00: @@ -890,16 +898,24 @@ void loadcscall(uint16_t seg) #endif { - uint16_t seg2, newss; - uint16_t segdat[4], segdat2[4]; - uint32_t addr, oldssbase = ss; - uint32_t oaddr, newpc; - uint32_t *segdat32 = (uint32_t *) segdat; - uint32_t *segdat232 = (uint32_t *) segdat2; - int count, type; - uint32_t oldss, oldsp, newsp, oldsp2; - uint16_t tempw; - x86seg *dt; + uint16_t seg2; + uint16_t newss; + uint16_t segdat[4]; + uint16_t segdat2[4]; + uint32_t addr; + uint32_t oldssbase = ss; + uint32_t oaddr; + uint32_t newpc; + uint32_t *segdat32 = (uint32_t *) segdat; + uint32_t *segdat232 = (uint32_t *) segdat2; + int count; + int type; + uint32_t oldss; + uint32_t oldsp; + uint32_t newsp; + uint32_t oldsp2; + uint16_t tempw; + const x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { x86seg_log("Protected mode CS load! %04X\n", seg); @@ -1174,7 +1190,7 @@ loadcscall(uint16_t seg) x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL", seg2 & 0xfffc); return; } - /*FALLTHROUGH*/ + fallthrough; case 0x1c00: case 0x1d00: case 0x1e00: @@ -1237,12 +1253,18 @@ loadcscall(uint16_t seg) void pmoderetf(int is32, uint16_t off) { - uint16_t segdat[4], segdat2[4], seg, newss; - uint32_t newpc, newsp, addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; - uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + uint16_t segdat[4]; + uint16_t segdat2[4]; + uint16_t seg; + uint16_t newss; + uint32_t newpc; + uint32_t newsp; + uint32_t addr; + uint32_t oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; + uint32_t *segdat232 = (uint32_t *) segdat2; + const x86seg *dt; x86seg_log("RETF %i %04X:%04X %08X %04X\n", is32, CS, cpu_state.pc, cr0, cpu_state.eflags); if (is32) { @@ -1467,17 +1489,22 @@ pmoderetf(int is32, uint16_t off) void pmodeint(int num, int soft) { - uint16_t segdat[4], segdat2[4]; - uint16_t segdat3[4]; - uint16_t newss, seg = 0; - int type, new_cpl; - uint32_t addr, oaddr; - uint32_t oldss, oldsp; - uint32_t newsp; - uint32_t *segdat32 = (uint32_t *) segdat; - uint32_t *segdat232 = (uint32_t *) segdat2; - uint32_t *segdat332 = (uint32_t *) segdat3; - x86seg *dt; + uint16_t segdat[4]; + uint16_t segdat2[4]; + uint16_t segdat3[4]; + uint16_t newss; + uint16_t seg = 0; + int type; + int new_cpl; + uint32_t addr; + uint32_t oaddr; + uint32_t oldss; + uint32_t oldsp; + uint32_t newsp; + uint32_t *segdat32 = (uint32_t *) segdat; + uint32_t *segdat232 = (uint32_t *) segdat2; + uint32_t *segdat332 = (uint32_t *) segdat3; + const x86seg *dt; if ((cpu_state.eflags & VM_FLAG) && (IOPL != 3) && soft) { x86seg_log("V86 banned int\n"); @@ -1661,7 +1688,7 @@ pmodeint(int num, int soft) x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc); return; } - /*FALLTHROUGH*/ + fallthrough; case 0x1c00: case 0x1d00: case 0x1e00: @@ -1750,16 +1777,21 @@ pmodeint(int num, int soft) void pmodeiret(int is32) { - uint16_t newss, seg = 0; - uint16_t segdat[4], segdat2[4]; - uint16_t segs[4]; - uint32_t tempflags, flagmask; - uint32_t newpc, newsp; - uint32_t addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; - uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + uint16_t newss; + uint16_t seg = 0; + uint16_t segdat[4]; + uint16_t segdat2[4]; + uint16_t segs[4]; + uint32_t tempflags; + uint32_t flagmask; + uint32_t newpc; + uint32_t newsp; + uint32_t addr; + uint32_t oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; + uint32_t *segdat232 = (uint32_t *) segdat2; + const x86seg *dt; if (is386 && (cpu_state.eflags & VM_FLAG)) { if (IOPL != 3) { @@ -2058,15 +2090,32 @@ pmodeiret(int is32) void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { - uint16_t tempw, new_ldt; - uint16_t new_es, new_cs, new_ss, new_ds, new_fs, new_gs; - uint16_t segdat2[4]; - uint32_t base, limit; - uint32_t templ, new_cr3 = 0; - uint32_t new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp; - uint32_t new_esi, new_edi, new_pc, new_flags, addr; - uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + uint16_t tempw; + uint16_t new_ldt; + uint16_t new_es; + uint16_t new_cs; + uint16_t new_ss; + uint16_t new_ds; + uint16_t new_fs; + uint16_t new_gs; + uint16_t segdat2[4]; + uint32_t base; + uint32_t limit; + uint32_t templ; + uint32_t new_cr3 = 0; + uint32_t new_eax; + uint32_t new_ebx; + uint32_t new_ecx; + uint32_t new_edx; + uint32_t new_esp; + uint32_t new_ebp; + uint32_t new_esi; + uint32_t new_edi; + uint32_t new_pc; + uint32_t new_flags; + uint32_t addr; + uint32_t *segdat232 = (uint32_t *) segdat2; + const x86seg *dt; base = segdat[1] | ((segdat[2] & 0x00ff) << 16); limit = segdat[0]; @@ -2447,7 +2496,8 @@ cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) { - uint16_t segdat[4], selector; + uint16_t segdat[4]; + uint16_t selector; segdat[0] = readmemw(0, addr); segdat[1] = readmemw(0, addr + 2); diff --git a/src/cpu/x87.c b/src/cpu/x87.c index 181b7b9ca..c75dac569 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -17,8 +17,10 @@ #include "386_common.h" #include "softfloat/softfloat-specialize.h" -uint32_t x87_pc_off, x87_op_off; -uint16_t x87_pc_seg, x87_op_seg; +uint32_t x87_pc_off; +uint32_t x87_op_off; +uint16_t x87_pc_seg; +uint16_t x87_op_seg; #ifdef ENABLE_FPU_LOG int fpu_do_log = ENABLE_FPU_LOG; @@ -43,9 +45,8 @@ uint16_t x87_gettag(void) { uint16_t ret = 0; - int c; - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { if (cpu_state.tag[c] == TAG_EMPTY) ret |= X87_TAG_EMPTY << (c * 2); else if (cpu_state.tag[c] & TAG_UINT64) @@ -62,9 +63,7 @@ x87_gettag(void) void x87_settag(uint16_t new_tag) { - int c; - - for (c = 0; c < 8; c++) { + for (uint8_t c = 0; c < 8; c++) { int tag = (new_tag >> (c * 2)) & 3; if (tag == X87_TAG_EMPTY) @@ -106,7 +105,6 @@ x87_settag(uint16_t new_tag) } #endif - static floatx80 FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct float_status_t *status) { @@ -119,24 +117,27 @@ FPU_handle_NaN32_Func(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, struct fl // propagate QNaN to SNaN a = propagateFloatx80NaNOne(a, status); - if (aIsNaN & !bIsNaN) return a; + if (aIsNaN & !bIsNaN) + return a; // float32 is NaN so conversion will propagate SNaN to QNaN and raise // appropriate exception flags floatx80 b = float32_to_floatx80(b32, status); if (aIsSignalingNaN) { - if (bIsSignalingNaN) goto returnLargerSignificand; + if (bIsSignalingNaN) + goto returnLargerSignificand; return bIsNaN ? b : a; - } - else if (aIsNaN) { - if (bIsSignalingNaN) return a; - returnLargerSignificand: - if (a.fraction < b.fraction) return b; - if (b.fraction < a.fraction) return a; + } else if (aIsNaN) { + if (bIsSignalingNaN) + return a; +returnLargerSignificand: + if (a.fraction < b.fraction) + return b; + if (b.fraction < a.fraction) + return a; return (a.exp < b.exp) ? a : b; - } - else { + } else { return b; } } @@ -152,7 +153,8 @@ FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *stat return 1; } - int aIsNaN = floatx80_is_nan(a), bIsNaN = float32_is_nan(b); + int aIsNaN = floatx80_is_nan(a); + int bIsNaN = float32_is_nan(b); if (aIsNaN | bIsNaN) { *r = FPU_handle_NaN32_Func(a, aIsNaN, b, bIsNaN, status); return 1; @@ -172,24 +174,27 @@ FPU_handle_NaN64_Func(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, struct fl // propagate QNaN to SNaN a = propagateFloatx80NaNOne(a, status); - if (aIsNaN & !bIsNaN) return a; + if (aIsNaN & !bIsNaN) + return a; // float64 is NaN so conversion will propagate SNaN to QNaN and raise // appropriate exception flags floatx80 b = float64_to_floatx80(b64, status); if (aIsSignalingNaN) { - if (bIsSignalingNaN) goto returnLargerSignificand; + if (bIsSignalingNaN) + goto returnLargerSignificand; return bIsNaN ? b : a; - } - else if (aIsNaN) { - if (bIsSignalingNaN) return a; - returnLargerSignificand: - if (a.fraction < b.fraction) return b; - if (b.fraction < a.fraction) return a; + } else if (aIsNaN) { + if (bIsSignalingNaN) + return a; +returnLargerSignificand: + if (a.fraction < b.fraction) + return b; + if (b.fraction < a.fraction) + return a; return (a.exp < b.exp) ? a : b; - } - else { + } else { return b; } } @@ -205,7 +210,8 @@ FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *stat return 1; } - int aIsNaN = floatx80_is_nan(a), bIsNaN = float64_is_nan(b); + int aIsNaN = floatx80_is_nan(a); + int bIsNaN = float64_is_nan(b); if (aIsNaN | bIsNaN) { *r = FPU_handle_NaN64_Func(a, aIsNaN, b, bIsNaN, status); return 1; @@ -217,7 +223,7 @@ struct float_status_t i387cw_to_softfloat_status_word(uint16_t control_word) { struct float_status_t status; - int precision = control_word & FPU_CW_PC; + int precision = control_word & FPU_CW_PC; switch (precision) { case FPU_PR_32_BITS: @@ -230,24 +236,23 @@ i387cw_to_softfloat_status_word(uint16_t control_word) status.float_rounding_precision = 80; break; default: - /* With the precision control bits set to 01 "(reserved)", a - real CPU behaves as if the precision control bits were - set to 11 "80 bits" */ + /* With the precision control bits set to 01 "(reserved)", a + real CPU behaves as if the precision control bits were + set to 11 "80 bits" */ status.float_rounding_precision = 80; break; } - status.float_exception_flags = 0; // clear exceptions before execution - status.float_nan_handling_mode = float_first_operand_nan; - status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10; - status.flush_underflow_to_zero = 0; + status.float_exception_flags = 0; // clear exceptions before execution + status.float_nan_handling_mode = float_first_operand_nan; + status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10; + status.flush_underflow_to_zero = 0; status.float_suppress_exception = 0; - status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask; - status.denormals_are_zeros = 0; + status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask; + status.denormals_are_zeros = 0; return status; } - int FPU_status_word_flags_fpu_compare(int float_relation) { @@ -256,16 +261,16 @@ FPU_status_word_flags_fpu_compare(int float_relation) return (C0 | C2 | C3); case float_relation_greater: - return (0); + return 0; case float_relation_less: - return (C0); + return C0; case float_relation_equal: - return (C3); + return C3; } - return (-1); // should never get here + return (-1); // should never get here } void @@ -280,11 +285,11 @@ FPU_write_eflags_fpu_compare(int float_relation) break; case float_relation_less: - cpu_state.flags |= (C_FLAG); + cpu_state.flags |= C_FLAG; break; case float_relation_equal: - cpu_state.flags |= (Z_FLAG); + cpu_state.flags |= Z_FLAG; break; default: @@ -319,9 +324,9 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) fpu_state.swd |= exceptions; if (exceptions & FPU_SW_Stack_Fault) { if (!(exceptions & C1)) { - /* This bit distinguishes over- from underflow for a stack fault, - and roundup from round-down for precision loss. */ - fpu_state.swd &= ~C1; + /* This bit distinguishes over- from underflow for a stack fault, + and roundup from round-down for precision loss. */ + fpu_state.swd &= ~C1; } } return unmasked; @@ -354,8 +359,8 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) if (exceptions & FPU_EX_Precision) { if (!(exceptions & C1)) { - /* This bit distinguishes over- from underflow for a stack fault, - and roundup from round-down for precision loss. */ + /* This bit distinguishes over- from underflow for a stack fault, + and roundup from round-down for precision loss. */ fpu_state.swd &= ~C1; } } @@ -444,14 +449,22 @@ pack_FPU_TW(uint16_t twd) { uint8_t tag_byte = 0; - if ((twd & 0x0003) != 0x0003) tag_byte |= 0x01; - if ((twd & 0x000c) != 0x000c) tag_byte |= 0x02; - if ((twd & 0x0030) != 0x0030) tag_byte |= 0x04; - if ((twd & 0x00c0) != 0x00c0) tag_byte |= 0x08; - if ((twd & 0x0300) != 0x0300) tag_byte |= 0x10; - if ((twd & 0x0c00) != 0x0c00) tag_byte |= 0x20; - if ((twd & 0x3000) != 0x3000) tag_byte |= 0x40; - if ((twd & 0xc000) != 0xc000) tag_byte |= 0x80; + if ((twd & 0x0003) != 0x0003) + tag_byte |= 0x01; + if ((twd & 0x000c) != 0x000c) + tag_byte |= 0x02; + if ((twd & 0x0030) != 0x0030) + tag_byte |= 0x04; + if ((twd & 0x00c0) != 0x00c0) + tag_byte |= 0x08; + if ((twd & 0x0300) != 0x0300) + tag_byte |= 0x10; + if ((twd & 0x0c00) != 0x0c00) + tag_byte |= 0x20; + if ((twd & 0x3000) != 0x3000) + tag_byte |= 0x40; + if ((twd & 0xc000) != 0xc000) + tag_byte |= 0x80; return tag_byte; } @@ -461,45 +474,45 @@ unpack_FPU_TW(uint16_t tag_byte) { uint32_t twd = 0; - /* FTW - * - * Note that the original format for FTW can be recreated from the stored - * FTW valid bits and the stored 80-bit FP data (assuming the stored data - * was not the contents of MMX registers) using the following table: + /* FTW + * + * Note that the original format for FTW can be recreated from the stored + * FTW valid bits and the stored 80-bit FP data (assuming the stored data + * was not the contents of MMX registers) using the following table: - | Exponent | Exponent | Fraction | J,M bits | FTW valid | x87 FTW | - | all 1s | all 0s | all 0s | | | | - ------------------------------------------------------------------- - | 0 | 0 | 0 | 0x | 1 | S 10 | - | 0 | 0 | 0 | 1x | 1 | V 00 | - ------------------------------------------------------------------- - | 0 | 0 | 1 | 00 | 1 | S 10 | - | 0 | 0 | 1 | 10 | 1 | V 00 | - ------------------------------------------------------------------- - | 0 | 1 | 0 | 0x | 1 | S 10 | - | 0 | 1 | 0 | 1x | 1 | S 10 | - ------------------------------------------------------------------- - | 0 | 1 | 1 | 00 | 1 | Z 01 | - | 0 | 1 | 1 | 10 | 1 | S 10 | - ------------------------------------------------------------------- - | 1 | 0 | 0 | 1x | 1 | S 10 | - | 1 | 0 | 0 | 1x | 1 | S 10 | - ------------------------------------------------------------------- - | 1 | 0 | 1 | 00 | 1 | S 10 | - | 1 | 0 | 1 | 10 | 1 | S 10 | - ------------------------------------------------------------------- - | all combinations above | 0 | E 11 | + | Exponent | Exponent | Fraction | J,M bits | FTW valid | x87 FTW | + | all 1s | all 0s | all 0s | | | | + ------------------------------------------------------------------- + | 0 | 0 | 0 | 0x | 1 | S 10 | + | 0 | 0 | 0 | 1x | 1 | V 00 | + ------------------------------------------------------------------- + | 0 | 0 | 1 | 00 | 1 | S 10 | + | 0 | 0 | 1 | 10 | 1 | V 00 | + ------------------------------------------------------------------- + | 0 | 1 | 0 | 0x | 1 | S 10 | + | 0 | 1 | 0 | 1x | 1 | S 10 | + ------------------------------------------------------------------- + | 0 | 1 | 1 | 00 | 1 | Z 01 | + | 0 | 1 | 1 | 10 | 1 | S 10 | + ------------------------------------------------------------------- + | 1 | 0 | 0 | 1x | 1 | S 10 | + | 1 | 0 | 0 | 1x | 1 | S 10 | + ------------------------------------------------------------------- + | 1 | 0 | 1 | 00 | 1 | S 10 | + | 1 | 0 | 1 | 10 | 1 | S 10 | + ------------------------------------------------------------------- + | all combinations above | 0 | E 11 | - * - * The J-bit is defined to be the 1-bit binary integer to the left of - * the decimal place in the significand. - * - * The M-bit is defined to be the most significant bit of the fractional - * portion of the significand (i.e., the bit immediately to the right of - * the decimal place). When the M-bit is the most significant bit of the - * fractional portion of the significand, it must be 0 if the fraction - * is all 0's. - */ + * + * The J-bit is defined to be the 1-bit binary integer to the left of + * the decimal place in the significand. + * + * The M-bit is defined to be the most significant bit of the fractional + * portion of the significand (i.e., the bit immediately to the right of + * the decimal place). When the M-bit is the most significant bit of the + * fractional portion of the significand, it must be 0 if the fraction + * is all 0's. + */ for (int index = 7; index >= 0; index--, twd <<= 2, tag_byte <<= 1) { if (tag_byte & 0x80) { diff --git a/src/cpu/x87.h b/src/cpu/x87.h index 66d51dbd9..1d889a544 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -3,8 +3,10 @@ #define X87_TAG_INVALID 2 #define X87_TAG_EMPTY 3 -extern uint32_t x87_pc_off, x87_op_off; -extern uint16_t x87_pc_seg, x87_op_seg; +extern uint32_t x87_pc_off; +extern uint32_t x87_op_off; +extern uint16_t x87_pc_seg; +extern uint16_t x87_op_seg; static __inline void x87_set_mmx(void) @@ -14,9 +16,9 @@ x87_set_mmx(void) fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } else { - cpu_state.TOP = 0; - p = (uint64_t *) cpu_state.tag; - *p = 0x0101010101010101ull; + cpu_state.TOP = 0; + p = (uint64_t *) cpu_state.tag; + *p = 0x0101010101010101ULL; } cpu_state.ismmx = 1; } @@ -29,8 +31,8 @@ x87_emms(void) fpu_state.tag = 0xffff; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } else { - p = (uint64_t *) cpu_state.tag; - *p = 0; + p = (uint64_t *) cpu_state.tag; + *p = 0; } cpu_state.ismmx = 0; } @@ -58,81 +60,87 @@ void x87_settag(uint16_t new_tag); void codegen_set_rounding_mode(int mode); /* Status Word */ -#define FPU_SW_Backward (0x8000) /* backward compatibility */ -#define FPU_SW_C3 (0x4000) /* condition bit 3 */ -#define FPU_SW_Top (0x3800) /* top of stack */ -#define FPU_SW_C2 (0x0400) /* condition bit 2 */ -#define FPU_SW_C1 (0x0200) /* condition bit 1 */ -#define FPU_SW_C0 (0x0100) /* condition bit 0 */ -#define FPU_SW_Summary (0x0080) /* exception summary */ -#define FPU_SW_Stack_Fault (0x0040) /* stack fault */ -#define FPU_SW_Precision (0x0020) /* loss of precision */ -#define FPU_SW_Underflow (0x0010) /* underflow */ -#define FPU_SW_Overflow (0x0008) /* overflow */ -#define FPU_SW_Zero_Div (0x0004) /* divide by zero */ -#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */ -#define FPU_SW_Invalid (0x0001) /* invalid operation */ +#define FPU_SW_Backward (0x8000) /* backward compatibility */ +#define FPU_SW_C3 (0x4000) /* condition bit 3 */ +#define FPU_SW_Top (0x3800) /* top of stack */ +#define FPU_SW_C2 (0x0400) /* condition bit 2 */ +#define FPU_SW_C1 (0x0200) /* condition bit 1 */ +#define FPU_SW_C0 (0x0100) /* condition bit 0 */ +#define FPU_SW_Summary (0x0080) /* exception summary */ +#define FPU_SW_Stack_Fault (0x0040) /* stack fault */ +#define FPU_SW_Precision (0x0020) /* loss of precision */ +#define FPU_SW_Underflow (0x0010) /* underflow */ +#define FPU_SW_Overflow (0x0008) /* overflow */ +#define FPU_SW_Zero_Div (0x0004) /* divide by zero */ +#define FPU_SW_Denormal_Op (0x0002) /* denormalized operand */ +#define FPU_SW_Invalid (0x0001) /* invalid operation */ -#define C0 (1 << 8) -#define C1 (1 << 9) -#define C2 (1 << 10) -#define C3 (1 << 14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) -#define FPU_SW_CC (C0 | C1 | C2 | C3) +#define FPU_SW_CC (C0 | C1 | C2 | C3) -#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */ +#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */ /* Exception flags: */ -#define FPU_EX_Precision (0x0020) /* loss of precision */ -#define FPU_EX_Underflow (0x0010) /* underflow */ -#define FPU_EX_Overflow (0x0008) /* overflow */ -#define FPU_EX_Zero_Div (0x0004) /* divide by zero */ -#define FPU_EX_Denormal (0x0002) /* denormalized operand */ -#define FPU_EX_Invalid (0x0001) /* invalid operation */ +#define FPU_EX_Precision (0x0020) /* loss of precision */ +#define FPU_EX_Underflow (0x0010) /* underflow */ +#define FPU_EX_Overflow (0x0008) /* overflow */ +#define FPU_EX_Zero_Div (0x0004) /* divide by zero */ +#define FPU_EX_Denormal (0x0002) /* denormalized operand */ +#define FPU_EX_Invalid (0x0001) /* invalid operation */ /* Special exceptions: */ -#define FPU_EX_Stack_Overflow (0x0041| C1) /* stack overflow */ -#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */ +#define FPU_EX_Stack_Overflow (0x0041 | C1) /* stack overflow */ +#define FPU_EX_Stack_Underflow (0x0041) /* stack underflow */ /* precision control */ -#define FPU_EX_Precision_Lost_Up (EX_Precision | C1) -#define FPU_EX_Precision_Lost_Dn (EX_Precision) +#define FPU_EX_Precision_Lost_Up (EX_Precision | C1) +#define FPU_EX_Precision_Lost_Dn (EX_Precision) -#define setcc(cc) \ - fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) & FPU_SW_CC) +#define setcc(cc) \ + fpu_state.swd = (fpu_state.swd & ~(FPU_SW_CC)) | ((cc) &FPU_SW_CC) -#define clear_C1() { fpu_state.swd &= ~C1; } -#define clear_C2() { fpu_state.swd &= ~C2; } +#define clear_C1() \ + { \ + fpu_state.swd &= ~C1; \ + } +#define clear_C2() \ + { \ + fpu_state.swd &= ~C2; \ + } /* ************ */ /* Control Word */ /* ************ */ -#define FPU_CW_Inf (0x1000) /* infinity control, legacy */ +#define FPU_CW_Inf (0x1000) /* infinity control, legacy */ -#define FPU_CW_RC (0x0C00) /* rounding control */ -#define FPU_CW_PC (0x0300) /* precision control */ +#define FPU_CW_RC (0x0C00) /* rounding control */ +#define FPU_CW_PC (0x0300) /* precision control */ -#define FPU_RC_RND (0x0000) /* rounding control */ -#define FPU_RC_DOWN (0x0400) -#define FPU_RC_UP (0x0800) -#define FPU_RC_CHOP (0x0C00) +#define FPU_RC_RND (0x0000) /* rounding control */ +#define FPU_RC_DOWN (0x0400) +#define FPU_RC_UP (0x0800) +#define FPU_RC_CHOP (0x0C00) -#define FPU_CW_Precision (0x0020) /* loss of precision mask */ -#define FPU_CW_Underflow (0x0010) /* underflow mask */ -#define FPU_CW_Overflow (0x0008) /* overflow mask */ -#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */ -#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */ -#define FPU_CW_Invalid (0x0001) /* invalid operation mask */ +#define FPU_CW_Precision (0x0020) /* loss of precision mask */ +#define FPU_CW_Underflow (0x0010) /* underflow mask */ +#define FPU_CW_Overflow (0x0008) /* overflow mask */ +#define FPU_CW_Zero_Div (0x0004) /* divide by zero mask */ +#define FPU_CW_Denormal (0x0002) /* denormalized operand mask */ +#define FPU_CW_Invalid (0x0001) /* invalid operation mask */ -#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */ +#define FPU_CW_Exceptions_Mask (0x003f) /* all masks */ /* Precision control bits affect only the following: ADD, SUB(R), MUL, DIV(R), and SQRT */ -#define FPU_PR_32_BITS (0x000) -#define FPU_PR_RESERVED_BITS (0x100) -#define FPU_PR_64_BITS (0x200) -#define FPU_PR_80_BITS (0x300) +#define FPU_PR_32_BITS (0x000) +#define FPU_PR_RESERVED_BITS (0x100) +#define FPU_PR_64_BITS (0x200) +#define FPU_PR_80_BITS (0x300) #include "softfloat/softfloatx80.h" @@ -143,16 +151,16 @@ is_IA_masked(void) } struct float_status_t i387cw_to_softfloat_status_word(uint16_t control_word); -uint16_t FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store); -int FPU_status_word_flags_fpu_compare(int float_relation); -void FPU_write_eflags_fpu_compare(int float_relation); -void FPU_stack_overflow(uint32_t fetchdat); -void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack); -int FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status); -int FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status); -int FPU_tagof(const floatx80 reg); -uint8_t pack_FPU_TW(uint16_t twd); -uint16_t unpack_FPU_TW(uint16_t tag_byte); +uint16_t FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store); +int FPU_status_word_flags_fpu_compare(int float_relation); +void FPU_write_eflags_fpu_compare(int float_relation); +void FPU_stack_overflow(uint32_t fetchdat); +void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack); +int FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status); +int FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status); +int FPU_tagof(const floatx80 reg); +uint8_t pack_FPU_TW(uint16_t twd); +uint16_t unpack_FPU_TW(uint16_t tag_byte); static __inline uint16_t i387_get_control_word(void) @@ -179,7 +187,7 @@ static __inline void FPU_settagi_valid(int stnr) { int regnr = (stnr + fpu_state.tos) & 7; - fpu_state.tag &= ~(3 << (regnr * 2)); // FPU_Tag_Valid == '00 + fpu_state.tag &= ~(3 << (regnr * 2)); // FPU_Tag_Valid == '00 } static __inline void @@ -226,16 +234,15 @@ FPU_save_regi_tag(floatx80 reg, int tag, int stnr) FPU_settagi(tag, stnr); } - -#define FPU_check_pending_exceptions() \ -do { \ - if (fpu_state.swd & FPU_SW_Summary) { \ - if (cr0 & 0x20) { \ - x86_int(16); \ - return 1; \ - } else { \ - picint(1 << 13); \ - return 1; \ - } \ - } \ -} while (0) +#define FPU_check_pending_exceptions() \ + do { \ + if (fpu_state.swd & FPU_SW_Summary) { \ + if (cr0 & 0x20) { \ + x86_int(16); \ + return 1; \ + } else { \ + picint(1 << 13); \ + return 1; \ + } \ + } \ + } while (0) diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index b01547314..d1c55f2e9 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -45,21 +45,20 @@ static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARD #define C2 (1 << 10) #define C3 (1 << 14) -#define X87_TAG_VALID 0 -#define X87_TAG_ZERO 1 -#define X87_TAG_INVALID 2 -#define X87_TAG_EMPTY 3 +#define X87_TAG_VALID 0 +#define X87_TAG_ZERO 1 +#define X87_TAG_INVALID 2 +#define X87_TAG_EMPTY 3 #define STATUS_ZERODIVIDE 4 -typedef union -{ +typedef union { double d; struct { - uint64_t mantissa:52; - uint64_t exponent:11; - uint64_t negative:1; + uint64_t mantissa : 52; + uint64_t exponent : 11; + uint64_t negative : 1; }; } double_decompose_t; @@ -111,6 +110,7 @@ typedef union static __inline void x87_checkexceptions(void) { + // } static __inline void @@ -169,7 +169,8 @@ x87_pop(void) static __inline int16_t x87_fround16(double b) { - int16_t a, c; + int16_t a; + int16_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ @@ -201,7 +202,8 @@ x87_fround16_64(double b) static __inline int32_t x87_fround32(double b) { - int32_t a, c; + int32_t a; + int32_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ @@ -233,7 +235,8 @@ x87_fround32_64(double b) static __inline int64_t x87_fround(double b) { - int64_t a, c; + int64_t a; + int64_t c; switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ @@ -338,9 +341,10 @@ x87_compare(double a, double b) { #ifdef X87_INLINE_ASM uint32_t result; - double ea = a, eb = b; - const uint64_t ia = 0x3fec1a6ff866a936ull; - const uint64_t ib = 0x3fec1a6ff866a938ull; + double ea = a; + double eb = b; + const uint64_t ia = 0x3fec1a6ff866a936ULL; + const uint64_t ib = 0x3fec1a6ff866a938ULL; /* Hack to make CHKCOP happy. */ if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) @@ -1069,7 +1073,6 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = { #else # define ILLEGAL_a32 FPU_ILLEGAL_a32 - const OpFn OP_TABLE(sf_fpu_d8_a16)[32] = { // clang-format off sf_FADDs_a16, sf_FMULs_a16, sf_FCOMs_a16, sf_FCOMPs_a16, sf_FSUBs_a16, sf_FSUBRs_a16, sf_FDIVs_a16, sf_FDIVRs_a16, @@ -1408,6 +1411,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 +1491,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 +1653,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 +1732,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 +2250,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 +2330,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 +2670,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 +2750,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 +2912,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 +2991,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 +3509,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 +3589,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 diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index d38d584a8..808a15051 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -143,9 +143,9 @@ opFPU(il, uint32_t, 16, t, geteal, (double) (int32_t) t, _i32) #ifndef FPU_8087 opFPU(il, uint32_t, 32, t, geteal, (double) (int32_t) t, _i32) #endif -// clang-format on + // clang-format on -static int opFADD(uint32_t fetchdat) + static int opFADD(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; @@ -242,6 +242,7 @@ opFUCOMPP(uint32_t fetchdat) return 0; } +# ifndef OPS_286_386 static int opFCOMI(uint32_t fetchdat) { @@ -273,6 +274,7 @@ opFCOMIP(uint32_t fetchdat) CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; } +# endif #endif static int @@ -476,6 +478,7 @@ opFUCOMP(uint32_t fetchdat) return 0; } +# ifndef OPS_286_386 static int opFUCOMI(uint32_t fetchdat) { @@ -507,4 +510,5 @@ opFUCOMIP(uint32_t fetchdat) CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } +# endif #endif diff --git a/src/cpu/x87_ops_conv.h b/src/cpu/x87_ops_conv.h index bb1e497da..7a949cfb2 100644 --- a/src/cpu/x87_ops_conv.h +++ b/src/cpu/x87_ops_conv.h @@ -22,7 +22,7 @@ x87_from80(x87_conv_t *test) blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff; exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64; - mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll); + mant64 = (test->eind.ll >> 11) & (0xfffffffffffffLL); sign = (test->begin & 0x8000) ? 1 : 0; if ((test->begin & 0x7fff) == 0x7fff) @@ -48,19 +48,19 @@ x87_to80(double d, x87_conv_t *test) test->eind.d = d; - sign80 = (test->eind.ll & (0x8000000000000000ll)) ? 1 : 0; - exp80 = test->eind.ll & (0x7ff0000000000000ll); + sign80 = (test->eind.ll & (0x8000000000000000LL)) ? 1 : 0; + exp80 = test->eind.ll & (0x7ff0000000000000LL); exp80final = (exp80 >> 52); - mant80 = test->eind.ll & (0x000fffffffffffffll); + mant80 = test->eind.ll & (0x000fffffffffffffLL); mant80final = (mant80 << 11); if (exp80final == 0x7ff) /*Infinity / Nan*/ { exp80final = 0x7fff; - mant80final |= (0x8000000000000000ll); + mant80final |= (0x8000000000000000LL); } else if (d != 0) { /* Zero is a special case */ /* Elvira wants the 8 and tcalc doesn't */ - mant80final |= (0x8000000000000000ll); + mant80final |= (0x8000000000000000LL); /* Ca-cyber doesn't like this when result is zero. */ exp80final += (BIAS80 - BIAS64); } diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index bd2b05c52..0c951815e 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -37,16 +37,17 @@ static int opFXTRACT(uint32_t fetchdat) { x87_conv_t test; - int64_t exp80, exp80final; - double mant; + int64_t exp80; + int64_t exp80final; + double mant; FP_ENTER(); cpu_state.pc++; test.eind.d = ST(0); - exp80 = test.eind.ll & (0x7ff0000000000000ll); - exp80final = (exp80 >> 52) - BIAS64; - mant = test.eind.d / (pow(2.0, (double)exp80final)); - ST(0) = (double)exp80final; + exp80 = test.eind.ll & 0x7ff0000000000000LL; + exp80final = (exp80 >> 52) - BIAS64; + mant = test.eind.d / (pow(2.0, (double) exp80final)); + ST(0) = (double) exp80final; FP_TAG_VALID; x87_push(mant); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxtract) : (x87_timings.fxtract * cpu_multi)); @@ -82,7 +83,7 @@ opFINIT(uint32_t fetchdat) #ifdef USE_NEW_DYNAREC *p = 0; #else - *p = 0x0303030303030303ll; + *p = 0x0303030303030303LL; #endif cpu_state.TOP = 0; cpu_state.ismmx = 0; @@ -192,7 +193,7 @@ FSTOR(void) something like this is needed*/ p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ull)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ULL)) #else if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && !(*p)) #endif @@ -410,7 +411,7 @@ FSAVE(void) #ifdef USE_NEW_DYNAREC *p = 0; #else - *p = 0x0303030303030303ll; + *p = 0x0303030303030303LL; #endif cpu_state.TOP = 0; cpu_state.ismmx = 0; @@ -629,7 +630,7 @@ opFLDLN2(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - x87_push_u64(0x3fe62e42fefa39f0ull); + x87_push_u64(0x3fe62e42fefa39f0ULL); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); return 0; @@ -1045,22 +1046,23 @@ opFSTCW_a32(uint32_t fetchdat) #endif #ifndef FPU_8087 -# define opFCMOV(condition) \ - static int opFCMOV##condition(uint32_t fetchdat) \ - { \ - FP_ENTER(); \ - cpu_state.pc++; \ - if (cond_##condition) { \ - cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ - ST(0) = ST(fetchdat & 7); \ - } \ - CLOCK_CYCLES_FPU(4); \ - return 0; \ - } +# ifndef OPS_286_386 +# define opFCMOV(condition) \ + static int opFCMOV##condition(uint32_t fetchdat) \ + { \ + FP_ENTER(); \ + cpu_state.pc++; \ + if (cond_##condition) { \ + cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + ST(0) = ST(fetchdat & 7); \ + } \ + CLOCK_CYCLES_FPU(4); \ + return 0; \ + } -# define cond_U (PF_SET()) -# define cond_NU (!PF_SET()) +# define cond_U (PF_SET()) +# define cond_NU (!PF_SET()) // clang-format off opFCMOV(B) @@ -1072,4 +1074,5 @@ opFCMOV(NE) opFCMOV(NBE) opFCMOV(NU) // clang-format on +# endif #endif diff --git a/src/cpu/x87_ops_sf.h b/src/cpu/x87_ops_sf.h index e70556fea..137919fa9 100644 --- a/src/cpu/x87_ops_sf.h +++ b/src/cpu/x87_ops_sf.h @@ -1,7 +1,7 @@ static uint32_t fpu_save_environment(void) { - int tag; + int tag; unsigned offset = 0; /* read all registers in stack order and update x87 tag word */ @@ -16,91 +16,98 @@ fpu_save_environment(void) fpu_state.swd = (fpu_state.swd & ~(7 << 11)) | ((fpu_state.tos & 7) << 11); switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { - case 0x000: { /*16-bit real mode*/ - uint16_t tmp; - uint32_t fp_ip, fp_dp; + case 0x000: + { /*16-bit real mode*/ + uint16_t tmp; + uint32_t fp_ip; + uint32_t fp_dp; - fp_ip = ((uint32_t)(fpu_state.fcs << 4)) | fpu_state.fip; - fp_dp = ((uint32_t)(fpu_state.fds << 4)) | fpu_state.fdp; + fp_ip = ((uint32_t) (fpu_state.fcs << 4)) | fpu_state.fip; + fp_dp = ((uint32_t) (fpu_state.fds << 4)) | fpu_state.fdp; - tmp = i387_get_control_word(); - writememw(easeg, cpu_state.eaaddr + 0x00, tmp); - tmp = i387_get_status_word(); - writememw(easeg, cpu_state.eaaddr + 0x02, tmp); - tmp = fpu_state.tag; - writememw(easeg, cpu_state.eaaddr + 0x04, tmp); - tmp = fp_ip & 0xffff; - writememw(easeg, cpu_state.eaaddr + 0x06, tmp); - tmp = (uint16_t)((fp_ip & 0xf0000) >> 4) | fpu_state.foo; - writememw(easeg, cpu_state.eaaddr + 0x08, tmp); - tmp = fp_dp & 0xffff; - writememw(easeg, cpu_state.eaaddr + 0x0a, tmp); - tmp = (uint16_t)((fp_dp & 0xf0000) >> 4); - writememw(easeg, cpu_state.eaaddr + 0x0c, tmp); - offset = 0x0e; - } - break; - case 0x001: {/*16-bit protected mode*/ - uint16_t tmp; - tmp = i387_get_control_word(); - writememw(easeg, cpu_state.eaaddr + 0x00, tmp); - tmp = i387_get_status_word(); - writememw(easeg, cpu_state.eaaddr + 0x02, tmp); - tmp = fpu_state.tag; - writememw(easeg, cpu_state.eaaddr + 0x04, tmp); - tmp = (uint16_t)(fpu_state.fip) & 0xffff; - writememw(easeg, cpu_state.eaaddr + 0x06, tmp); - tmp = fpu_state.fcs; - writememw(easeg, cpu_state.eaaddr + 0x08, tmp); - tmp = (uint16_t)(fpu_state.fdp) & 0xffff; - writememw(easeg, cpu_state.eaaddr + 0x0a, tmp); - tmp = fpu_state.fds; - writememw(easeg, cpu_state.eaaddr + 0x0c, tmp); - offset = 0x0e; - } - break; - case 0x100: { /*32-bit real mode*/ - uint32_t tmp, fp_ip, fp_dp; + tmp = i387_get_control_word(); + writememw(easeg, cpu_state.eaaddr + 0x00, tmp); + tmp = i387_get_status_word(); + writememw(easeg, cpu_state.eaaddr + 0x02, tmp); + tmp = fpu_state.tag; + writememw(easeg, cpu_state.eaaddr + 0x04, tmp); + tmp = fp_ip & 0xffff; + writememw(easeg, cpu_state.eaaddr + 0x06, tmp); + tmp = (uint16_t) ((fp_ip & 0xf0000) >> 4) | fpu_state.foo; + writememw(easeg, cpu_state.eaaddr + 0x08, tmp); + tmp = fp_dp & 0xffff; + writememw(easeg, cpu_state.eaaddr + 0x0a, tmp); + tmp = (uint16_t) ((fp_dp & 0xf0000) >> 4); + writememw(easeg, cpu_state.eaaddr + 0x0c, tmp); + offset = 0x0e; + } + break; + case 0x001: + { /*16-bit protected mode*/ + uint16_t tmp; + tmp = i387_get_control_word(); + writememw(easeg, cpu_state.eaaddr + 0x00, tmp); + tmp = i387_get_status_word(); + writememw(easeg, cpu_state.eaaddr + 0x02, tmp); + tmp = fpu_state.tag; + writememw(easeg, cpu_state.eaaddr + 0x04, tmp); + tmp = (uint16_t) (fpu_state.fip) & 0xffff; + writememw(easeg, cpu_state.eaaddr + 0x06, tmp); + tmp = fpu_state.fcs; + writememw(easeg, cpu_state.eaaddr + 0x08, tmp); + tmp = (uint16_t) (fpu_state.fdp) & 0xffff; + writememw(easeg, cpu_state.eaaddr + 0x0a, tmp); + tmp = fpu_state.fds; + writememw(easeg, cpu_state.eaaddr + 0x0c, tmp); + offset = 0x0e; + } + break; + case 0x100: + { /*32-bit real mode*/ + uint32_t tmp; + uint32_t fp_ip; + uint32_t fp_dp; - fp_ip = ((uint32_t)(fpu_state.fcs << 4)) | fpu_state.fip; - fp_dp = ((uint32_t)(fpu_state.fds << 4)) | fpu_state.fdp; + fp_ip = ((uint32_t) (fpu_state.fcs << 4)) | fpu_state.fip; + fp_dp = ((uint32_t) (fpu_state.fds << 4)) | fpu_state.fdp; - tmp = 0xffff0000 | i387_get_control_word(); - writememl(easeg, cpu_state.eaaddr + 0x00, tmp); - tmp = 0xffff0000 | i387_get_status_word(); - writememl(easeg, cpu_state.eaaddr + 0x04, tmp); - tmp = 0xffff0000 | fpu_state.tag; - writememl(easeg, cpu_state.eaaddr + 0x08, tmp); - tmp = 0xffff0000 | (fp_ip & 0xffff); - writememl(easeg, cpu_state.eaaddr + 0x0c, tmp); - tmp = ((fp_ip & 0xffff0000) >> 4) | fpu_state.foo; - writememl(easeg, cpu_state.eaaddr + 0x10, tmp); - tmp = 0xffff0000 | (fp_dp & 0xffff); - writememl(easeg, cpu_state.eaaddr + 0x14, tmp); - tmp = (fp_dp & 0xffff0000) >> 4; - writememl(easeg, cpu_state.eaaddr + 0x18, tmp); - offset = 0x1c; - } - break; - case 0x101: { /*32-bit protected mode*/ - uint32_t tmp; - tmp = 0xffff0000 | i387_get_control_word(); - writememl(easeg, cpu_state.eaaddr + 0x00, tmp); - tmp = 0xffff0000 | i387_get_status_word(); - writememl(easeg, cpu_state.eaaddr + 0x04, tmp); - tmp = 0xffff0000 | fpu_state.tag; - writememl(easeg, cpu_state.eaaddr + 0x08, tmp); - tmp = (uint32_t)(fpu_state.fip); - writememl(easeg, cpu_state.eaaddr + 0x0c, tmp); - tmp = fpu_state.fcs | (((uint32_t)(fpu_state.foo)) << 16); - writememl(easeg, cpu_state.eaaddr + 0x10, tmp); - tmp = (uint32_t)(fpu_state.fdp); - writememl(easeg, cpu_state.eaaddr + 0x14, tmp); - tmp = 0xffff0000 | fpu_state.fds; - writememl(easeg, cpu_state.eaaddr + 0x18, tmp); - offset = 0x1c; - } - break; + tmp = 0xffff0000 | i387_get_control_word(); + writememl(easeg, cpu_state.eaaddr + 0x00, tmp); + tmp = 0xffff0000 | i387_get_status_word(); + writememl(easeg, cpu_state.eaaddr + 0x04, tmp); + tmp = 0xffff0000 | fpu_state.tag; + writememl(easeg, cpu_state.eaaddr + 0x08, tmp); + tmp = 0xffff0000 | (fp_ip & 0xffff); + writememl(easeg, cpu_state.eaaddr + 0x0c, tmp); + tmp = ((fp_ip & 0xffff0000) >> 4) | fpu_state.foo; + writememl(easeg, cpu_state.eaaddr + 0x10, tmp); + tmp = 0xffff0000 | (fp_dp & 0xffff); + writememl(easeg, cpu_state.eaaddr + 0x14, tmp); + tmp = (fp_dp & 0xffff0000) >> 4; + writememl(easeg, cpu_state.eaaddr + 0x18, tmp); + offset = 0x1c; + } + break; + case 0x101: + { /*32-bit protected mode*/ + uint32_t tmp; + tmp = 0xffff0000 | i387_get_control_word(); + writememl(easeg, cpu_state.eaaddr + 0x00, tmp); + tmp = 0xffff0000 | i387_get_status_word(); + writememl(easeg, cpu_state.eaaddr + 0x04, tmp); + tmp = 0xffff0000 | fpu_state.tag; + writememl(easeg, cpu_state.eaaddr + 0x08, tmp); + tmp = (uint32_t) (fpu_state.fip); + writememl(easeg, cpu_state.eaaddr + 0x0c, tmp); + tmp = fpu_state.fcs | (((uint32_t) (fpu_state.foo)) << 16); + writememl(easeg, cpu_state.eaaddr + 0x10, tmp); + tmp = (uint32_t) (fpu_state.fdp); + writememl(easeg, cpu_state.eaaddr + 0x14, tmp); + tmp = 0xffff0000 | fpu_state.fds; + writememl(easeg, cpu_state.eaaddr + 0x18, tmp); + offset = 0x1c; + } + break; } return (cpu_state.eaaddr + offset); @@ -112,95 +119,104 @@ fpu_load_environment(void) unsigned offset = 0; switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { - case 0x000: { /*16-bit real mode*/ - uint16_t tmp; - uint32_t fp_ip, fp_dp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c); - fp_dp = (tmp & 0xf000) << 4; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a); - fpu_state.fdp = fp_dp | tmp; - fpu_state.fds = 0; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x08); - fp_ip = (tmp & 0xf000) << 4; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x06); - fpu_state.fip = fp_ip | tmp; - fpu_state.fcs = 0; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x04); - fpu_state.tag = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x02); - fpu_state.swd = tmp; - fpu_state.tos = (tmp >> 11) & 7; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x00); - fpu_state.cwd = tmp; - offset = 0x0e; - } - break; - case 0x001: {/*16-bit protected mode*/ - uint16_t tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c); - fpu_state.fds = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a); - fpu_state.fdp = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x08); - fpu_state.fcs = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x06); - fpu_state.fip = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x04); - fpu_state.tag = tmp; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x02); - fpu_state.swd = tmp; - fpu_state.tos = (tmp >> 11) & 7; - tmp = readmemw(easeg, cpu_state.eaaddr + 0x00); - fpu_state.cwd = tmp; - offset = 0x0e; - } - break; - case 0x100: { /*32-bit real mode*/ - uint32_t tmp, fp_ip, fp_dp; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x18); - fp_dp = (tmp & 0x0ffff000) << 4; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x14); - fp_dp |= (tmp & 0xffff); - fpu_state.fdp = fp_dp; - fpu_state.fds = 0; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x10); - fpu_state.foo = tmp & 0x07ff; - fp_ip = (tmp & 0x0ffff000) << 4; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c); - fp_ip |= (tmp & 0xffff); - fpu_state.fip = fp_ip; - fpu_state.fcs = 0; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x08); - fpu_state.tag = tmp & 0xffff; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x04); - fpu_state.swd = tmp & 0xffff; - fpu_state.tos = (tmp >> 11) & 7; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x00); - fpu_state.cwd = tmp & 0xffff; - offset = 0x1c; - } - break; - case 0x101: { /*32-bit protected mode*/ - uint32_t tmp; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x18); - fpu_state.fds = tmp & 0xffff; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x14); - fpu_state.fdp = tmp; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x10); - fpu_state.fcs = tmp & 0xffff; - fpu_state.foo = (tmp >> 16) & 0x07ff; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c); - fpu_state.fip = tmp; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x08); - fpu_state.tag = tmp & 0xffff; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x04); - fpu_state.swd = tmp & 0xffff; - fpu_state.tos = (tmp >> 11) & 7; - tmp = readmeml(easeg, cpu_state.eaaddr + 0x00); - fpu_state.cwd = tmp & 0xffff; - offset = 0x1c; - } - break; + case 0x000: + { /*16-bit real mode*/ + uint16_t tmp; + uint32_t fp_ip; + uint32_t fp_dp; + + tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c); + fp_dp = (tmp & 0xf000) << 4; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a); + fpu_state.fdp = fp_dp | tmp; + fpu_state.fds = 0; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x08); + fp_ip = (tmp & 0xf000) << 4; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x06); + fpu_state.fip = fp_ip | tmp; + fpu_state.fcs = 0; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x04); + fpu_state.tag = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x02); + fpu_state.swd = tmp; + fpu_state.tos = (tmp >> 11) & 7; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x00); + fpu_state.cwd = tmp; + offset = 0x0e; + } + break; + case 0x001: + { /*16-bit protected mode*/ + uint16_t tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c); + fpu_state.fds = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a); + fpu_state.fdp = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x08); + fpu_state.fcs = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x06); + fpu_state.fip = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x04); + fpu_state.tag = tmp; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x02); + fpu_state.swd = tmp; + fpu_state.tos = (tmp >> 11) & 7; + tmp = readmemw(easeg, cpu_state.eaaddr + 0x00); + fpu_state.cwd = tmp; + offset = 0x0e; + } + break; + case 0x100: + { /*32-bit real mode*/ + uint32_t tmp; + uint32_t fp_ip; + uint32_t fp_dp; + + tmp = readmeml(easeg, cpu_state.eaaddr + 0x18); + fp_dp = (tmp & 0x0ffff000) << 4; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x14); + fp_dp |= (tmp & 0xffff); + fpu_state.fdp = fp_dp; + fpu_state.fds = 0; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x10); + fpu_state.foo = tmp & 0x07ff; + fp_ip = (tmp & 0x0ffff000) << 4; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c); + fp_ip |= (tmp & 0xffff); + fpu_state.fip = fp_ip; + fpu_state.fcs = 0; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x08); + fpu_state.tag = tmp & 0xffff; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x04); + fpu_state.swd = tmp & 0xffff; + fpu_state.tos = (tmp >> 11) & 7; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x00); + fpu_state.cwd = tmp & 0xffff; + offset = 0x1c; + } + break; + case 0x101: + { /*32-bit protected mode*/ + uint32_t tmp; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x18); + fpu_state.fds = tmp & 0xffff; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x14); + fpu_state.fdp = tmp; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x10); + fpu_state.fcs = tmp & 0xffff; + fpu_state.foo = (tmp >> 16) & 0x07ff; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c); + fpu_state.fip = tmp; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x08); + fpu_state.tag = tmp & 0xffff; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x04); + fpu_state.swd = tmp & 0xffff; + fpu_state.tos = (tmp >> 11) & 7; + tmp = readmeml(easeg, cpu_state.eaaddr + 0x00); + fpu_state.cwd = tmp & 0xffff; + offset = 0x1c; + } + break; } /* always set bit 6 as '1 */ @@ -356,7 +372,7 @@ static int sf_FRSTOR_a16(uint32_t fetchdat) { floatx80 tmp; - int offset; + int offset; FP_ENTER(); fetch_ea_16(fetchdat); @@ -364,7 +380,7 @@ sf_FRSTOR_a16(uint32_t fetchdat) offset = fpu_load_environment(); for (int n = 0; n < 8; n++) { tmp.fraction = readmemq(easeg, offset + (n * 10)); - tmp.exp = readmemw(easeg, offset + (n * 10) + 8); + tmp.exp = readmemw(easeg, offset + (n * 10) + 8); FPU_save_regi_tag(tmp, IS_TAG_EMPTY(n) ? X87_TAG_EMPTY : FPU_tagof(tmp), n); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); @@ -376,7 +392,7 @@ static int sf_FRSTOR_a32(uint32_t fetchdat) { floatx80 tmp; - int offset; + int offset; FP_ENTER(); fetch_ea_32(fetchdat); @@ -384,7 +400,7 @@ sf_FRSTOR_a32(uint32_t fetchdat) offset = fpu_load_environment(); for (int n = 0; n < 8; n++) { tmp.fraction = readmemq(easeg, offset + (n * 10)); - tmp.exp = readmemw(easeg, offset + (n * 10) + 8); + tmp.exp = readmemw(easeg, offset + (n * 10) + 8); FPU_save_regi_tag(tmp, IS_TAG_EMPTY(n) ? X87_TAG_EMPTY : FPU_tagof(tmp), n); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); @@ -397,7 +413,7 @@ static int sf_FNSAVE_a16(uint32_t fetchdat) { floatx80 stn; - int offset; + int offset; FP_ENTER(); fetch_ea_16(fetchdat); @@ -415,15 +431,15 @@ sf_FNSAVE_a16(uint32_t fetchdat) #else fpu_state.cwd = 0x37F; #endif - fpu_state.swd = 0; - fpu_state.tos = 0; - fpu_state.tag = 0xffff; + fpu_state.swd = 0; + fpu_state.tos = 0; + fpu_state.tag = 0xffff; cpu_state.ismmx = 0; - fpu_state.foo = 0; - fpu_state.fds = 0; - fpu_state.fdp = 0; - fpu_state.fcs = 0; - fpu_state.fip = 0; + fpu_state.foo = 0; + fpu_state.fds = 0; + fpu_state.fdp = 0; + fpu_state.fcs = 0; + fpu_state.fip = 0; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); return cpu_state.abrt; @@ -433,7 +449,7 @@ static int sf_FNSAVE_a32(uint32_t fetchdat) { floatx80 stn; - int offset; + int offset; FP_ENTER(); fetch_ea_32(fetchdat); @@ -446,20 +462,20 @@ sf_FNSAVE_a32(uint32_t fetchdat) writememw(easeg, offset + (m * 10) + 8, stn.exp); } -#ifdef FPU_8087 +# ifdef FPU_8087 fpu_state.swd = 0x3FF; -#else +# else fpu_state.cwd = 0x37F; -#endif - fpu_state.swd = 0; - fpu_state.tos = 0; - fpu_state.tag = 0xffff; +# endif + fpu_state.swd = 0; + fpu_state.tos = 0; + fpu_state.tag = 0xffff; cpu_state.ismmx = 0; - fpu_state.foo = 0; - fpu_state.fds = 0; - fpu_state.fdp = 0; - fpu_state.fcs = 0; - fpu_state.fip = 0; + fpu_state.foo = 0; + fpu_state.fds = 0; + fpu_state.fdp = 0; + fpu_state.fcs = 0; + fpu_state.fip = 0; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); return cpu_state.abrt; @@ -471,9 +487,7 @@ sf_FNCLEX(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - fpu_state.swd &= ~(FPU_SW_Backward | FPU_SW_Summary | FPU_SW_Stack_Fault | FPU_SW_Precision | - FPU_SW_Underflow | FPU_SW_Overflow | FPU_SW_Zero_Div | FPU_SW_Denormal_Op | - FPU_SW_Invalid); + fpu_state.swd &= ~(FPU_SW_Backward | FPU_SW_Summary | FPU_SW_Stack_Fault | FPU_SW_Precision | FPU_SW_Underflow | FPU_SW_Overflow | FPU_SW_Zero_Div | FPU_SW_Denormal_Op | FPU_SW_Invalid); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); return 0; @@ -489,14 +503,14 @@ sf_FNINIT(uint32_t fetchdat) #else fpu_state.cwd = 0x37F; #endif - fpu_state.swd = 0; + fpu_state.swd = 0; fpu_state.tos = 0; - fpu_state.tag = 0xffff; - fpu_state.foo = 0; - fpu_state.fds = 0; - fpu_state.fdp = 0; - fpu_state.fcs = 0; - fpu_state.fip = 0; + fpu_state.tag = 0xffff; + fpu_state.foo = 0; + fpu_state.fds = 0; + fpu_state.fdp = 0; + fpu_state.fcs = 0; + fpu_state.fip = 0; cpu_state.ismmx = 0; CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi)); @@ -559,7 +573,7 @@ sf_FNSTENV_a16(uint32_t fetchdat) /* mask all floating point exceptions */ fpu_state.cwd |= FPU_CW_Exceptions_Mask; /* clear the B and ES bits in the status word */ - fpu_state.swd &= ~(FPU_SW_Backward|FPU_SW_Summary); + fpu_state.swd &= ~(FPU_SW_Backward | FPU_SW_Summary); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); return cpu_state.abrt; @@ -575,7 +589,7 @@ sf_FNSTENV_a32(uint32_t fetchdat) /* mask all floating point exceptions */ fpu_state.cwd |= FPU_CW_Exceptions_Mask; /* clear the B and ES bits in the status word */ - fpu_state.swd &= ~(FPU_SW_Backward|FPU_SW_Summary); + fpu_state.swd &= ~(FPU_SW_Backward | FPU_SW_Summary); CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); return cpu_state.abrt; diff --git a/src/cpu/x87_ops_sf_arith.h b/src/cpu/x87_ops_sf_arith.h index 10b100b2a..5144062bb 100644 --- a/src/cpu/x87_ops_sf_arith.h +++ b/src/cpu/x87_ops_sf_arith.h @@ -1,180 +1,180 @@ -#define sf_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ - static int sf_FADD##name##_a##a_size(uint32_t fetchdat) \ +#define sf_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ + static int sf_FADD##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) \ - result = floatx80_add(a, use_var, &status); \ - \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) \ + result = floatx80_add(a, use_var, &status); \ + \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FDIV##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FDIV##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) { \ - result = floatx80_div(a, use_var, &status); \ - } \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) { \ + result = floatx80_div(a, use_var, &status); \ + } \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FDIVR##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FDIVR##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) { \ - result = floatx80_div(use_var, a, &status); \ - } \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) { \ + result = floatx80_div(use_var, a, &status); \ + } \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv##cycle_postfix) : ((x87_concurrency.fdiv##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FMUL##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FMUL##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) { \ - result = floatx80_mul(a, use_var, &status); \ - } \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) { \ + result = floatx80_mul(a, use_var, &status); \ + } \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul##cycle_postfix) : ((x87_timings.fmul##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul##cycle_postfix) : ((x87_concurrency.fmul##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FSUB##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FSUB##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) \ - result = floatx80_sub(a, use_var, &status); \ - \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) \ + result = floatx80_sub(a, use_var, &status); \ + \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FSUBR##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FSUBR##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a, result; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ - FPU_check_pending_exceptions(); \ + FPU_check_pending_exceptions(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_stack_underflow(fetchdat, 0, 0); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (!is_nan) \ - result = floatx80_sub(use_var, a, &status); \ - \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_save_regi(result, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_stack_underflow(fetchdat, 0, 0); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (!is_nan) \ + result = floatx80_sub(use_var, a, &status); \ + \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_save_regi(result, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ @@ -198,12 +198,13 @@ sf_FPU(il, uint32_t, 16, temp, geteal(), int32_to_floatx80((int32_t)temp), 0, _i #ifndef FPU_8087 sf_FPU(il, uint32_t, 32, temp, geteal(), int32_to_floatx80((int32_t)temp), 0, _i32) #endif -// clang-format on + // clang-format on -static int -sf_FADD_st0_stj(uint32_t fetchdat) + static int sf_FADD_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -215,8 +216,8 @@ sf_FADD_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_add(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -230,7 +231,9 @@ next_ins: static int sf_FADD_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -242,8 +245,8 @@ sf_FADD_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_add(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -258,7 +261,9 @@ next_ins: static int sf_FADDP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -270,8 +275,8 @@ sf_FADDP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_add(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -288,7 +293,9 @@ next_ins: static int sf_FDIV_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -299,8 +306,8 @@ sf_FDIV_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -315,7 +322,9 @@ next_ins: static int sf_FDIV_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -326,8 +335,8 @@ sf_FDIV_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -341,7 +350,9 @@ next_ins: static int sf_FDIVP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -352,8 +363,8 @@ sf_FDIVP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -370,7 +381,9 @@ next_ins: static int sf_FDIVR_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -381,8 +394,8 @@ sf_FDIVR_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -396,7 +409,9 @@ next_ins: static int sf_FDIVR_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -407,8 +422,8 @@ sf_FDIVR_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) @@ -422,7 +437,9 @@ next_ins: static int sf_FDIVRP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -433,8 +450,8 @@ sf_FDIVRP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_div(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -451,7 +468,9 @@ next_ins: static int sf_FMUL_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -462,8 +481,8 @@ sf_FMUL_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_mul(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -478,7 +497,9 @@ next_ins: static int sf_FMUL_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -489,8 +510,8 @@ sf_FMUL_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_mul(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -505,7 +526,9 @@ next_ins: static int sf_FMULP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -516,8 +539,8 @@ sf_FMULP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_mul(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -534,7 +557,9 @@ next_ins: static int sf_FSUB_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -545,8 +570,8 @@ sf_FSUB_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -561,7 +586,9 @@ next_ins: static int sf_FSUB_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -572,8 +599,8 @@ sf_FSUB_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -588,7 +615,9 @@ next_ins: static int sf_FSUBP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -599,8 +628,8 @@ sf_FSUBP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -617,7 +646,9 @@ next_ins: static int sf_FSUBR_st0_stj(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -628,8 +659,8 @@ sf_FSUBR_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(fetchdat & 7); - b = FPU_read_regi(0); + a = FPU_read_regi(fetchdat & 7); + b = FPU_read_regi(0); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -644,7 +675,9 @@ next_ins: static int sf_FSUBR_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -655,8 +688,8 @@ sf_FSUBR_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -671,7 +704,9 @@ next_ins: static int sf_FSUBRP_sti_st0(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -682,8 +717,8 @@ sf_FSUBRP_sti_st0(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); result = floatx80_sub(a, b, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { @@ -700,7 +735,7 @@ next_ins: static int sf_FSQRT(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -726,7 +761,7 @@ next_ins: static int sf_FRNDINT(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); diff --git a/src/cpu/x87_ops_sf_compare.h b/src/cpu/x87_ops_sf_compare.h index 59135c05b..6b4c1cb62 100644 --- a/src/cpu/x87_ops_sf_compare.h +++ b/src/cpu/x87_ops_sf_compare.h @@ -1,76 +1,76 @@ -#define cmp_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ - static int sf_FCOM##name##_a##a_size(uint32_t fetchdat) \ +#define cmp_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ + static int sf_FCOM##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a; \ - int rc; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a; \ + int rc; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ - setcc(C0 | C2 | C3); \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (is_nan) { \ - rc = float_relation_unordered; \ - float_raise(&status, float_flag_invalid); \ - } else { \ - rc = floatx80_compare_two(a, use_var, &status); \ - } \ - setcc(FPU_status_word_flags_fpu_compare(rc)); \ - FPU_exception(fetchdat, status.float_exception_flags, 0); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ + setcc(C0 | C2 | C3); \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (is_nan) { \ + rc = float_relation_unordered; \ + float_raise(&status, float_flag_invalid); \ + } else { \ + rc = floatx80_compare_two(a, use_var, &status); \ + } \ + setcc(FPU_status_word_flags_fpu_compare(rc)); \ + FPU_exception(fetchdat, status.float_exception_flags, 0); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int sf_FCOMP##name##_a##a_size(uint32_t fetchdat) \ + static int sf_FCOMP##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a; \ - int rc; \ - struct float_status_t status; \ - optype temp; \ + floatx80 a; \ + int rc; \ + struct float_status_t status; \ + optype temp; \ FP_ENTER(); \ fetch_ea_##a_size(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = rw; \ - if (cpu_state.abrt) \ - return 1;\ - clear_C1(); \ - if (IS_TAG_EMPTY(0)) { \ - FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ - setcc(C0 | C2 | C3); \ - if (is_IA_masked()) \ - FPU_pop(); \ - \ - goto next_ins; \ - } \ - status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ - a = FPU_read_regi(0); \ - if (is_nan) { \ - rc = float_relation_unordered; \ - float_raise(&status, float_flag_invalid); \ - } else { \ - rc = floatx80_compare_two(a, use_var, &status); \ - } \ - setcc(FPU_status_word_flags_fpu_compare(rc)); \ - if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ - FPU_pop(); \ - \ -next_ins: \ + load_var = rw; \ + if (cpu_state.abrt) \ + return 1; \ + clear_C1(); \ + if (IS_TAG_EMPTY(0)) { \ + FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \ + setcc(C0 | C2 | C3); \ + if (is_IA_masked()) \ + FPU_pop(); \ + \ + goto next_ins; \ + } \ + status = i387cw_to_softfloat_status_word(i387_get_control_word()); \ + a = FPU_read_regi(0); \ + if (is_nan) { \ + rc = float_relation_unordered; \ + float_raise(&status, float_flag_invalid); \ + } else { \ + rc = floatx80_compare_two(a, use_var, &status); \ + } \ + setcc(FPU_status_word_flags_fpu_compare(rc)); \ + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \ + FPU_pop(); \ + \ +next_ins: \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ return 0; \ - } \ + } // clang-format off cmp_FPU(s, float32, 16, temp, geteal(), float32_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float32_is_nan(temp), _32) @@ -90,14 +90,14 @@ cmp_FPU(il, int32_t, 16, temp, (int32_t)geteal(), int32_to_floatx80(temp), 0, _i #ifndef FPU_8087 cmp_FPU(il, int32_t, 32, temp, (int32_t)geteal(), int32_to_floatx80(temp), 0, _i32) #endif -// clang-format on + // clang-format on -static int -sf_FCOM_sti(uint32_t fetchdat) + static int sf_FCOM_sti(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -108,9 +108,9 @@ sf_FCOM_sti(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_two(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); FPU_exception(fetchdat, status.float_exception_flags, 0); @@ -123,9 +123,10 @@ next_ins: static int sf_FCOMP_sti(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -139,9 +140,9 @@ sf_FCOMP_sti(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_two(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); @@ -156,9 +157,10 @@ next_ins: static int sf_FCOMPP(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -173,9 +175,9 @@ sf_FCOMPP(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(1); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(1); + rc = floatx80_compare_two(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); @@ -192,9 +194,10 @@ next_ins: static int sf_FUCOMPP(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -209,9 +212,9 @@ sf_FUCOMPP(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(1); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(1); + rc = floatx80_compare_quiet(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); @@ -224,12 +227,14 @@ next_ins: return 0; } +# ifndef OPS_286_386 static int sf_FCOMI_st0_stj(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -241,9 +246,9 @@ sf_FCOMI_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_two(a, b, &status); FPU_write_eflags_fpu_compare(rc); FPU_exception(fetchdat, status.float_exception_flags, 0); @@ -255,9 +260,10 @@ next_ins: static int sf_FCOMIP_st0_stj(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -272,9 +278,9 @@ sf_FCOMIP_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_two(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_two(a, b, &status); FPU_write_eflags_fpu_compare(rc); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); @@ -285,13 +291,15 @@ 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) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -302,9 +310,9 @@ sf_FUCOM_sti(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_quiet(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); FPU_exception(fetchdat, status.float_exception_flags, 0); @@ -317,9 +325,10 @@ next_ins: static int sf_FUCOMP_sti(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -333,9 +342,9 @@ sf_FUCOMP_sti(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_quiet(a, b, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_pop(); @@ -346,12 +355,14 @@ next_ins: return 0; } +# ifndef OPS_286_386 static int sf_FUCOMI_st0_stj(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -363,9 +374,9 @@ sf_FUCOMI_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_quiet(a, b, &status); FPU_write_eflags_fpu_compare(rc); FPU_exception(fetchdat, status.float_exception_flags, 0); @@ -377,9 +388,10 @@ next_ins: static int sf_FUCOMIP_st0_stj(uint32_t fetchdat) { - floatx80 a, b; + floatx80 a; + floatx80 b; struct float_status_t status; - int rc; + int rc; FP_ENTER(); cpu_state.pc++; @@ -394,9 +406,9 @@ sf_FUCOMIP_st0_stj(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(fetchdat & 7); - rc = floatx80_compare_quiet(a, b, &status); + a = FPU_read_regi(0); + b = FPU_read_regi(fetchdat & 7); + rc = floatx80_compare_quiet(a, b, &status); FPU_write_eflags_fpu_compare(rc); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_pop(); @@ -406,12 +418,13 @@ next_ins: CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } +# endif #endif static int sf_FTST(uint32_t fetchdat) { - int rc; + int rc; struct float_status_t status; FP_ENTER(); @@ -422,7 +435,7 @@ sf_FTST(uint32_t fetchdat) setcc(C0 | C2 | C3); } else { status = i387cw_to_softfloat_status_word(i387_get_control_word()); - rc = floatx80_compare_two(FPU_read_regi(0), Const_Z, &status); + rc = floatx80_compare_two(FPU_read_regi(0), Const_Z, &status); setcc(FPU_status_word_flags_fpu_compare(rc)); FPU_exception(fetchdat, status.float_exception_flags, 0); } @@ -434,19 +447,19 @@ sf_FTST(uint32_t fetchdat) static int sf_FXAM(uint32_t fetchdat) { - floatx80 reg; - int sign; + floatx80 reg; + int sign; float_class_t aClass; FP_ENTER(); cpu_state.pc++; - reg = FPU_read_regi(0); + reg = FPU_read_regi(0); sign = floatx80_sign(reg); - /* - * Examine the contents of the ST(0) register and sets the condition - * code flags C0, C2 and C3 in the FPU status word to indicate the - * class of value or number in the register. - */ + /* + * Examine the contents of the ST(0) register and sets the condition + * code flags C0, C2 and C3 in the FPU status word to indicate the + * class of value or number in the register. + */ if (IS_TAG_EMPTY(0)) { setcc(C3 | C1 | C0); } else { @@ -476,10 +489,10 @@ sf_FXAM(uint32_t fetchdat) break; } } - /* - * The C1 flag is set to the sign of the value in ST(0), regardless - * of whether the register is empty or full. - */ + /* + * The C1 flag is set to the sign of the value in ST(0), regardless + * of whether the register is empty or full. + */ if (!sign) clear_C1(); diff --git a/src/cpu/x87_ops_sf_const.h b/src/cpu/x87_ops_sf_const.h index 708c6ff7a..0808cbae8 100644 --- a/src/cpu/x87_ops_sf_const.h +++ b/src/cpu/x87_ops_sf_const.h @@ -1,14 +1,14 @@ /* A fast way to find out whether x is one of RC_DOWN or RC_CHOP (and not one of RC_RND or RC_UP). */ -#define DOWN_OR_CHOP() (fpu_state.cwd & FPU_CW_RC & FPU_RC_DOWN) +#define DOWN_OR_CHOP() (fpu_state.cwd & FPU_CW_RC & FPU_RC_DOWN) static __inline floatx80 FPU_round_const(const floatx80 a, int adj) { - floatx80 result = a; - result.fraction += adj; - return result; + floatx80 result = a; + result.fraction += adj; + return result; } static int diff --git a/src/cpu/x87_ops_sf_load_store.h b/src/cpu/x87_ops_sf_load_store.h index 69bc5598c..383a7ee52 100644 --- a/src/cpu/x87_ops_sf_load_store.h +++ b/src/cpu/x87_ops_sf_load_store.h @@ -17,13 +17,18 @@ * Copyright 2016-2019 Miran Grca. */ -#define swap_values16u(a, b) { uint16_t tmp = a; a = b; b = tmp; } +#define swap_values16u(a, b) \ + { \ + uint16_t tmp = a; \ + a = b; \ + b = tmp; \ + } static int sf_FILDiw_a16(uint32_t fetchdat) { floatx80 result; - int16_t temp; + int16_t temp; FP_ENTER(); FPU_check_pending_exceptions(); @@ -49,7 +54,7 @@ static int sf_FILDiw_a32(uint32_t fetchdat) { floatx80 result; - int16_t temp; + int16_t temp; FP_ENTER(); FPU_check_pending_exceptions(); @@ -76,7 +81,7 @@ static int sf_FILDil_a16(uint32_t fetchdat) { floatx80 result; - int32_t templ; + int32_t templ; FP_ENTER(); FPU_check_pending_exceptions(); @@ -102,7 +107,7 @@ static int sf_FILDil_a32(uint32_t fetchdat) { floatx80 result; - int32_t templ; + int32_t templ; FP_ENTER(); FPU_check_pending_exceptions(); @@ -129,7 +134,7 @@ static int sf_FILDiq_a16(uint32_t fetchdat) { floatx80 result; - int64_t temp64; + int64_t temp64; FP_ENTER(); FPU_check_pending_exceptions(); @@ -155,7 +160,7 @@ static int sf_FILDiq_a32(uint32_t fetchdat) { floatx80 result; - int64_t temp64; + int64_t temp64; FP_ENTER(); FPU_check_pending_exceptions(); @@ -182,9 +187,9 @@ static int sf_FLDs_a16(uint32_t fetchdat) { struct float_status_t status; - floatx80 result; - float32 load_reg; - unsigned unmasked; + floatx80 result; + float32 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -198,8 +203,8 @@ sf_FLDs_a16(uint32_t fetchdat) FPU_stack_overflow(fetchdat); goto next_ins; } - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float32_to_floatx80(load_reg, &status); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = float32_to_floatx80(load_reg, &status); unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); @@ -216,9 +221,9 @@ static int sf_FLDs_a32(uint32_t fetchdat) { struct float_status_t status; - floatx80 result; - float32 load_reg; - unsigned unmasked; + floatx80 result; + float32 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -232,8 +237,8 @@ sf_FLDs_a32(uint32_t fetchdat) FPU_stack_overflow(fetchdat); goto next_ins; } - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float32_to_floatx80(load_reg, &status); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = float32_to_floatx80(load_reg, &status); unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); @@ -251,9 +256,9 @@ static int sf_FLDd_a16(uint32_t fetchdat) { struct float_status_t status; - floatx80 result; - float64 load_reg; - unsigned unmasked; + floatx80 result; + float64 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -267,8 +272,8 @@ sf_FLDd_a16(uint32_t fetchdat) FPU_stack_overflow(fetchdat); goto next_ins; } - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float64_to_floatx80(load_reg, &status); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = float64_to_floatx80(load_reg, &status); unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); @@ -285,9 +290,9 @@ static int sf_FLDd_a32(uint32_t fetchdat) { struct float_status_t status; - floatx80 result; - float64 load_reg; - unsigned unmasked; + floatx80 result; + float64 load_reg; + unsigned unmasked; FP_ENTER(); FPU_check_pending_exceptions(); @@ -301,8 +306,8 @@ sf_FLDd_a32(uint32_t fetchdat) FPU_stack_overflow(fetchdat); goto next_ins; } - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - result = float64_to_floatx80(load_reg, &status); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + result = float64_to_floatx80(load_reg, &status); unmasked = FPU_exception(fetchdat, status.float_exception_flags, 0); if (!(unmasked & FPU_CW_Invalid)) { FPU_push(); @@ -326,7 +331,7 @@ sf_FLDe_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); result.fraction = readmemq(easeg, cpu_state.eaaddr); - result.exp = readmemw(easeg, cpu_state.eaaddr + 8); + result.exp = readmemw(easeg, cpu_state.eaaddr + 8); if (cpu_state.abrt) return 1; clear_C1(); @@ -351,7 +356,7 @@ sf_FLDe_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_READ(cpu_state.ea_seg); result.fraction = readmemq(easeg, cpu_state.eaaddr); - result.exp = readmemw(easeg, cpu_state.eaaddr + 8); + result.exp = readmemw(easeg, cpu_state.eaaddr + 8); if (cpu_state.abrt) return 1; clear_C1(); @@ -371,7 +376,7 @@ static int sf_FLD_sti(uint32_t fetchdat) { const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 sti_reg; + floatx80 sti_reg; FP_ENTER(); FPU_check_pending_exceptions(); @@ -403,8 +408,8 @@ static int sf_FISTiw_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -417,7 +422,7 @@ sf_FISTiw_a16(uint32_t fetchdat) goto next_ins; } } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int16(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -438,8 +443,8 @@ static int sf_FISTiw_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -451,7 +456,7 @@ sf_FISTiw_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int16(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -472,8 +477,8 @@ static int sf_FISTPiw_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -485,7 +490,7 @@ sf_FISTPiw_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int16(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -509,8 +514,8 @@ static int sf_FISTPiw_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int16_t save_reg = int16_indefinite; + uint16_t sw = fpu_state.swd; + int16_t save_reg = int16_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -522,7 +527,7 @@ sf_FISTPiw_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int16(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -546,8 +551,8 @@ static int sf_FISTil_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -559,7 +564,7 @@ sf_FISTil_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -580,8 +585,8 @@ static int sf_FISTil_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -593,7 +598,7 @@ sf_FISTil_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -614,8 +619,8 @@ static int sf_FISTPil_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -627,7 +632,7 @@ sf_FISTPil_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -651,8 +656,8 @@ static int sf_FISTPil_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int32_t save_reg = int32_indefinite; + uint16_t sw = fpu_state.swd; + int32_t save_reg = int32_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -664,7 +669,7 @@ sf_FISTPil_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -688,8 +693,8 @@ static int sf_FISTPiq_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int64_t save_reg = int64_indefinite; + uint16_t sw = fpu_state.swd; + int64_t save_reg = int64_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -701,9 +706,9 @@ sf_FISTPiq_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int64(FPU_read_regi(0), &status); - if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { + if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; } } @@ -725,8 +730,8 @@ static int sf_FISTPiq_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - int64_t save_reg = int64_indefinite; + uint16_t sw = fpu_state.swd; + int64_t save_reg = int64_indefinite; FP_ENTER(); FPU_check_pending_exceptions(); @@ -738,7 +743,7 @@ sf_FISTPiq_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_int64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -762,12 +767,12 @@ static int sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - uint16_t save_reg_hi = 0xffff; - uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); - floatx80 reg; - int64_t save_val; - int sign; + uint16_t sw = fpu_state.swd; + uint16_t save_reg_hi = 0xffff; + uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); + floatx80 reg; + int64_t save_val; + int sign; FP_ENTER(); FPU_check_pending_exceptions(); @@ -779,10 +784,10 @@ sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - reg = FPU_read_regi(0); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + reg = FPU_read_regi(0); save_val = floatx80_to_int64(reg, &status); - sign = (reg.exp & 0x8000) != 0; + sign = (reg.exp & 0x8000) != 0; if (sign) save_val = -save_val; @@ -793,12 +798,12 @@ sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) save_reg_hi = sign ? 0x8000 : 0; save_reg_lo = 0; for (int i = 0; i < 16; i++) { - save_reg_lo += ((uint64_t)(save_val % 10)) << (4 * i); + save_reg_lo += ((uint64_t) (save_val % 10)) << (4 * i); save_val /= 10; } - save_reg_hi += (uint16_t)(save_val % 10); + save_reg_hi += (uint16_t) (save_val % 10); save_val /= 10; - save_reg_hi += (uint16_t)(save_val % 10) << 4; + save_reg_hi += (uint16_t) (save_val % 10) << 4; } /* check for fpu arithmetic exceptions */ if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { @@ -826,12 +831,12 @@ static int sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - uint16_t save_reg_hi = 0xffff; - uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); - floatx80 reg; - int64_t save_val; - int sign; + uint16_t sw = fpu_state.swd; + uint16_t save_reg_hi = 0xffff; + uint64_t save_reg_lo = BX_CONST64(0xC000000000000000); + floatx80 reg; + int64_t save_val; + int sign; FP_ENTER(); FPU_check_pending_exceptions(); @@ -843,10 +848,10 @@ sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); - reg = FPU_read_regi(0); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); + reg = FPU_read_regi(0); save_val = floatx80_to_int64(reg, &status); - sign = (reg.exp & 0x8000) != 0; + sign = (reg.exp & 0x8000) != 0; if (sign) save_val = -save_val; @@ -857,12 +862,12 @@ sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) save_reg_hi = sign ? 0x8000 : 0; save_reg_lo = 0; for (int i = 0; i < 16; i++) { - save_reg_lo += ((uint64_t)(save_val % 10)) << (4 * i); + save_reg_lo += ((uint64_t) (save_val % 10)) << (4 * i); save_val /= 10; } - save_reg_hi += (uint16_t)(save_val % 10); + save_reg_hi += (uint16_t) (save_val % 10); save_val /= 10; - save_reg_hi += (uint16_t)(save_val % 10) << 4; + save_reg_hi += (uint16_t) (save_val % 10) << 4; } /* check for fpu arithmetic exceptions */ if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { @@ -891,8 +896,8 @@ static int sf_FSTs_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -904,7 +909,7 @@ sf_FSTs_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -925,8 +930,8 @@ static int sf_FSTs_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -938,7 +943,7 @@ sf_FSTs_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -959,8 +964,8 @@ static int sf_FSTPs_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -972,7 +977,7 @@ sf_FSTPs_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -997,8 +1002,8 @@ static int sf_FSTPs_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float32 save_reg = float32_default_nan; + uint16_t sw = fpu_state.swd; + float32 save_reg = float32_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1010,7 +1015,7 @@ sf_FSTPs_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float32(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -1034,8 +1039,8 @@ static int sf_FSTd_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1047,7 +1052,7 @@ sf_FSTd_a16(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -1068,8 +1073,8 @@ static int sf_FSTd_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1081,7 +1086,7 @@ sf_FSTd_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -1102,8 +1107,8 @@ static int sf_FSTPd_a16(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1116,7 +1121,7 @@ sf_FSTPd_a16(uint32_t fetchdat) goto next_ins; } } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) { goto next_ins; @@ -1140,8 +1145,8 @@ static int sf_FSTPd_a32(uint32_t fetchdat) { struct float_status_t status; - uint16_t sw = fpu_state.swd; - float64 save_reg = float64_default_nan; + uint16_t sw = fpu_state.swd; + float64 save_reg = float64_default_nan; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1153,7 +1158,7 @@ sf_FSTPd_a32(uint32_t fetchdat) if (!is_IA_masked()) goto next_ins; } else { - status = i387cw_to_softfloat_status_word(i387_get_control_word()); + status = i387cw_to_softfloat_status_word(i387_get_control_word()); save_reg = floatx80_to_float64(FPU_read_regi(0), &status); if (FPU_exception(fetchdat, status.float_exception_flags, 1)) goto next_ins; @@ -1177,7 +1182,7 @@ static int sf_FSTPe_a16(uint32_t fetchdat) { const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 save_reg; + floatx80 save_reg; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1209,7 +1214,7 @@ static int sf_FSTPe_a32(uint32_t fetchdat) { const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 save_reg; + floatx80 save_reg; FP_ENTER(); FPU_check_pending_exceptions(); @@ -1279,25 +1284,26 @@ sf_FSTP_sti(uint32_t fetchdat) } #ifndef FPU_8087 -# define sf_FCMOV(condition) \ - static int sf_FCMOV##condition(uint32_t fetchdat) \ - { \ - FP_ENTER(); \ - FPU_check_pending_exceptions(); \ - cpu_state.pc++; \ - if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) \ - FPU_stack_underflow(fetchdat, 0, 0); \ - else { \ - if (cond_##condition) { \ - FPU_save_regi(FPU_read_regi(fetchdat & 7), 0); \ - } \ - } \ - CLOCK_CYCLES_FPU(4); \ - return 0; \ - } +# ifndef OPS_286_386 +# define sf_FCMOV(condition) \ + static int sf_FCMOV##condition(uint32_t fetchdat) \ + { \ + FP_ENTER(); \ + FPU_check_pending_exceptions(); \ + cpu_state.pc++; \ + if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) \ + FPU_stack_underflow(fetchdat, 0, 0); \ + else { \ + if (cond_##condition) { \ + FPU_save_regi(FPU_read_regi(fetchdat & 7), 0); \ + } \ + } \ + CLOCK_CYCLES_FPU(4); \ + return 0; \ + } -# define cond_U (PF_SET()) -# define cond_NU (!PF_SET()) +# define cond_U (PF_SET()) +# define cond_NU (!PF_SET()) // clang-format off sf_FCMOV(B) @@ -1309,4 +1315,5 @@ sf_FCMOV(NE) sf_FCMOV(NBE) sf_FCMOV(NU) // clang-format on +# endif #endif diff --git a/src/cpu/x87_ops_sf_misc.h b/src/cpu/x87_ops_sf_misc.h index d8a3d7368..85f42e6d5 100644 --- a/src/cpu/x87_ops_sf_misc.h +++ b/src/cpu/x87_ops_sf_misc.h @@ -2,8 +2,10 @@ static int sf_FXCH_sti(uint32_t fetchdat) { const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 st0_reg, sti_reg; - int st0_tag, sti_tag; + floatx80 st0_reg; + floatx80 sti_reg; + int st0_tag; + int sti_tag; FP_ENTER(); FPU_check_pending_exceptions(); @@ -48,7 +50,7 @@ sf_FCHS(uint32_t fetchdat) else { clear_C1(); st0_reg = FPU_read_regi(0); - result = floatx80_chs(st0_reg); + result = floatx80_chs(st0_reg); FPU_save_regi(result, 0); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); @@ -70,7 +72,7 @@ sf_FABS(uint32_t fetchdat) else { clear_C1(); st0_reg = FPU_read_regi(0); - result = floatx80_abs(st0_reg); + result = floatx80_abs(st0_reg); FPU_save_regi(result, 0); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); diff --git a/src/cpu/x87_ops_sf_trans.h b/src/cpu/x87_ops_sf_trans.h index 5289b2bbf..5a99abb4c 100644 --- a/src/cpu/x87_ops_sf_trans.h +++ b/src/cpu/x87_ops_sf_trans.h @@ -1,7 +1,7 @@ static int sf_F2XM1(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -13,7 +13,7 @@ sf_F2XM1(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = f2xm1(FPU_read_regi(0), &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_save_regi(result, 0); next_ins: @@ -25,7 +25,7 @@ next_ins: static int sf_FYL2X(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -37,7 +37,7 @@ sf_FYL2X(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = fyl2x(FPU_read_regi(0), FPU_read_regi(1), &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); FPU_save_regi(result, 0); } @@ -51,8 +51,8 @@ next_ins: static int sf_FPTAN(uint32_t fetchdat) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); - floatx80 y; + const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + floatx80 y; struct float_status_t status; FP_ENTER(); @@ -74,14 +74,14 @@ sf_FPTAN(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); - y = FPU_read_regi(0); + y = FPU_read_regi(0); if (ftan(&y, &status) == -1) { fpu_state.swd |= C2; goto next_ins; } if (floatx80_is_nan(y)) { - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(y, 0); FPU_push(); FPU_save_regi(y, 0); @@ -89,7 +89,7 @@ sf_FPTAN(uint32_t fetchdat) goto next_ins; } - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(y, 0); FPU_push(); FPU_save_regi(Const_1, 0); @@ -104,7 +104,9 @@ next_ins: static int sf_FPATAN(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -113,11 +115,11 @@ sf_FPATAN(uint32_t fetchdat) FPU_stack_underflow(fetchdat, 1, 1); goto next_ins; } - a = FPU_read_regi(0); - b = FPU_read_regi(1); + a = FPU_read_regi(0); + b = FPU_read_regi(1); status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = fpatan(a, b, &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_pop(); FPU_save_regi(result, 0); } @@ -132,13 +134,14 @@ static int sf_FXTRACT(uint32_t fetchdat) { struct float_status_t status; - floatx80 a, b; + floatx80 a; + floatx80 b; FP_ENTER(); cpu_state.pc++; clear_C1(); -#if 0 //TODO +#if 0 // TODO if ((IS_TAG_EMPTY(0) || IS_TAG_EMPTY(-1))) { if (IS_TAG_EMPTY(0)) FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); @@ -156,15 +159,15 @@ sf_FXTRACT(uint32_t fetchdat) #endif status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = floatx80_extract(&a, &status); + a = FPU_read_regi(0); + b = floatx80_extract(&a, &status); if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(b, 0); // exponent FPU_push(); FPU_save_regi(a, 0); // fraction } -#if 0 //TODO. +#if 0 // TODO. next_ins: #endif CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxtract) : (x87_timings.fxtract * cpu_multi)); @@ -175,10 +178,13 @@ next_ins: static int sf_FPREM1(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; - uint64_t quotient = 0; - int flags, cc; + uint64_t quotient = 0; + int flags; + int cc; FP_ENTER(); cpu_state.pc++; @@ -189,10 +195,10 @@ sf_FPREM1(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(1); - flags = floatx80_ieee754_remainder(a, b, &result, "ient, &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + a = FPU_read_regi(0); + b = FPU_read_regi(1); + flags = floatx80_ieee754_remainder(a, b, &result, "ient, &status); + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { if (flags >= 0) { cc = 0; if (flags) @@ -219,10 +225,13 @@ next_ins: static int sf_FPREM(uint32_t fetchdat) { - floatx80 a, b, result; + floatx80 a; + floatx80 b; + floatx80 result; struct float_status_t status; - uint64_t quotient = 0; - int flags, cc; + uint64_t quotient = 0; + int flags; + int cc; FP_ENTER(); cpu_state.pc++; @@ -233,11 +242,11 @@ sf_FPREM(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word()); - a = FPU_read_regi(0); - b = FPU_read_regi(1); + a = FPU_read_regi(0); + b = FPU_read_regi(1); // handle unsupported extended double-precision floating encodings flags = floatx80_remainder(a, b, &result, "ient, &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { if (flags >= 0) { cc = 0; if (flags) @@ -264,7 +273,7 @@ next_ins: static int sf_FYL2XP1(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -276,7 +285,7 @@ sf_FYL2XP1(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); result = fyl2xp1(FPU_read_regi(0), FPU_read_regi(1), &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(result, 1); FPU_pop(); } @@ -291,9 +300,11 @@ next_ins: static int sf_FSINCOS(uint32_t fetchdat) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); + const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); struct float_status_t status; - floatx80 y, sin_y, cos_y; + floatx80 y; + floatx80 sin_y; + floatx80 cos_y; FP_ENTER(); cpu_state.pc++; @@ -314,12 +325,12 @@ sf_FSINCOS(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); - y = FPU_read_regi(0); + y = FPU_read_regi(0); if (fsincos(y, &sin_y, &cos_y, &status) == -1) { fpu_state.swd |= C2; goto next_ins; } - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) { + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) { FPU_save_regi(sin_y, 0); FPU_push(); FPU_save_regi(cos_y, 0); @@ -335,7 +346,7 @@ next_ins: static int sf_FSCALE(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -347,7 +358,7 @@ sf_FSCALE(uint32_t fetchdat) } status = i387cw_to_softfloat_status_word(i387_get_control_word()); result = floatx80_scale(FPU_read_regi(0), FPU_read_regi(1), &status); - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_save_regi(result, 0); next_ins: @@ -360,7 +371,7 @@ next_ins: static int sf_FSIN(uint32_t fetchdat) { - floatx80 y; + floatx80 y; struct float_status_t status; FP_ENTER(); @@ -372,12 +383,12 @@ sf_FSIN(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); - y = FPU_read_regi(0); + y = FPU_read_regi(0); if (fsin(&y, &status) == -1) { fpu_state.swd |= C2; goto next_ins; } - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_save_regi(y, 0); next_ins: @@ -389,7 +400,7 @@ next_ins: static int sf_FCOS(uint32_t fetchdat) { - floatx80 y; + floatx80 y; struct float_status_t status; FP_ENTER(); @@ -401,12 +412,12 @@ sf_FCOS(uint32_t fetchdat) goto next_ins; } status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS); - y = FPU_read_regi(0); + y = FPU_read_regi(0); if (fcos(&y, &status) == -1) { fpu_state.swd |= C2; goto next_ins; } - if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) + if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) FPU_save_regi(y, 0); next_ins: diff --git a/src/device.c b/src/device.c index e9d0a094a..6154de708 100644 --- a/src/device.c +++ b/src/device.c @@ -439,13 +439,13 @@ device_has_config(const device_t *dev) } int -device_poll(const device_t *dev, int x, int y, int z, int b) +device_poll(const device_t *dev) { for (uint16_t c = 0; c < DEVICE_MAX; c++) { if (devices[c] != NULL) { if (devices[c] == dev) { if (devices[c]->poll) - return (devices[c]->poll(x, y, z, b, 0, 0, device_priv[c])); + return (devices[c]->poll(device_priv[c])); } } } @@ -453,22 +453,6 @@ device_poll(const device_t *dev, int x, int y, int z, int b) return 0; } -void -device_register_pci_slot(const device_t *dev, int device, int type, int inta, int intb, int intc, int intd) -{ - for (uint16_t c = 0; c < DEVICE_MAX; c++) { - if (devices[c] != NULL) { - if (devices[c] == dev) { - if (devices[c]->register_pci_slot) - devices[c]->register_pci_slot(device, type, inta, intb, intc, intd, device_priv[c]); - return; - } - } - } - - return; -} - void device_get_name(const device_t *dev, int bus, char *name) { diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index ef3a392ee..7852417d9 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -24,6 +24,10 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c h mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c mouse_wacom_tablet.c serial_passthrough.c) +if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_link_libraries(86Box atomic) +endif() + if(ISAMEM_RAMPAGE) target_compile_definitions(dev PRIVATE USE_ISAMEM_RAMPAGE) endif() diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 39398f996..f40c032c7 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -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; } @@ -464,9 +468,7 @@ kbc_at_poll_at(atkbc_t *dev) case STATE_KBC_AMI_OUT: if (dev->status & STAT_OFULL) break; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case STATE_MAIN_IBF: default: at_main_ibf: @@ -589,9 +591,7 @@ kbc_at_poll_ps2(atkbc_t *dev) case STATE_KBC_AMI_OUT: if (dev->status & STAT_OFULL) break; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case STATE_MAIN_IBF: default: ps2_main_ibf: @@ -720,10 +720,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 +879,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); @@ -918,7 +921,7 @@ write64_generic(void *priv, uint8_t val) Bit 6: Mostly, display: 0 = CGA, 1 = MDA, inverted on Xi8088 and Acer KBC's; Intel AMI MegaKey KB-5: Used for green features, SMM handler expects it to be set; IBM PS/1 Model 2011: 0 = current FDD is 3.5", 1 = current FDD is 5.25"; - Comapq: 0 = Compaq dual-scan display, 1 = non-Compaq display. + Compaq: 0 = Compaq dual-scan display, 1 = non-Compaq display. Bit 5: Mostly, manufacturing jumper: 0 = installed (infinite loop at POST), 1 = not installed; NCR: power-on default speed: 0 = high, 1 = low; Compaq: System board DIP switch 5: 0 = ON, 1 = OFF. @@ -1550,7 +1553,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 +1573,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 +1857,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 +1906,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 +1934,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); diff --git a/src/device/kbc_at_dev.c b/src/device/kbc_at_dev.c index 894b5f08a..1c1a0e91a 100644 --- a/src/device/kbc_at_dev.c +++ b/src/device/kbc_at_dev.c @@ -136,9 +136,7 @@ kbc_at_dev_poll(void *priv) dev->port->wantcmd = 0; break; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case DEV_STATE_MAIN_WANT_IN: /* Output command response and then return to main loop #2. */ if ((dev->port->out_new == -1) && (dev->cmd_queue_start != dev->cmd_queue_end)) { diff --git a/src/device/keyboard.c b/src/device/keyboard.c index e788ff23f..15eb06035 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -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; diff --git a/src/device/mouse.c b/src/device/mouse.c index 2acfd905e..24e1ba00f 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -19,7 +19,9 @@ * Copyright 2016-2018 Miran Grca. * Copyright 2017-2018 Fred N. van Kempen. */ +#include #include +#include #include #include #include @@ -30,6 +32,8 @@ #include <86box/timer.h> #include <86box/gdbstub.h> #include <86box/mouse.h> +#include <86box/video.h> +#include <86box/plat.h> #include <86box/plat_unused.h> typedef struct mouse_t { @@ -37,17 +41,16 @@ typedef struct mouse_t { } mouse_t; int mouse_type = 0; -int mouse_x; -int mouse_y; -int mouse_z; -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; + pc_timer_t mouse_timer; /* mouse event timer */ static const device_t mouse_none_device = { @@ -84,7 +87,7 @@ static mouse_t mouse_devices[] = { { &mouse_internal_device }, { &mouse_logibus_device }, { &mouse_msinport_device }, -#if 0 +#ifdef USE_GENIBUS { &mouse_genibus_device }, #endif { &mouse_mssystems_device }, @@ -97,10 +100,19 @@ static mouse_t mouse_devices[] = { // clang-format on }; +static _Atomic double mouse_x; +static _Atomic double mouse_y; +static atomic_int mouse_z; +static atomic_int mouse_buttons; + +static int mouse_delta_b; +static int mouse_old_b; + static const device_t *mouse_curr; static void *mouse_priv; static int mouse_nbut; -static int (*mouse_dev_poll)(int x, int y, int z, int b, void *priv); +static int mouse_raw; +static int (*mouse_dev_poll)(void *priv); static void (*mouse_poll_ex)(void) = NULL; static double sample_rate = 200.0; @@ -123,84 +135,369 @@ mouse_log(const char *fmt, ...) # define mouse_log(fmt, ...) #endif -/* Initialize the mouse module. */ void -mouse_init(void) +mouse_clear_x(void) { - /* Initialize local data. */ - mouse_x = mouse_y = mouse_z = 0; - mouse_buttons = 0x00; - - mouse_type = MOUSE_TYPE_NONE; - mouse_curr = NULL; - mouse_priv = NULL; - mouse_nbut = 0; - mouse_dev_poll = NULL; + mouse_x = 0.0; } void -mouse_close(void) +mouse_clear_y(void) { - if (mouse_curr == NULL) - return; + mouse_y = 0.0; +} - mouse_curr = NULL; - mouse_priv = NULL; - mouse_nbut = 0; - mouse_dev_poll = NULL; +void +mouse_clear_coords(void) +{ + mouse_clear_x(); + mouse_clear_y(); - timer_stop(&mouse_timer); + mouse_z = 0; +} + +void +mouse_clear_buttons(void) +{ + mouse_buttons = 0x00; + mouse_old_b = 0x00; + + mouse_delta_b = 0x00; +} + +static double +mouse_scale_coord_x(double x, int mul) +{ + double ratio = 1.0; + + if (!mouse_raw) + ratio = ((double) monitors[0].mon_unscaled_size_x) / monitors[0].mon_res_x; + + if (mul) + x *= ratio; + else + x /= ratio; + + return x; +} + +static double +mouse_scale_coord_y(double y, int mul) +{ + double ratio = 1.0; + + if (!mouse_raw) + ratio = ((double) monitors[0].mon_efscrnsz_y) / monitors[0].mon_res_y; + + if (mul) + y *= ratio; + else + y /= ratio; + + return y; +} + +void +mouse_subtract_x(int *delta_x, int *o_x, int min, int max, int abs) +{ + double real_x = atomic_load(&mouse_x); + double smax_x; + double rsmin_x; + double smin_x; + int ds_x; + int scaled_x; + + rsmin_x = mouse_scale_coord_x(min, 0); + if (abs) { + smax_x = mouse_scale_coord_x(max, 0) + ABS(rsmin_x); + max += ABSD(min); + real_x += rsmin_x; + smin_x = 0; + } else { + smax_x = mouse_scale_coord_x(max, 0); + smin_x = rsmin_x; + } + + smax_x = floor(smax_x); + smin_x = ceil(smin_x); + + /* Default the X overflow to 1. */ + if (o_x != NULL) + *o_x = 1; + + ds_x = mouse_scale_coord_x(real_x, 1); + + if (ds_x >= 0.0) + scaled_x = (int) floor(mouse_scale_coord_x(real_x, 1)); + else + scaled_x = (int) ceil(mouse_scale_coord_x(real_x, 1)); + + if (real_x > smax_x) { + if (abs) { + *delta_x = scaled_x; + real_x -= mouse_scale_coord_x((double) scaled_x, 0); + } else { + *delta_x = max; + real_x -= smax_x; + } + } else if (real_x < smin_x) { + if (abs) { + *delta_x = scaled_x; + real_x -= mouse_scale_coord_x((double) scaled_x, 0); + } else { + *delta_x = min; + real_x += ABSD(smin_x); + } + } else { + *delta_x = scaled_x; + real_x -= mouse_scale_coord_x((double) scaled_x, 0); + if (o_x != NULL) + *o_x = 0; + } + + if (abs) + real_x -= rsmin_x; + + atomic_store(&mouse_x, real_x); +} + +/* It appears all host platforms give us y in the Microsoft format + (positive to the south), so for all non-Microsoft report formsts, + we have to invert that. */ +void +mouse_subtract_y(int *delta_y, int *o_y, int min, int max, int invert, int abs) +{ + double real_y = atomic_load(&mouse_y); + double smax_y; + double rsmin_y; + double smin_y; + int ds_y; + int scaled_y; + + if (invert) + real_y = -real_y; + + rsmin_y = mouse_scale_coord_y(min, 0); + if (abs) { + smax_y = mouse_scale_coord_y(max, 0) + ABS(rsmin_y); + max += ABSD(min); + real_y += rsmin_y; + smin_y = 0; + } else { + smax_y = mouse_scale_coord_y(max, 0); + smin_y = rsmin_y; + } + + smax_y = floor(smax_y); + smin_y = ceil(smin_y); + + /* Default Y overflow to 1. */ + if (o_y != NULL) + *o_y = 1; + + ds_y = mouse_scale_coord_x(real_y, 1); + + if (ds_y >= 0.0) + scaled_y = (int) floor(mouse_scale_coord_x(real_y, 1)); + else + scaled_y = (int) ceil(mouse_scale_coord_x(real_y, 1)); + + if (real_y > smax_y) { + if (abs) { + *delta_y = scaled_y; + real_y -= mouse_scale_coord_y((double) scaled_y, 0); + } else { + *delta_y = max; + real_y -= smax_y; + } + } else if (real_y < smin_y) { + if (abs) { + *delta_y = scaled_y; + real_y -= mouse_scale_coord_y((double) scaled_y, 0); + } else { + *delta_y = min; + real_y += ABSD(smin_y); + } + } else { + *delta_y = scaled_y; + real_y -= mouse_scale_coord_y((double) scaled_y, 0); + if (o_y != NULL) + *o_y = 0; + } + + if (abs) + real_y -= rsmin_y; + + if (invert) + real_y = -real_y; + + atomic_store(&mouse_y, real_y); +} + +/* It appears all host platforms give us y in the Microsoft format + (positive to the south), so for all non-Microsoft report formsts, + we have to invenrt that. */ +void +mouse_subtract_coords(int *delta_x, int *delta_y, int *o_x, int *o_y, + int min, int max, int invert, int abs) +{ + mouse_subtract_x(delta_x, o_x, min, max, abs); + mouse_subtract_y(delta_y, o_y, min, max, invert, abs); +} + +int +mouse_moved(void) +{ + int moved_x = !!((int) floor(ABSD(mouse_scale_coord_x(atomic_load(&mouse_x), 1)))); + int moved_y = !!((int) floor(ABSD(mouse_scale_coord_y(atomic_load(&mouse_y), 1)))); + + /* Convert them to integer so we treat < 1.0 and > -1.0 as 0. */ + int ret = (moved_x || moved_y); + + return ret; +} + +int +mouse_state_changed(void) +{ + int b; + int b_mask = (1 << mouse_nbut) - 1; + int wheel = (mouse_nbut >= 4); + int ret; + + b = atomic_load(&mouse_buttons); + mouse_delta_b = (b ^ mouse_old_b); + mouse_old_b = b; + + ret = mouse_moved() || ((atomic_load(&mouse_z) != 0) && wheel) || (mouse_delta_b & b_mask); + + return ret; +} + +int +mouse_mbut_changed(void) +{ + return !!(mouse_delta_b & 0x04); } 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 +} + +static void +atomic_double_add(_Atomic double *var, double val) +{ + double temp = atomic_load(var); + + temp += val; + + atomic_store(var, temp); +} + +void +mouse_scale_fx(double x) +{ + atomic_double_add(&mouse_x, ((double) x) * mouse_sensitivity); +} + +void +mouse_scale_fy(double y) +{ + atomic_double_add(&mouse_y, ((double) y) * mouse_sensitivity); +} + +void +mouse_scale_x(int x) +{ + atomic_double_add(&mouse_x, ((double) x) * mouse_sensitivity); +} + +void +mouse_scale_y(int y) +{ + atomic_double_add(&mouse_y, ((double) y) * mouse_sensitivity); +} + +void +mouse_scalef(double x, double y) +{ + mouse_scale_fx(x); + mouse_scale_fy(y); +} + +void +mouse_scale(int x, int y) +{ + mouse_scale_x(x); + mouse_scale_y(y); +} + +void +mouse_set_z(int z) +{ + atomic_fetch_add(&mouse_z, z); +} + +void +mouse_clear_z(void) +{ + atomic_store(&mouse_z, 0); +} + +void +mouse_subtract_z(int *delta_z, int min, int max, int invert) +{ + int z = atomic_load(&mouse_z); + int real_z = invert ? -z : z; + + if (mouse_z > max) { + *delta_z = max; + real_z -= max; + } else if (mouse_z < min) { + *delta_z = min; + real_z += ABS(min); + } else { + *delta_z = mouse_z; + real_z = 0; + } + + atomic_store(&mouse_z, invert ? -real_z : real_z); +} + +void +mouse_set_buttons_ex(int b) +{ + atomic_store(&mouse_buttons, b); +} + +int +mouse_get_buttons_ex(void) +{ + return atomic_load(&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); -} - -void -mouse_reset(void) -{ - if (mouse_curr != NULL) - return; /* Mouse already initialized. */ - - mouse_log("MOUSE: reset(type=%d, '%s')\n", - mouse_type, mouse_devices[mouse_type].device->name); - - /* Clear local data. */ - mouse_x = mouse_y = mouse_z = 0; - mouse_buttons = 0x00; - mouse_mode = 0; - - /* If no mouse configured, we're done. */ - if (mouse_type == 0) - return; - - timer_add(&mouse_timer, mouse_timer_poll, NULL, 0); - - /* Poll at 100 Hz, the default of a PS/2 mouse. */ - sample_rate = 100.0; - timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); - - mouse_curr = mouse_devices[mouse_type].device; - - if (mouse_curr != NULL) - mouse_priv = device_add(mouse_curr); + if (mouse_timed) + timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); } /* Callback from the hardware driver. */ @@ -211,9 +508,10 @@ mouse_set_buttons(int buttons) } void -mouse_set_poll_ex(void (*poll_ex)(void)) +mouse_get_abs_coords(double *x_abs, double *y_abs) { - mouse_poll_ex = poll_ex; + *x_abs = mouse_x_abs; + *y_abs = mouse_y_abs; } void @@ -222,24 +520,24 @@ 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)) { + else if ((mouse_mode == 0) && ((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); + mouse_curr->poll(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; + mouse_dev_poll(mouse_priv); } } void -mouse_set_poll(int (*func)(int, int, int, int, void *), void *arg) +mouse_set_poll_ex(void (*poll_ex)(void)) +{ + mouse_poll_ex = poll_ex; +} + +void +mouse_set_poll(int (*func)(void *), void *arg) { if (mouse_type != MOUSE_TYPE_INTERNAL) return; @@ -301,3 +599,69 @@ mouse_get_ndev(void) { return ((sizeof(mouse_devices) / sizeof(mouse_t)) - 1); } + +void +mouse_set_raw(int raw) +{ + mouse_raw = raw; +} + +void +mouse_reset(void) +{ + if (mouse_curr != NULL) + return; /* Mouse already initialized. */ + + mouse_log("MOUSE: reset(type=%d, '%s')\n", + mouse_type, mouse_devices[mouse_type].device->name); + + /* Clear local data. */ + mouse_clear_coords(); + mouse_clear_buttons(); + mouse_mode = 0; + mouse_timed = 1; + + /* If no mouse configured, we're done. */ + if (mouse_type == 0) + return; + + timer_add(&mouse_timer, mouse_timer_poll, NULL, 0); + + /* Poll at 100 Hz, the default of a PS/2 mouse. */ + sample_rate = 100.0; + timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); + + mouse_curr = mouse_devices[mouse_type].device; + + if (mouse_curr != NULL) + mouse_priv = device_add(mouse_curr); +} + +void +mouse_close(void) +{ + if (mouse_curr == NULL) + return; + + mouse_curr = NULL; + mouse_priv = NULL; + mouse_nbut = 0; + mouse_dev_poll = NULL; + + timer_stop(&mouse_timer); +} + +/* Initialize the mouse module. */ +void +mouse_init(void) +{ + /* Initialize local data. */ + mouse_clear_coords(); + mouse_clear_buttons(); + + mouse_type = MOUSE_TYPE_NONE; + mouse_curr = NULL; + mouse_priv = NULL; + mouse_nbut = 0; + mouse_dev_poll = NULL; +} diff --git a/src/device/mouse_bus.c b/src/device/mouse_bus.c index 0537c0cb4..554704c9d 100644 --- a/src/device/mouse_bus.c +++ b/src/device/mouse_bus.c @@ -68,6 +68,7 @@ */ #include #include +#include #include #include #include @@ -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; @@ -475,16 +475,22 @@ ms_write(uint16_t port, uint8_t val, void *priv) /* The emulator calls us with an update on the host mouse device. */ static int -bm_poll(int x, int y, UNUSED(int z), int b, UNUSED(double abs_x), UNUSED(double abs_y), void *priv) +bm_poll(void *priv) { mouse_t *dev = (mouse_t *) priv; - int xor ; + int delta_x; + int delta_y; + int xor; + int b = mouse_get_buttons_ex(); + + 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)) { - dev->mouse_buttons_last = b; + if (!mouse_state_changed()) { + dev->mouse_buttons_last = 0x00; return 1; /* State has not changed, do nothing. */ } @@ -498,36 +504,23 @@ 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_moved()) dev->mouse_buttons |= 0x40; /* Set bits 3-5 according to button state changes. */ - xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; + xor = ((dev->current_b ^ mouse_get_buttons_ex()) & 0x07) << 3; dev->mouse_buttons |= xor; } 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; + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 0, 0); + + dev->current_x = (int8_t) delta_x; + dev->current_y = (int8_t) delta_y; dev->current_b = dev->mouse_buttons; } @@ -538,6 +531,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,32 +542,12 @@ 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) { - delta_x = 127; - dev->mouse_delayed_dx -= 127; - } else if (dev->mouse_delayed_dx < -128) { - delta_x = -128; - dev->mouse_delayed_dx += 128; - } else { - delta_x = dev->mouse_delayed_dx; - dev->mouse_delayed_dx = 0; - } - - if (dev->mouse_delayed_dy > 127) { - delta_y = 127; - dev->mouse_delayed_dy -= 127; - } else if (dev->mouse_delayed_dy < -128) { - delta_y = -128; - dev->mouse_delayed_dy += 128; - } else { - delta_y = dev->mouse_delayed_dy; - dev->mouse_delayed_dy = 0; - } + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 0, 0); dev->current_x = (int8_t) delta_x; dev->current_y = (int8_t) delta_y; @@ -659,8 +633,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 +679,8 @@ bm_init(const device_t *info) else bm_log("Standard MS/Logitech BusMouse initialized\n"); + mouse_set_sample_rate(0.0); + return dev; } diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 2d150b5ed..251459199 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -13,6 +13,7 @@ * Authors: Fred N. van Kempen, */ #include +#include #include #include #include @@ -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 { @@ -73,56 +75,41 @@ static void ps2_report_coordinates(atkbc_dev_t *dev, int main) { uint8_t buff[3] = { 0x08, 0x00, 0x00 }; - int temp_z; + int delta_x; + int delta_y; + int overflow_x; + int overflow_y; + int b = mouse_get_buttons_ex(); + int delta_z; - if (dev->x > 255) { - dev->x = 255; - buff[0] |= 0x40; - } - 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; + mouse_subtract_coords(&delta_x, &delta_y, &overflow_x, &overflow_y, + -256, 255, 1, 0); + mouse_subtract_z(&delta_z, -8, 7, 0); - 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); + buff[0] |= (overflow_y << 7) | (overflow_x << 6) | + ((delta_y & 0x0100) >> 3) | ((delta_x & 0x0100) >> 4) | + (b & ((dev->flags & FLAG_INTELLI) ? 0x07 : 0x03)); + buff[1] = (delta_x & 0x00ff); + buff[2] = (delta_y & 0x00ff); 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; + delta_z &= 0x0f; + if (dev->flags & FLAG_5BTN) { - if (mouse_buttons & 8) - temp_z |= 0x10; - if (mouse_buttons & 16) - temp_z |= 0x20; + if (b & 8) + delta_z |= 0x10; + if (b & 16) + delta_z |= 0x20; } else { /* The wheel coordinate is sign-extended. */ - if (temp_z & 0x08) - temp_z |= 0xf0; + if (delta_z & 0x08) + delta_z |= 0xf0; } - kbc_at_dev_queue_add(dev, temp_z, main); + kbc_at_dev_queue_add(dev, delta_z, main); } - - dev->x = dev->y = dev->z = 0; } static void @@ -132,7 +119,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; } @@ -151,6 +138,7 @@ static void ps2_write(void *priv) { atkbc_dev_t *dev = (atkbc_dev_t *) priv; + int b; uint8_t temp; uint8_t val; static uint8_t last_data[6] = { 0x00 }; @@ -209,15 +197,16 @@ ps2_write(void *priv) case 0xe9: /* status request */ mouse_ps2_log("%s: Status request\n", dev->name); + b = mouse_get_buttons_ex(); kbc_at_dev_queue_add(dev, 0xfa, 0); temp = (dev->flags & 0x20); if (mouse_scan) temp |= FLAG_ENABLED; - if (mouse_buttons & 1) + if (b & 1) temp |= 4; - if (mouse_buttons & 2) + if (b & 2) temp |= 1; - if ((mouse_buttons & 4) && (dev->flags & FLAG_INTELLI)) + if ((b & 4) && (dev->flags & FLAG_INTELLI)) temp |= 2; kbc_at_dev_queue_add(dev, temp, 0); kbc_at_dev_queue_add(dev, dev->resolution, 0); @@ -311,30 +300,18 @@ ps2_write(void *priv) } static int -ps2_poll(int x, int y, int z, int b, UNUSED(double abs_x), UNUSED(double abs_y), void *priv) +ps2_poll(void *priv) { 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 || !mouse_state_changed()) || + ((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; - dev->b = b; - } - - if ((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size))) + if (!cond && (dev->mode == MODE_STREAM)) ps2_report_coordinates(dev, 1); - return 0; + return cond; } /* @@ -358,9 +335,6 @@ mouse_ps2_init(const device_t *info) if (i > 4) dev->flags |= FLAG_EXPLORER; - if (i >= 4) - i = 3; - mouse_ps2_log("%s: buttons=%d\n", dev->name, i); /* Tell them how many buttons we have. */ diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index c74e5216b..91fdd498a 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -14,6 +14,7 @@ * * Authors: Fred N. van Kempen, */ +#include #include #include #include @@ -26,66 +27,78 @@ #include <86box/timer.h> #include <86box/serial.h> #include <86box/mouse.h> -#include <86box/plat_fallthrough.h> -#include <86box/plat_unused.h> +#include <86box/plat.h> #define SERMOUSE_PORT 0 /* attach to Serial0 */ enum { - PHASE_IDLE, - PHASE_ID, - PHASE_DATA, - PHASE_STATUS, - PHASE_DIAGNOSTIC, - PHASE_FORMAT_AND_REVISION, - PHASE_COPYRIGHT_STRING, - PHASE_BUTTONS, - PHASE_ACK, - PHASE_BAUD_RATE + STATE_RESET, + STATE_BAUD_RATE, + STATE_DORMANT, + STATE_IDLE, + STATE_COMMAND, + STATE_DATA, + STATE_TRANSMIT, + STATE_TRANSMIT_REPORT, + STATE_SKIP_REPORT }; enum { - REPORT_PHASE_PREPARE, - REPORT_PHASE_TRANSMIT + FORMAT_BP1_ABS = 0x01, + FORMAT_BP1_REL, + FORMAT_MM_SERIES = 0x13, + FORMAT_PB_3BYTE, + FORMAT_PB_5BYTE, + FORMAT_MSYSTEMS = 0x15, /* Alias for FORMAT_PB_5BYTE. */ + FORMAT_MS, + FORMAT_HEX, + FORMAT_MS_4BYTE, + FORMAT_MS_WHEEL, + FORMATS_NUM }; typedef struct mouse_t { const char *name; /* name of this device */ - int8_t type; /* type of this device */ - int8_t port; + + uint8_t id[252]; + uint8_t buf[256]; + uint8_t flags; /* device flags */ uint8_t but; - uint8_t want_data; + uint8_t rts_toggle; uint8_t status; uint8_t format; uint8_t prompt; - uint8_t on_change; + + uint8_t continuous; + uint8_t ib; + uint8_t command; + uint8_t buf_len; + uint8_t report_mode; uint8_t id_len; - uint8_t id[255]; - uint8_t data_len; - uint8_t data[5]; - int abs_x; - int abs_y; - int rel_x; - int rel_y; - int rel_z; - int oldb; - int lastb; + uint8_t buf_pos; + uint8_t rev; - int command_pos; - int command_phase; - int report_pos; - int report_phase; - int command_enabled; - int report_enabled; - double transmit_period; - double report_period; - double auto_period; - pc_timer_t command_timer; - pc_timer_t report_timer; + int8_t type; /* type of this device */ + int8_t port; - serial_t *serial; + int state; + + int bps; + int rps; + + double transmit_period; + double report_period; + double cur_period; + double min_bit_period; + double acc_time; + double host_transmit_period; + + pc_timer_t timer; + + serial_t * serial; } mouse_t; + #define FLAG_INPORT 0x80 /* device is MS InPort */ #define FLAG_3BTN 0x20 /* enable 3-button mode */ #define FLAG_SCALED 0x10 /* enable delta scaling */ @@ -112,63 +125,666 @@ mouse_serial_log(const char *fmt, ...) #endif static void -sermouse_timer_on(mouse_t *dev, double period, int report) +sermouse_set_period(mouse_t *dev, double period) { - pc_timer_t *timer; - int *enabled; + dev->cur_period = period; /* Needed for the recalculation of the timings. */ - if (report) { - timer = &dev->report_timer; - enabled = &dev->report_enabled; - } else { - timer = &dev->command_timer; - enabled = &dev->command_enabled; - } + timer_stop(&dev->timer); - timer_on_auto(timer, period); - - *enabled = 1; + if (period > 0.0) + timer_on_auto(&dev->timer, 10000.0); } -static double -sermouse_transmit_period(mouse_t *dev, int bps, int rps) +static void +sermouse_transmit_byte(mouse_t *dev, int do_next) { - double dbps = (double) bps; - double temp = 0.0; - int word_len; + if (dev->buf_pos == 0) + dev->acc_time = 0.0; + + serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]); + + if (do_next) { + dev->buf_pos = (dev->buf_pos + 1) % dev->buf_len; + + if (dev->buf_pos != 0) + sermouse_set_period(dev, dev->transmit_period); + } +} + +static void +sermouse_transmit(mouse_t *dev, int len, int from_report, int to_report) +{ + dev->state = to_report ? STATE_TRANSMIT_REPORT : STATE_TRANSMIT; + dev->buf_pos = 0; + dev->buf_len = len; + + if (from_report) { + if (dev->acc_time > dev->report_period) + dev->acc_time -= dev->report_period; + + /* We have too little time left, pretend it's zero and handle + schedule the next report at byte period. */ + if (dev->acc_time < dev->min_bit_period) + sermouse_set_period(dev, dev->transmit_period); + /* We have enough time, schedule the next report at report period, + subtract the accumulated time from the total period, and add + one byte period (the first byte delay). */ + else + sermouse_set_period(dev, dev->report_period - dev->acc_time + dev->transmit_period); + } else + sermouse_set_period(dev, dev->transmit_period); +} + +static uint8_t +sermouse_report_msystems(mouse_t *dev) +{ + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 1, 0); + + dev->buf[0] = 0x80; + dev->buf[0] |= (b & 0x01) ? 0x00 : 0x04; /* left button */ + if (dev->but >= 3) + dev->buf[0] |= (b & 0x04) ? 0x00 : 0x02; /* middle button */ + else + dev->buf[0] |= 0x02; /* middle button */ + dev->buf[0] |= (b & 0x02) ? 0x00 : 0x01; /* right button */ + dev->buf[1] = delta_x; + dev->buf[2] = delta_y; + dev->buf[2] = delta_x; /* same as byte 1 */ + dev->buf[3] = delta_y; /* same as byte 2 */ + + return 5; +} + +static uint8_t +sermouse_report_3bp(mouse_t *dev) +{ + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 1, 0); + + dev->buf[0] = 0x80; + dev->buf[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */ + if (dev->but >= 3) + dev->buf[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ + dev->buf[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */ + dev->buf[1] = delta_x; + dev->buf[2] = delta_y; + dev->buf[2] = delta_x; /* same as byte 1 */ + dev->buf[3] = delta_y; /* same as byte 2 */ + + return 3; +} + +static uint8_t +sermouse_report_mmseries(mouse_t *dev) +{ + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -127, 127, 1, 0); + + dev->buf[0] = 0x80; + if (delta_x >= 0) + dev->buf[0] |= 0x10; + if (delta_y >= 0) + dev->buf[0] |= 0x08; + + dev->buf[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */ + if (dev->but >= 3) + dev->buf[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ + dev->buf[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */ + dev->buf[1] = ABS(delta_x) & 0x7f; + dev->buf[2] = ABS(delta_y) & 0x7f; + mouse_serial_log("MM series mouse report: %02X %02X %02X\n", dev->buf[0], dev->buf[1], dev->buf[2]); + + return 3; +} + +static uint8_t +sermouse_report_bp1(mouse_t *dev, int abs) +{ + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -2048, 2047, 1, abs); + + dev->buf[0] = 0x80; + dev->buf[0] |= (b & 0x01) ? 0x10 : 0x00; /* left button */ + if (dev->but >= 3) + dev->buf[0] |= (b & 0x04) ? 0x08 : 0x00; /* middle button */ + dev->buf[0] |= (b & 0x02) ? 0x04 : 0x00; /* right button */ + dev->buf[1] = (delta_x & 0x3f); + dev->buf[2] = ((delta_x >> 6) & 0x3f); + dev->buf[3] = (delta_y & 0x3f); + dev->buf[4] = ((delta_y >> 6) & 0x3f); + + return 5; +} + +static uint8_t +sermouse_report_ms(mouse_t *dev) +{ + uint8_t len; + int delta_x = 0; + int delta_y = 0; + int delta_z = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 0, 0); + mouse_subtract_z(&delta_z, -8, 7, 0); + + dev->buf[0] = 0x40; + dev->buf[0] |= (((delta_y >> 6) & 0x03) << 2); + dev->buf[0] |= ((delta_x >> 6) & 0x03); + if (b & 0x01) + dev->buf[0] |= 0x20; + if (b & 0x02) + dev->buf[0] |= 0x10; + dev->buf[1] = delta_x & 0x3f; + dev->buf[2] = delta_y & 0x3f; + mouse_serial_log("Microsoft serial mouse report: %02X %02X %02X\n", dev->buf[0], dev->buf[1], dev->buf[2]); + if (dev->but == 3) { + len = 3; + if (dev->format == FORMAT_MS) { + if (b & 0x04) { + dev->buf[3] = 0x20; + len++; + } + } else { + if (mouse_mbut_changed()) { + /* Microsoft 3-button mice send a fourth byte of 0x00 when the middle button + has changed. */ + dev->buf[3] = 0x00; + len++; + } + } + } else if (dev->but == 4) { + len = 4; + + dev->buf[3] = delta_z & 0x0f; + if (b & 0x04) + dev->buf[3] |= 0x10; + } else + len = 3; + + return len; +} + +static uint8_t +sermouse_report_hex(mouse_t *dev) +{ + char ret[6] = { 0, 0, 0, 0, 0, 0 }; + uint8_t but = 0x00; + int delta_x = 0; + int delta_y = 0; + int b = mouse_get_buttons_ex(); + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 1, 0); + + but |= (b & 0x01) ? 0x04 : 0x00; /* left button */ + if (dev->but >= 3) + but |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ + but |= (b & 0x02) ? 0x01 : 0x00; /* right button */ + + sprintf(ret, "%01X%02X%02X", but & 0x0f, (int8_t) delta_x, (int8_t) delta_y); + + memcpy(dev->buf, ret, 5); + + return 5; +} + +static int +sermouse_report(mouse_t *dev) +{ + int len = 0; + + memset(dev->buf, 0, 5); switch (dev->format) { - case 0: - case 1: /* Mouse Systems and Three Byte Packed formats: 8 data, no parity, 2 stop, 1 start */ - word_len = 11; + case FORMAT_PB_5BYTE: + len = sermouse_report_msystems(dev); break; - case 2: /* Hexadecimal format - 8 data, no parity, 1 stop, 1 start - number of stop bits is a guess because - it is not documented anywhere. */ - word_len = 10; + case FORMAT_PB_3BYTE: + len = sermouse_report_3bp(dev); + break; + case FORMAT_HEX: + len = sermouse_report_hex(dev); + break; + case FORMAT_BP1_REL: + len = sermouse_report_bp1(dev, 0); + break; + case FORMAT_MM_SERIES: + len = sermouse_report_mmseries(dev); + break; + case FORMAT_BP1_ABS: + len = sermouse_report_bp1(dev, 1); + break; + case FORMAT_MS: + case FORMAT_MS_4BYTE: + case FORMAT_MS_WHEEL: + len = sermouse_report_ms(dev); + break; + + default: + break; + } + + return len; +} + +static void +sermouse_transmit_report(mouse_t *dev, int from_report) +{ + if (mouse_capture && mouse_state_changed()) + sermouse_transmit(dev, sermouse_report(dev), from_report, 1); + else { + if (dev->prompt || dev->continuous) + sermouse_set_period(dev, 0.0); + else { + dev->state = STATE_SKIP_REPORT; + /* Not in prompt or continuous mode and there have been no changes, + skip the next report entirely. */ + if (from_report) { + if (dev->acc_time > dev->report_period) + dev->acc_time -= dev->report_period; + + if (dev->acc_time < dev->min_bit_period) + sermouse_set_period(dev, dev->report_period); + else + sermouse_set_period(dev, (dev->report_period * 2.0) - dev->acc_time); + } else + sermouse_set_period(dev, dev->report_period); + } + } +} + +static int +sermouse_poll(void *priv) +{ + mouse_t *dev = (mouse_t *) priv; + + if (!mouse_capture || dev->prompt || !dev->continuous || (dev->state != STATE_IDLE)) + return 1; + + sermouse_transmit_report(dev, 0); + return (dev->cur_period == 0.0) ? 1 : 0; +} + +static void +ltsermouse_set_prompt_mode(mouse_t *dev, int prompt) +{ + dev->prompt = prompt; + + if (prompt || dev->continuous) + sermouse_set_period(dev, 0.0); + else + sermouse_set_period(dev, dev->transmit_period); +} + +static void +ltsermouse_set_report_period(mouse_t *dev, int rps) +{ + /* Limit the reports rate according to the baud rate. */ + if (rps == 0) { + sermouse_set_period(dev, 0.0); + + dev->report_period = 0.0; + dev->continuous = 1; + } else { + /* if (rps > dev->max_rps) + rps = dev->max_rps; */ + + dev->continuous = 0; + dev->report_period = 1000000.0 / ((double) rps); + /* Actual spacing between reports. */ + } +} + +static void +ltsermouse_update_report_period(mouse_t *dev) +{ + ltsermouse_set_report_period(dev, dev->rps); + + ltsermouse_set_prompt_mode(dev, 0); + mouse_serial_log("ltsermouse_update_report_period(): %i, %i\n", dev->continuous, dev->prompt); + if (dev->continuous) + dev->state = STATE_IDLE; + else { + sermouse_transmit_report(dev, 0); + dev->state = STATE_TRANSMIT_REPORT; + } +} + +static void +ltsermouse_switch_baud_rate(mouse_t *dev, int next_state) +{ + double word_lens[FORMATS_NUM] = { + [FORMAT_BP1_ABS] = 7.0 + 1.0, /* 7 data bits + even parity */ + [FORMAT_BP1_REL] = 7.0 + 1.0, /* 7 data bits + even parity */ + [FORMAT_MM_SERIES] = 8.0 + 1.0, /* 8 data bits + odd parity */ + [FORMAT_PB_3BYTE] = 8.0, /* 8 data bits + no parity */ + [FORMAT_PB_5BYTE] = 8.0, /* 8 data bits + no parity */ + [FORMAT_MS] = 7.0, /* 7 datas bits + no parity */ + [FORMAT_HEX] = 8.0, /* 8 data bits + no parity */ + [FORMAT_MS_4BYTE] = 7.0, /* 7 datas bits + no parity */ + [FORMAT_MS_WHEEL] = 7.0 }; /* 7 datas bits + no parity */ + double word_len = word_lens[dev->format]; + + word_len += 1.0 + 2.0; /* 1 start bit + 2 stop bits */ + + // dev->max_rps = (int) floor(((double) dev->bps) / (word_len * num_words)); + + if (next_state == STATE_BAUD_RATE) + dev->transmit_period = dev->host_transmit_period; + else + dev->transmit_period = (1000000.0) / ((double) dev->bps); + + dev->min_bit_period = dev->transmit_period; + + dev->transmit_period *= word_len; + /* The transmit period for the entire report, we're going to need this in ltsermouse_set_report_period(). */ + // dev->report_transmit_period = dev->transmit_period * num_words; + + ltsermouse_set_report_period(dev, dev->rps); + + if (!dev->continuous && (next_state != STATE_BAUD_RATE)) { + if (dev->prompt) + ltsermouse_set_prompt_mode(dev, 0); + + sermouse_transmit_report(dev, 0); + } + + dev->state = next_state; +} + +static int +sermouse_next_state(mouse_t *dev) +{ + int ret = STATE_IDLE; + + if (dev->prompt || (dev->rps == 0)) + ret = STATE_IDLE; + else + ret = STATE_TRANSMIT; + + return ret; +} + +static void +ltsermouse_process_command(mouse_t *dev) +{ + int cmd_to_rps[9] = { 10, 20, 35, 70, 150, 0, -1, 100, 50 }; + int b; + uint8_t format_codes[FORMATS_NUM] = { + [FORMAT_BP1_ABS] = 0x0c, + [FORMAT_BP1_REL] = 0x06, + [FORMAT_MM_SERIES] = 0x0a, + [FORMAT_PB_3BYTE] = 0x00, + [FORMAT_PB_5BYTE] = 0x02, + [FORMAT_MS] = 0x0e, + [FORMAT_HEX] = 0x04, + [FORMAT_MS_4BYTE] = 0x08, /* Guess */ + [FORMAT_MS_WHEEL] = 0x08 }; /* Guess */ + char *copr = "\r\n(C) 2023 86Box, Revision 3.0"; + + mouse_serial_log("ltsermouse_process_command(): %02X\n", dev->ib); + dev->command = dev->ib; + + switch (dev->command) { + case 0x20: + /* Auto Baud Selection */ + dev->bps = (int) floor(1000000.0 / dev->host_transmit_period); + dev->transmit_period = dev->host_transmit_period; + + dev->buf[0] = 0x06; + sermouse_transmit(dev, 1, 0, 0); + + ltsermouse_switch_baud_rate(dev, STATE_BAUD_RATE); + break; + + case 0x4a: /* Report Rate Selection commands */ + case 0x4b: + case 0x4c: + case 0x52: + case 0x4d: + case 0x51: + case 0x4e: + case 0x4f: + dev->report_mode = dev->command; + dev->rps = cmd_to_rps[dev->command - 0x4a]; + ltsermouse_update_report_period(dev); + break; + + case 0x44: + /* Select Prompt Mode */ + dev->report_mode = dev->command; + ltsermouse_set_prompt_mode(dev, 1); + dev->state = STATE_IDLE; + break; + case 0x50: + /* Promopt to send a report (also enters Prompt Mode). */ + if (!dev->prompt) { + dev->report_mode = 0x44; + ltsermouse_set_prompt_mode(dev, 1); + } + sermouse_transmit_report(dev, 0); + dev->state = STATE_TRANSMIT_REPORT; + break; + + case 0x41: + /* Absolute Bit Pad One Packed Binary Format */ + mouse_clear_coords(); + fallthrough; + case 0x42: /* Relative Bit Pad One Packed Binary Format */ + case 0x53: /* MM Series Data Format */ + case 0x54: /* Three Byte Packed Binary Format */ + case 0x55: /* Five Byte Packed Binary Format (Mouse Systems-compatible) */ + case 0x56: /* Microsoft Compatible Format */ + case 0x57: /* Hexadecimal Format */ + case 0x58: /* Microsoft Compatible Format (3+1 byte 3-button, from the FreeBSD source code) */ + if ((dev->rev >= 0x02) && ((dev->command != 0x58) || (dev->rev > 0x04))) { + dev->format = dev->command & 0x1f; + ltsermouse_switch_baud_rate(dev, sermouse_next_state(dev)); + } + break; + + case 0x2a: + if (dev->rev >= 0x03) { + /* Programmable Baud Rate Selection */ + dev->state = STATE_DATA; + } + break; + + case 0x73: + /* Status */ + dev->buf[0] = dev->prompt ? 0x4f : 0x0f; + sermouse_transmit(dev, 1, 0, 0); + break; + case 0x05: + /* Diagnostic */ + b = mouse_get_buttons_ex(); + dev->buf[0] = ((b & 0x01) << 2) | ((b & 0x06) >> 1); + dev->buf[1] = dev->buf[2] = 0x00; + sermouse_transmit(dev, 3, 0, 0); + break; + + case 0x66: + if (dev->rev >= 0x20) { + /* Format and Revision Number */ + dev->buf[0] = format_codes[dev->format]; + dev->buf[0] |= 0x10; /* Revision 3.0, 0x00 would be Revision 2.0 */ + sermouse_transmit(dev, 1, 0, 0); + } + break; + + case 0x74: + /* Format and Mode in ASCII */ + if (dev->rev >= 0x03) { + dev->buf[0] = dev->format | 0x40; + dev->buf[1] = dev->report_mode; + sermouse_transmit(dev, 2, 0, 0); + } + break; + + case 0x63: + /* Copyright and Revision in ASCII */ + if (dev->rev >= 0x03) { + memcpy(&(dev->buf[0]), copr, strlen(copr) + 1); + sermouse_transmit(dev, strlen(copr) + 1, 0, 0); + } else { + memcpy(&(dev->buf[0]), copr, strlen(copr)); + sermouse_transmit(dev, strlen(copr), 0, 0); + } + dev->buf[29] = dev->rev | 0x30; + break; + + case 0x64: + /* Dormant State */ + dev->state = STATE_DORMANT; + break; + + case 0x6b: + /* Buttons - 86Box-specific command. */ + dev->state = dev->but; + break; + } +} + +static void +ltsermouse_process_data(mouse_t *dev) +{ + mouse_serial_log("ltsermouse_process_data(): %02X (command = %02X)\n", dev->ib, dev->command); + + switch(dev->command) { + case 0x2a: + switch (dev->ib) { + default: + mouse_serial_log("Serial mouse: Invalid period %02X, using 1200 bps\n", data); + fallthrough; + case 0x6e: + dev->bps = 1200; + break; + case 0x6f: + dev->bps = 2400; + break; + case 0x70: + dev->bps = 4800; + break; + case 0x71: + dev->bps = 9600; + break; + } + ltsermouse_switch_baud_rate(dev, (dev->prompt || dev->continuous) ? STATE_IDLE : STATE_TRANSMIT_REPORT); + break; + default: + dev->state = STATE_IDLE; + break; + } +} + +static void +sermouse_reset(mouse_t *dev, int callback) +{ + sermouse_set_period(dev, 0.0); + + dev->bps = 1200; + dev->rps = 0; + dev->prompt = 0; + if (dev->id[0] == 'H') + dev->format = FORMAT_MSYSTEMS; + else switch (dev->but) { + default: + case 2: + dev->format = FORMAT_MS; break; case 3: - case 6: /* Bit Pad One formats: 7 data, even parity, 2 stop, 1 start */ - word_len = 11; + dev->format = (dev->type == MOUSE_TYPE_LT3BUTTON) ? FORMAT_MS : FORMAT_MS_4BYTE; break; - case 5: /* MM Series format: 8 data, odd parity, 1 stop, 1 start */ - word_len = 11; + case 4: + dev->format = FORMAT_MS_WHEEL; + break; + } + + ltsermouse_switch_baud_rate(dev, callback ? STATE_TRANSMIT : STATE_IDLE); +} + +static void +sermouse_timer(void *priv) +{ + mouse_t *dev = (mouse_t *) priv; +#ifdef ENABLE_MOUSE_SERIAL_LOG + int old_state = dev->state; +#endif + + switch (dev->state) { + case STATE_RESET: + /* All three mice default to continuous reporting. */ + sermouse_reset(dev, 0); + break; + case STATE_DATA: + ltsermouse_process_data(dev); + break; + case STATE_COMMAND: + ltsermouse_process_command(dev); + break; + case STATE_SKIP_REPORT: + if (!dev->prompt && !dev->continuous) + sermouse_transmit_report(dev, (dev->state == STATE_TRANSMIT_REPORT)); + else + dev->state = STATE_IDLE; + break; + case STATE_TRANSMIT_REPORT: + case STATE_TRANSMIT: + case STATE_BAUD_RATE: + sermouse_transmit_byte(dev, 1); + + if (dev->buf_pos == 0) { + if (!dev->prompt && !dev->continuous) + sermouse_transmit_report(dev, (dev->state == STATE_TRANSMIT_REPORT)); + else + dev->state = STATE_IDLE; + } break; - case 7: /* Microsoft-compatible format: 7 data, no parity, 1 stop, 1 start */ default: - word_len = 9; break; } - if (rps == -1) - temp = (double) word_len; - else { - temp = (double) rps; - temp = (9600.0 - (temp * 33.0)); - temp /= rps; - } - temp = (1000000.0 / dbps) * temp; + mouse_serial_log("sermouse_timer(): %02i -> %02i\n", old_state, dev->state); +} - return temp; +static void +ltsermouse_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) +{ + mouse_t *dev = (mouse_t *) priv; + + mouse_serial_log("ltsermouse_write(): %02X\n", data); + + dev->ib = data; + + switch (dev->state) { + case STATE_RESET: + case STATE_BAUD_RATE: + break; + case STATE_TRANSMIT_REPORT: + case STATE_TRANSMIT: + case STATE_SKIP_REPORT: + sermouse_set_period(dev, 0.0); + fallthrough; + default: + dev->state = STATE_COMMAND; + fallthrough; + case STATE_DATA: + sermouse_timer(dev); + break; + } } /* Callback from serial driver: RTS was toggled. */ @@ -177,585 +793,10 @@ sermouse_callback(UNUSED(struct serial_s *serial), void *priv) { mouse_t *dev = (mouse_t *) priv; - /* Start a timer to wake us up in a little while. */ - dev->command_pos = 0; - dev->command_phase = PHASE_ID; - if (dev->id[0] != 'H') - dev->format = 7; - dev->transmit_period = sermouse_transmit_period(dev, 1200, -1); - timer_stop(&dev->command_timer); -#ifdef USE_NEW_DYNAREC - sermouse_timer_on(dev, cpu_use_dynarec ? 5000.0 : dev->transmit_period, 0); -#else - sermouse_timer_on(dev, dev->transmit_period, 0); -#endif -} + sermouse_reset(dev, 1); -static uint8_t -sermouse_data_msystems(mouse_t *dev, int x, int y, int b) -{ - dev->data[0] = 0x80; - dev->data[0] |= (b & 0x01) ? 0x00 : 0x04; /* left button */ - dev->data[0] |= (b & 0x02) ? 0x00 : 0x01; /* middle button */ - dev->data[0] |= (b & 0x04) ? 0x00 : 0x02; /* right button */ - dev->data[1] = x; - dev->data[2] = -y; - dev->data[3] = x; /* same as byte 1 */ - dev->data[4] = -y; /* same as byte 2 */ - - return 5; -} - -static uint8_t -sermouse_data_3bp(mouse_t *dev, int x, int y, int b) -{ - dev->data[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */ - dev->data[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ - dev->data[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */ - dev->data[1] = x; - dev->data[2] = -y; - - return 3; -} - -static uint8_t -sermouse_data_mmseries(mouse_t *dev, int x, int y, int b) -{ - if (x < -127) - x = -127; - if (y < -127) - y = -127; - - dev->data[0] = 0x80; - if (x >= 0) - dev->data[0] |= 0x10; - /* It appears we have inverted Y polarity. */ - if (y < 0) - dev->data[0] |= 0x08; - dev->data[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */ - dev->data[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ - dev->data[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */ - dev->data[1] = abs(x) & 0x7f; - dev->data[2] = abs(y) & 0x7f; - - return 3; -} - -static uint8_t -sermouse_data_bp1(mouse_t *dev, int x, int y, int b) -{ - dev->data[0] = 0x80; - dev->data[0] |= (b & 0x01) ? 0x10 : 0x00; /* left button */ - dev->data[0] |= (b & 0x04) ? 0x08 : 0x00; /* middle button */ - dev->data[0] |= (b & 0x02) ? 0x04 : 0x00; /* right button */ - dev->data[1] = (x & 0x3f); - dev->data[2] = (x >> 6); - dev->data[3] = (y & 0x3f); - dev->data[4] = (y >> 6); - - return 5; -} - -static uint8_t -sermouse_data_ms(mouse_t *dev, int x, int y, int z, int b) -{ - uint8_t len; - - dev->data[0] = 0x40; - dev->data[0] |= (((y >> 6) & 0x03) << 2); - dev->data[0] |= ((x >> 6) & 0x03); - if (b & 0x01) - dev->data[0] |= 0x20; - if (b & 0x02) - dev->data[0] |= 0x10; - dev->data[1] = x & 0x3F; - dev->data[2] = y & 0x3F; - if (dev->but == 3) { - len = 3; - if (dev->type == MOUSE_TYPE_LT3BUTTON) { - if (b & 0x04) { - dev->data[3] = 0x20; - len++; - } - } else { - if ((b ^ dev->oldb) & 0x04) { - /* Microsoft 3-button mice send a fourth byte of 0x00 when the middle button - has changed. */ - dev->data[3] = 0x00; - len++; - } - } - } else if (dev->but == 4) { - len = 4; - dev->data[3] = z & 0x0F; - if (b & 0x04) - dev->data[3] |= 0x10; - } else - len = 3; - - return len; -} - -static uint8_t -sermouse_data_hex(mouse_t *dev, int x, int y, int b) -{ - char ret[6] = { 0, 0, 0, 0, 0, 0 }; - uint8_t but = 0x00; - - but |= (b & 0x01) ? 0x04 : 0x00; /* left button */ - but |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ - but |= (b & 0x02) ? 0x01 : 0x00; /* right button */ - - sprintf(ret, "%02X%02X%01X", (int8_t) y, (int8_t) x, but & 0x0f); - - for (uint8_t i = 0; i < 5; i++) - dev->data[i] = ret[4 - i]; - - return 5; -} - -static void -sermouse_report(int x, int y, int z, int b, mouse_t *dev) -{ - int len = 0; - - memset(dev->data, 0, 5); - - /* If the mouse is 2-button, ignore the middle button. */ - if (dev->but == 2) - b &= ~0x04; - - switch (dev->format) { - case 0: - len = sermouse_data_msystems(dev, x, y, b); - break; - case 1: - len = sermouse_data_3bp(dev, x, y, b); - break; - case 2: - len = sermouse_data_hex(dev, x, y, b); - break; - case 3: /* Relative */ - len = sermouse_data_bp1(dev, x, y, b); - break; - case 5: - len = sermouse_data_mmseries(dev, x, y, b); - break; - case 6: /* Absolute */ - len = sermouse_data_bp1(dev, dev->abs_x, dev->abs_y, b); - break; - case 7: - len = sermouse_data_ms(dev, x, y, z, b); - break; - - default: - break; - } - - dev->data_len = len; -} - -static void -sermouse_command_phase_idle(mouse_t *dev) -{ - dev->command_pos = 0; - dev->command_phase = PHASE_IDLE; - dev->command_enabled = 0; -} - -static void -sermouse_command_pos_check(mouse_t *dev, int len) -{ - if (++dev->command_pos == len) - sermouse_command_phase_idle(dev); - else - timer_on_auto(&dev->command_timer, dev->transmit_period); -} - -static uint8_t -sermouse_last_button_status(mouse_t *dev) -{ - uint8_t ret = 0x00; - - if (dev->oldb & 0x01) - ret |= 0x04; - if (dev->oldb & 0x02) - ret |= 0x02; - if (dev->oldb & 0x04) - ret |= 0x01; - - return ret; -} - -static void -sermouse_update_delta(mouse_t *dev, int *local, int *global) -{ - int min; - int max; - - if (dev->format == 3) { - min = -2048; - max = 2047; - } else { - min = -128; - max = 127; - } - - if (*global > max) { - *local = max; - *global -= max; - } else if (*global < min) { - *local = min; - *global += -min; - } else { - *local = *global; - *global = 0; - } -} - -static uint8_t -sermouse_update_data(mouse_t *dev) -{ - uint8_t ret = 0; - int delta_x; - int delta_y; - int delta_z; - - /* Update the deltas and the delays. */ - sermouse_update_delta(dev, &delta_x, &dev->rel_x); - sermouse_update_delta(dev, &delta_y, &dev->rel_y); - sermouse_update_delta(dev, &delta_z, &dev->rel_z); - - sermouse_report(delta_x, delta_y, delta_z, dev->oldb, dev); - - mouse_serial_log("delta_x = %i, delta_y = %i, delta_z = %i, dev->oldb = %02X\n", - delta_x, delta_y, delta_z, dev->oldb); - - if (delta_x || delta_y || delta_z || (dev->oldb != dev->lastb) || !dev->on_change) - ret = 1; - - dev->lastb = dev->oldb; - - mouse_serial_log("sermouse_update_data(): ret = %i\n", ret); - - return ret; -} - -static double -sermouse_report_period(mouse_t *dev) -{ - if (dev->report_period == 0) - return dev->transmit_period; - else - return dev->report_period; -} - -static void -sermouse_report_prepare(mouse_t *dev) -{ - if (sermouse_update_data(dev)) { - /* Start sending data. */ - dev->report_phase = REPORT_PHASE_TRANSMIT; - dev->report_pos = 0; - sermouse_timer_on(dev, dev->transmit_period, 1); - } else { - dev->report_phase = REPORT_PHASE_PREPARE; - sermouse_timer_on(dev, sermouse_report_period(dev), 1); - } -} - -static void -sermouse_report_timer(void *priv) -{ - mouse_t *dev = (mouse_t *) priv; - - if (dev->report_phase == REPORT_PHASE_PREPARE) - sermouse_report_prepare(dev); - else { - /* If using the Mouse Systems format, update data because - the last two bytes are the X and Y delta since bytes 1 - and 2 were transmitted. */ - if (!dev->format && (dev->report_pos == 3)) - sermouse_update_data(dev); - serial_write_fifo(dev->serial, dev->data[dev->report_pos]); - if (++dev->report_pos == dev->data_len) { - if (!dev->report_enabled) - sermouse_report_prepare(dev); - else { - sermouse_timer_on(dev, sermouse_report_period(dev), 1); - dev->report_phase = REPORT_PHASE_PREPARE; - } - } else - sermouse_timer_on(dev, dev->transmit_period, 1); - } -} - -/* Callback timer expired, now send our "mouse ID" to the serial port. */ -static void -sermouse_command_timer(void *priv) -{ - mouse_t *dev = (mouse_t *) priv; - - switch (dev->command_phase) { - case PHASE_ID: - serial_write_fifo(dev->serial, dev->id[dev->command_pos]); - sermouse_command_pos_check(dev, dev->id_len); - if ((dev->command_phase == PHASE_IDLE) && (dev->type != MOUSE_TYPE_MSYSTEMS)) { - /* This resets back to Microsoft-compatible mode. */ - dev->report_phase = REPORT_PHASE_PREPARE; - sermouse_report_timer((void *) dev); - } - break; - case PHASE_ACK: - serial_write_fifo(dev->serial, 0x06); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif - case PHASE_BAUD_RATE: - sermouse_command_phase_idle(dev); - sermouse_timer_on(dev, dev->report_period, 1); - dev->report_phase = REPORT_PHASE_PREPARE; - sermouse_report_timer((void *) dev); - break; - case PHASE_DATA: - serial_write_fifo(dev->serial, dev->data[dev->command_pos]); - sermouse_command_pos_check(dev, dev->data_len); - break; - case PHASE_STATUS: - serial_write_fifo(dev->serial, dev->status); - sermouse_command_phase_idle(dev); - break; - case PHASE_DIAGNOSTIC: - if (dev->command_pos) - serial_write_fifo(dev->serial, 0x00); - else - serial_write_fifo(dev->serial, sermouse_last_button_status(dev)); - sermouse_command_pos_check(dev, 3); - break; - case PHASE_FORMAT_AND_REVISION: - serial_write_fifo(dev->serial, 0x10 | (dev->format << 1)); - sermouse_command_phase_idle(dev); - break; - case PHASE_BUTTONS: - serial_write_fifo(dev->serial, dev->but); - sermouse_command_phase_idle(dev); - break; - default: - sermouse_command_phase_idle(dev); - break; - } -} - -static int -sermouse_poll(int x, int y, int z, int b, UNUSED(double abs_x), UNUSED(double abs_y), void *priv) -{ - mouse_t *dev = (mouse_t *) priv; - - if (!x && !y && !z && (b == dev->oldb)) { - dev->oldb = b; - return 1; - } - - dev->oldb = b; - dev->abs_x += x; - dev->abs_y += y; - if (dev->abs_x < 0) - dev->abs_x = 0; - if (dev->abs_x > 4095) - dev->abs_x = 4095; - if (dev->abs_y < 0) - dev->abs_y = 0; - if (dev->abs_y > 4095) - dev->abs_y = 4095; - - if (dev->format == 3) { - if (x > 2047) - x = 2047; - if (y > 2047) - y = 2047; - if (x < -2048) - x = -2048; - if (y < -2048) - y = -2048; - } else { - if (x > 127) - x = 127; - if (y > 127) - y = 127; - if (x < -128) - x = -128; - if (y < -128) - y = -128; - } - - dev->rel_x += x; - dev->rel_y += y; - dev->rel_z += z; - - return 0; -} - -static void -ltsermouse_prompt_mode(mouse_t *dev, int prompt) -{ - dev->prompt = prompt; - dev->status &= 0xBF; - if (prompt) - dev->status |= 0x40; -} - -static void -ltsermouse_command_phase(mouse_t *dev, int phase) -{ - dev->command_pos = 0; - dev->command_phase = phase; - timer_stop(&dev->command_timer); - sermouse_timer_on(dev, dev->transmit_period, 0); -} - -static void -ltsermouse_set_report_period(mouse_t *dev, int rps) -{ - dev->report_period = sermouse_transmit_period(dev, 9600, rps); - timer_stop(&dev->report_timer); - sermouse_timer_on(dev, dev->report_period, 1); - ltsermouse_prompt_mode(dev, 0); - dev->report_phase = REPORT_PHASE_PREPARE; -} - -static void -ltsermouse_switch_baud_rate(mouse_t *dev, int phase) -{ - dev->command_pos = 0; - dev->command_phase = phase; - timer_stop(&dev->command_timer); - sermouse_timer_on(dev, 10000.0, 0); -} - -static void -ltsermouse_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) -{ - mouse_t *dev = (mouse_t *) priv; - - /* Stop reporting when we're processing a command. */ - dev->report_phase = REPORT_PHASE_PREPARE; - - if (dev->want_data) - switch (dev->want_data) { - case 0x2A: - dev->data_len--; - dev->want_data = 0; - switch (data) { - default: - mouse_serial_log("Serial mouse: Invalid period %02X, using 1200 bps\n", data); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif - case 0x6E: - dev->transmit_period = sermouse_transmit_period(dev, 1200, -1); - break; - case 0x6F: - dev->transmit_period = sermouse_transmit_period(dev, 2400, -1); - break; - case 0x70: - dev->transmit_period = sermouse_transmit_period(dev, 4800, -1); - break; - case 0x71: - dev->transmit_period = sermouse_transmit_period(dev, 9600, -1); - break; - } - ltsermouse_switch_baud_rate(dev, PHASE_BAUD_RATE); - break; - default: - break; - } - else - switch (data) { - case 0x20: - sermouse_timer_on(dev, 0.0, 1); - dev->transmit_period = dev->auto_period; - ltsermouse_switch_baud_rate(dev, PHASE_ACK); - break; - case 0x2A: - sermouse_timer_on(dev, 0.0, 1); - dev->want_data = data; - dev->data_len = 1; - break; - case 0x44: /* Set prompt mode */ - ltsermouse_prompt_mode(dev, 1); - break; - case 0x50: - if (!dev->prompt) - ltsermouse_prompt_mode(dev, 1); - sermouse_update_data(dev); - ltsermouse_command_phase(dev, PHASE_DATA); - break; - case 0x73: /* Status */ - ltsermouse_command_phase(dev, PHASE_STATUS); - break; - case 0x4A: /* Report Rate Selection commands */ - ltsermouse_set_report_period(dev, 10); - break; - case 0x4B: - ltsermouse_set_report_period(dev, 20); - break; - case 0x4C: - ltsermouse_set_report_period(dev, 35); - break; - case 0x52: - ltsermouse_set_report_period(dev, 50); - break; - case 0x4D: - ltsermouse_set_report_period(dev, 70); - break; - case 0x51: - ltsermouse_set_report_period(dev, 100); - break; - case 0x4E: - ltsermouse_set_report_period(dev, 150); - break; - case 0x4F: - ltsermouse_prompt_mode(dev, 0); - dev->report_period = 0; - timer_stop(&dev->report_timer); - dev->report_phase = REPORT_PHASE_PREPARE; - sermouse_report_timer((void *) dev); - break; - case 0x41: - dev->format = 6; /* Aboslute Bit Pad One Format */ - dev->abs_x = dev->abs_y = 0; - break; - case 0x42: - dev->format = 3; /* Relative Bit Pad One Format */ - break; - case 0x53: - dev->format = 5; /* MM Series Format */ - break; - case 0x54: - dev->format = 1; /* Three Byte Packed Binary Format */ - break; - case 0x55: /* This is the Mouse Systems-compatible format */ - dev->format = 0; /* Five Byte Packed Binary Format */ - break; - case 0x56: - dev->format = 7; /* Microsoft Compatible Format */ - break; - case 0x57: - dev->format = 2; /* Hexadecimal Format */ - break; - case 0x05: - ltsermouse_command_phase(dev, PHASE_DIAGNOSTIC); - break; - case 0x66: - ltsermouse_command_phase(dev, PHASE_FORMAT_AND_REVISION); - break; - case 0x6B: - ltsermouse_command_phase(dev, PHASE_BUTTONS); - break; - - default: - break; - } + memcpy(dev->buf, dev->id, dev->id_len); + sermouse_transmit(dev, dev->id_len, 0, 0); } static void @@ -763,7 +804,7 @@ ltsermouse_transmit_period(UNUSED(serial_t *serial), void *priv, double transmit { mouse_t *dev = (mouse_t *) priv; - dev->auto_period = transmit_period; + dev->host_transmit_period = transmit_period; } static void @@ -771,18 +812,8 @@ sermouse_speed_changed(void *priv) { mouse_t *dev = (mouse_t *) priv; - if (dev->report_enabled) { - timer_stop(&dev->report_timer); - if (dev->report_phase == REPORT_PHASE_TRANSMIT) - sermouse_timer_on(dev, dev->transmit_period, 1); - else - sermouse_timer_on(dev, sermouse_report_period(dev), 1); - } - - if (dev->command_enabled) { - timer_stop(&dev->command_timer); - sermouse_timer_on(dev, dev->transmit_period, 0); - } + if (dev->cur_period != 0.0) + sermouse_set_period(dev, dev->cur_period); } static void @@ -802,26 +833,36 @@ static void * sermouse_init(const device_t *info) { mouse_t *dev; + 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); dev = (mouse_t *) malloc(sizeof(mouse_t)); memset(dev, 0x00, sizeof(mouse_t)); dev->name = info->name; dev->but = device_get_config_int("buttons"); + dev->rev = device_get_config_int("revision"); + + if (info->local == 0) + dev->rts_toggle = 1; + else + dev->rts_toggle = device_get_config_int("rts_toggle"); + if (dev->but > 2) dev->flags |= FLAG_3BTN; if (info->local == MOUSE_TYPE_MSYSTEMS) { - dev->on_change = 1; dev->format = 0; dev->type = info->local; dev->id_len = 1; dev->id[0] = 'H'; } else { - dev->on_change = !info->local; dev->format = 7; dev->status = 0x0f; dev->id_len = 1; dev->id[0] = 'M'; + if (info->local) + dev->rev = device_get_config_int("revision"); switch (dev->but) { default: case 2: @@ -841,33 +882,22 @@ sermouse_init(const device_t *info) } } - dev->transmit_period = sermouse_transmit_period(dev, 1200, -1); - dev->auto_period = dev->transmit_period; - - /* Default: Continuous reporting = no delay between reports. */ - dev->report_phase = REPORT_PHASE_PREPARE; - dev->report_period = 0; - - /* Default: Doing nothing - command transmit timer deactivated. */ - dev->command_phase = PHASE_IDLE; - dev->port = device_get_config_int("port"); /* Attach a serial port to the mouse. */ - if (info->local) - dev->serial = serial_attach_ex(dev->port, sermouse_callback, ltsermouse_write, ltsermouse_transmit_period, NULL, dev); - else - dev->serial = serial_attach(dev->port, sermouse_callback, NULL, dev); + rcr_callback = dev->rts_toggle ? sermouse_callback : NULL; + dev_write = (info->local == 1) ? ltsermouse_write : NULL; + transmit_period_callback = (info->local == 1) ? ltsermouse_transmit_period : NULL; + + dev->serial = serial_attach_ex(dev->port, rcr_callback, dev_write, + transmit_period_callback, NULL, dev); mouse_serial_log("%s: port=COM%d\n", dev->name, dev->port + 1); - timer_add(&dev->report_timer, sermouse_report_timer, dev, 0); - timer_add(&dev->command_timer, sermouse_command_timer, dev, 0); + timer_add(&dev->timer, sermouse_timer, dev, 0); - if (info->local == MOUSE_TYPE_MSYSTEMS) { - sermouse_timer_on(dev, dev->transmit_period, 1); - dev->report_enabled = 1; - } + /* The five second delay allows the mouse to execute internal initializations. */ + sermouse_set_period(dev, 5000000.0); /* Tell them how many buttons we have. */ mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); @@ -876,6 +906,49 @@ sermouse_init(const device_t *info) return dev; } +static const device_config_t msssermouse_config[] = { + // clang-format off + { + .name = "port", + .description = "Serial Port", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "COM1", .value = 0 }, + { .description = "COM2", .value = 1 }, + { .description = "COM3", .value = 2 }, + { .description = "COM4", .value = 3 }, + { .description = "" } + } + }, + { + .name = "buttons", + .description = "Buttons", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 2, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Two", .value = 2 }, + { .description = "Three", .value = 3 }, + { .description = "" } + } + }, + { + .name = "rts_toggle", + .description = "RTS toggle", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + static const device_config_t mssermouse_config[] = { // clang-format off { @@ -945,6 +1018,29 @@ static const device_config_t ltsermouse_config[] = { { .description = "" } } }, + { + .name = "revision", + .description = "Revision", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 3, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "LOGIMOUSE R7 1.0", .value = 1 }, + { .description = "LOGIMOUSE R7 2.0", .value = 2 }, + { .description = "LOGIMOUSE C7 3.0", .value = 3 }, + { .description = "Logitech MouseMan", .value = 4 }, + { .description = "" } + } + }, + { + .name = "rts_toggle", + .description = "Microsoft-compatible RTS toggle", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 0 + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -960,7 +1056,7 @@ const device_t mouse_mssystems_device = { { .poll = sermouse_poll }, .speed_changed = sermouse_speed_changed, .force_redraw = NULL, - .config = mssermouse_config + .config = msssermouse_config }; const device_t mouse_msserial_device = { diff --git a/src/device/mouse_wacom_tablet.c b/src/device/mouse_wacom_tablet.c index 32856634e..667b020f1 100644 --- a/src/device/mouse_wacom_tablet.c +++ b/src/device/mouse_wacom_tablet.c @@ -424,9 +424,17 @@ wacom_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) } static int -wacom_poll(int x, int y, UNUSED(int z), int b, double abs_x, double abs_y, void *priv) +wacom_poll(void *priv) { mouse_wacom_t *wacom = (mouse_wacom_t *) priv; + int delta_x; + int delta_y; + int b = mouse_get_buttons_ex(); + double abs_x; + double abs_y; + + mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -32768, 32767, 0, 0); + mouse_get_abs_coords(&abs_x, &abs_y); if (wacom->settings_bits.cmd_set == WACOM_CMDSET_IV) { wacom->abs_x = abs_x * 5039. * (wacom->x_res / 1000.); @@ -442,8 +450,8 @@ wacom_poll(int x, int y, UNUSED(int z), int b, double abs_x, double abs_y, void wacom->abs_x = 0; if (wacom->abs_y < 0) wacom->abs_y = 0; - wacom->rel_x = x; - wacom->rel_y = y; + wacom->rel_x = delta_x; + wacom->rel_y = delta_y; } if (wacom->b != b) wacom->oldb = wacom->b; diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index eb0c734aa..ad44fc9e7 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -54,7 +54,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 @@ -493,7 +493,7 @@ 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); + pci_add_bridge(AGP_BRIDGE(dev->local), pci_bridge_read, pci_bridge_write, dev, &dev->slot); interrupt_count = sizeof(interrupts); interrupt_mask = interrupt_count - 1; diff --git a/src/device/postcard.c b/src/device/postcard.c index f5e85dafb..15f396516 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -29,11 +29,15 @@ #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; -#define UISTR_LEN 13 +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 32 static char postcard_str[UISTR_LEN]; /* UI output string */ extern void ui_sb_bugui(char *__str); @@ -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][3] = { { 0 }, + { 0 } }; + for (uint8_t i = 0; i < POSTCARDS_NUM; i++) { + if (!postcard_written[i]) { + snprintf(ps[0][i], sizeof(ps[0][i]), "--"); + snprintf(ps[1][i], sizeof(ps[1][i]), "--"); + } else if (postcard_written[i] == 1) { + snprintf(ps[0][i], sizeof(ps[0][i]), "%02X", postcard_codes[i]); + snprintf(ps[1][i], sizeof(ps[1][i]), "--"); + } else { + snprintf(ps[0][i], sizeof(ps[0][i]), "%02X", postcard_codes[i]); + snprintf(ps[1][i], sizeof(ps[1][i]), "%02X", postcard_prev_codes[i]); + } + } + + switch (postcard_ports_num) { + default: + case 2: + snprintf(postcard_str, sizeof(postcard_str), "POST: %s%s %s%s", + ps[0][0], ps[0][1], ps[1][0], ps[1][1]); + break; + case 3: + snprintf(postcard_str, sizeof(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: + snprintf(postcard_str, sizeof(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]) + snprintf(postcard_str, sizeof(postcard_str), "POST: -- --"); + else if (postcard_written[0] == 1) + snprintf(postcard_str, sizeof(postcard_str), "POST: %02X --", postcard_codes[0]); + else + snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X", postcard_codes[0], postcard_prev_codes[0]); + } ui_sb_bugui(postcard_str); @@ -79,22 +117,25 @@ 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)) + 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 +143,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 +151,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 +175,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); } diff --git a/src/device/serial.c b/src/device/serial.c index a36e4f99f..1587fbe03 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -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,17 @@ 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) { + if (set || (dev->irq_state != !!set)) + picint_common(1 << dev->irq, !!(dev->type >= SERIAL_16450), set, &dev->irq_state); + if (dev->type >= SERIAL_16450) + dev->irq_state = !!set; + } +} + void serial_update_ints(serial_t *dev) { @@ -131,13 +146,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 +604,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 +801,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), diff --git a/src/device/smbus_ali7101.c b/src/device/smbus_ali7101.c index 855f0c270..349de470d 100644 --- a/src/device/smbus_ali7101.c +++ b/src/device/smbus_ali7101.c @@ -193,10 +193,7 @@ smbus_ali7101_write(uint16_t addr, uint8_t val, void *priv) case 0x4: /* block R/W */ timer_bytes++; /* count the SMBus length byte now */ - -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; default: /* unknown */ dev->next_stat = 0x20; /* raise DEV_ERR */ diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index bad49b957..6f2b1632e 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -195,10 +195,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) i2c_write(i2c_smbus, smbus_addr, dev->cmd); timer_bytes++; } - -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0xc: /* I2C process call */ if (!read) { /* word write (only when writing) */ @@ -216,10 +213,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) case 0x5: /* block R/W */ timer_bytes++; /* count the SMBus length byte now */ - -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0xd: /* I2C block R/W */ i2c_write(i2c_smbus, smbus_addr, dev->cmd); @@ -251,10 +245,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) /* command write */ i2c_write(i2c_smbus, smbus_addr, dev->cmd); timer_bytes++; - -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0xe: /* I2C with 7-bit address */ if (!read) { /* word write (only when writing) */ diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 258ea9d0f..35f2db754 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -338,9 +338,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) esdi->command &= ~0x03; if (val & 0x02) fatal("Read with ECC\n"); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0xa0: esdi->status = STAT_BUSY; @@ -399,9 +397,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) default: esdi_at_log("WD1007: bad command %02X\n", val); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0xe8: /*???*/ esdi->status = STAT_BUSY; esdi_set_callback(esdi, 200 * HDC_TIME); diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index ace646328..01d1d28bf 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1655,9 +1655,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) disabled, the Read Multiple operation is rejected with an Aborted Com- mand error. */ ide->blockcount = 0; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case WIN_READ: case WIN_READ_NORETRY: @@ -1706,9 +1704,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) /* Turn on the activity indicator *here* so that it gets turned on less times. */ ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case WIN_WRITE: case WIN_WRITE_NORETRY: diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index 6cb54aea5..2d203f3f8 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -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); diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index 1f727bf6b..397329010 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -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); diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 5e8e4e987..fd6bee29d 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -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++; diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 766d70145..c924393e4 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -623,9 +623,7 @@ st506_callback(void *priv) st506_complete(dev); break; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case CMD_FORMAT_TRACK: case CMD_FORMAT_BAD_TRACK: @@ -1608,9 +1606,7 @@ st506_init(const device_t *info) case ST506_XT_TYPE_ST11R: /* Seagate ST-11R (RLL) */ dev->spt = RLL_SECTORS; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case ST506_XT_TYPE_ST11M: /* Seagate ST-11M (MFM) */ dev->nr_err = ERR_NOT_AVAILABLE; diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index b27648eca..9325c8f91 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -509,9 +509,7 @@ hdc_callback(void *priv) case CMD_READ_VERIFY: no_data = 1; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case CMD_READ_SECTORS: if (!drive->present) { @@ -536,9 +534,7 @@ hdc_callback(void *priv) dev->buf_len = 512; dev->state = STATE_SEND; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case STATE_SEND: /* Activate the status icon. */ @@ -646,9 +642,7 @@ do_send: dev->buf_len = 512; dev->state = STATE_RECV; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case STATE_RECV: /* Activate the status icon. */ diff --git a/src/disk/minivhd/manage.c b/src/disk/minivhd/manage.c index 053acc40c..b04a7d2ce 100644 --- a/src/disk/minivhd/manage.c +++ b/src/disk/minivhd/manage.c @@ -439,13 +439,14 @@ MVHDAPI int mvhd_file_is_vhd(FILE* f) { uint8_t con_str[8]; + size_t res; if (f == NULL) { return 0; } mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END); - fread(con_str, sizeof con_str, 1, f); + res = fread(con_str, sizeof con_str, 1, f); if (mvhd_is_conectix_str(con_str)) { return 1; } diff --git a/src/disk/mo.c b/src/disk/mo.c index eef83ec3a..378661683 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -655,9 +655,8 @@ mo_update_request_length(mo_t *dev, int len, int block_len) break; } } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; + default: dev->packet_len = len; break; @@ -1344,9 +1343,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) mo_invalid_field(dev); return; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: diff --git a/src/disk/zip.c b/src/disk/zip.c index cd7359c05..4473feca1 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -821,9 +821,7 @@ zip_update_request_length(zip_t *dev, int len, int block_len) break; } } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; default: dev->packet_len = len; @@ -1411,9 +1409,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_invalid_field(dev); return; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: @@ -1576,9 +1572,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_command_complete(dev); break; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case GPCMD_WRITE_6: case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 37e078b76..a163e5ca1 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -917,9 +917,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc_bad_command(fdc); break; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x07: /*Recalibrate*/ fdc->pnum = 0; fdc->ptot = 1; @@ -962,9 +960,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc_bad_command(fdc); break; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x10: /*Get version*/ case 0x14: /*Unlock*/ case 0x94: /*Lock*/ @@ -1086,9 +1082,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) case 0x16: /* Verify */ if (fdc->params[0] & 0x80) fdc->sc = fdc->params[7]; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x06: /* Read data */ case 0x0c: /* Read deleted data */ fdc_io_command_phase1(fdc, 0); diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 0e8085a71..4acb372d2 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1951,9 +1951,7 @@ d86f_format_track(int drive, int side, int do_write) if (dev->datac == 3) fdc_stop_id_request(d86f_fdc); } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case FMT_PRETRK_SYNC: case FMT_SECTOR_DATA_SYNC: @@ -2296,9 +2294,7 @@ d86f_turbo_poll(int drive, int side) case STATE_0D_SPIN_TO_INDEX: dev->sector_count = 0; dev->datac = 5; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case STATE_02_SPIN_TO_INDEX: dev->state++; @@ -2343,9 +2339,7 @@ d86f_turbo_poll(int drive, int side) dev->last_sector.id.r = dev->req_sector.id.r; dev->last_sector.id.n = dev->req_sector.id.n; d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case STATE_0A_FIND_ID: dev->turbo_pos = 0; diff --git a/src/gdbstub.c b/src/gdbstub.c index 4fafb545e..97bf82fc9 100644 --- a/src/gdbstub.c +++ b/src/gdbstub.c @@ -1015,13 +1015,8 @@ e14: /* Add our supported features to the end. */ if (client->response_pos < (sizeof(client->response) - 1)) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) client->response_pos += snprintf(&client->response[client->response_pos], sizeof(client->response) - client->response_pos, - "PacketSize=%lX;swbreak+;hwbreak+;qXfer:features:read+", sizeof(client->packet) - 1); -#else - client->response_pos += snprintf(&client->response[client->response_pos], sizeof(client->response) - client->response_pos, - "PacketSize=%X;swbreak+;hwbreak+;qXfer:features:read+", sizeof(client->packet) - 1); -#endif + "PacketSize=%X;swbreak+;hwbreak+;qXfer:features:read+", (int) (sizeof(client->packet) - 1)); break; } else if (!strcmp(client->response, "Xfer")) { /* Read the transfer object. */ diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 2f16c92d7..11dacef8c 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -47,10 +47,14 @@ #ifdef ABS # undef ABS #endif +#ifdef ABSD +# undef ABSD +#endif #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define ABS(x) ((x) > 0 ? (x) : -(x)) +#define ABSD(x) ((x) > 0.0 ? (x) : -(x)) #define BCD8(x) ((((x) / 10) << 4) | ((x) % 10)) #define BCD16(x) ((((x) / 1000) << 12) | (((x) / 100) << 8) | BCD8(x)) #define BCD32(x) ((((x) / 10000000) << 28) | (((x) / 1000000) << 24) | (((x) / 100000) << 20) | (((x) / 10000) << 16) | BCD16(x)) @@ -143,8 +147,10 @@ extern int is_pentium; /* TODO: Move back to cpu/cpu.h when it's figured out, extern int fixed_size_x; extern int fixed_size_y; extern double mouse_sensitivity; /* (C) Mouse sensitivity scale */ -extern double mouse_x_error; /* Mouse error accumulator - Y */ -extern double mouse_y_error; /* Mouse error accumulator - Y */ +#ifdef _Atomic +extern _Atomic double mouse_x_error; /* Mouse error accumulator - Y */ +extern _Atomic double mouse_y_error; /* Mouse error accumulator - Y */ +#endif extern int pit_mode; /* (C) force setting PIT mode */ extern int fm_driver; /* (C) select FM sound driver */ diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 11be67278..2b8a6396f 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -113,7 +113,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; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 9d6bd64cf..0a811938f 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -36,6 +36,9 @@ extern const device_t ali6117d_device; /* AMD */ extern const device_t amd640_device; +/* Compaq */ +extern const device_t compaq_386_device; + /* Contaq/Cypress */ extern const device_t contaq_82c596a_device; extern const device_t contaq_82c597_device; diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 74dd5ee3d..fb2d78eb4 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -135,8 +135,7 @@ typedef struct _device_ { void (*reset)(void *priv); union { int (*available)(void); - int (*poll)(int x, int y, int z, int b, double abs_x, double abs_y, void *priv); - void (*register_pci_slot)(int device, int type, int inta, int intb, int intc, int intd, void *priv); + int (*poll)(void *priv); }; void (*speed_changed)(void *priv); void (*force_redraw)(void *priv); @@ -179,8 +178,7 @@ extern void device_close_all(void); extern void device_reset_all(uint32_t match_flags); extern void *device_get_priv(const device_t *d); extern int device_available(const device_t *d); -extern int device_poll(const device_t *d, int x, int y, int z, int b); -extern void device_register_pci_slot(const device_t *d, int device, int type, int inta, int intb, int intc, int intd); +extern int device_poll(const device_t *d); extern void device_speed_changed(void); extern void device_force_redraw(void); extern void device_get_name(const device_t *d, int bus, char *name); diff --git a/src/include/86box/hdc_ide_sff8038i.h b/src/include/86box/hdc_ide_sff8038i.h index 490a13a42..f9c40e29a 100644 --- a/src/include/86box/hdc_ide_sff8038i.h +++ b/src/include/86box/hdc_ide_sff8038i.h @@ -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; diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index 4c1c793ae..eb3f54973 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -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); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index bd2207fe7..884564dbc 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -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]; + extern void mem_add_mtrr(uint64_t base, uint64_t mask, uint8_t type); extern void mem_del_mtrr(uint64_t base, uint64_t mask); extern void mem_invalidate_mtrr(uint8_t wb); diff --git a/src/include/86box/mouse.h b/src/include/86box/mouse.h index 839c0f11a..90000c0e2 100644 --- a/src/include/86box/mouse.h +++ b/src/include/86box/mouse.h @@ -20,8 +20,13 @@ #ifndef EMU_MOUSE_H #define EMU_MOUSE_H +#ifndef __cplusplus +/* Yes, a big no-no, but I'm saving myself time here. */ +#include +#endif + #define MOUSE_TYPE_NONE 0 /* no mouse configured */ -#define MOUSE_TYPE_INTERNAL 1 /* machine has internal mouse */ +#define MOUSE_TYPE_INTERNAL 1 /* achine has internal mouse */ #define MOUSE_TYPE_LOGIBUS 2 /* Logitech/ATI Bus Mouse */ #define MOUSE_TYPE_INPORT 3 /* Microsoft InPort Mouse */ #if 0 @@ -39,29 +44,27 @@ #define MOUSE_TYPE_ONBOARD 0x80 /* Mouse is an on-board version of one of the above. */ + #ifdef __cplusplus extern "C" { #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; #ifdef EMU_DEVICE_H -extern const device_t *mouse_get_device(int mouse); extern void *mouse_ps2_init(const device_t *); extern const device_t mouse_logibus_device; extern const device_t mouse_logibus_onboard_device; extern const device_t mouse_msinport_device; -# if 0 +# ifdef USE_GENIBUS extern const device_t mouse_genibus_device; # endif extern const device_t mouse_mssystems_device; @@ -72,28 +75,49 @@ extern const device_t mouse_wacom_device; extern const device_t mouse_wacom_artpad_device; #endif -extern void mouse_init(void); -extern void mouse_close(void); -extern void mouse_reset(void); -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_clear_x(void); +extern void mouse_clear_y(void); +extern void mouse_clear_coords(void); +extern void mouse_clear_buttons(void); +extern void mouse_subtract_x(int *delta_x, int *o_x, int min, int max, int abs); +extern void mouse_subtract_y(int *delta_y, int *o_y, int min, int max, int invert, int abs); +extern void mouse_subtract_coords(int *delta_x, int *delta_y, int *o_x, int *o_y, + int min, int max, int invert, int abs); +extern int mouse_moved(void); +extern int mouse_state_changed(void); +extern int mouse_mbut_changed(void); +extern void mouse_scale_fx(double x); +extern void mouse_scale_fy(double y); +extern void mouse_scale_x(int x); +extern void mouse_scale_y(int y); +extern void mouse_scalef(double x, double y); +extern void mouse_scale(int x, int y); +extern void mouse_set_z(int z); +extern void mouse_clear_z(void); +extern void mouse_subtract_z(int *delta_z, int min, int max, int invert); +extern void mouse_set_buttons_ex(int b); +extern int mouse_get_buttons_ex(void); +extern void mouse_set_sample_rate(double new_rate); +extern void mouse_set_buttons(int buttons); +extern void mouse_get_abs_coords(double *x_abs, double *y_abs); +extern void mouse_process(void); +extern void mouse_set_poll_ex(void (*poll_ex)(void)); +extern void mouse_set_poll(int (*f)(void *), void *); +extern char * mouse_get_name(int mouse); +extern char * mouse_get_internal_name(int mouse); +extern int mouse_get_from_internal_name(char *s); +extern int mouse_has_config(int mouse); +#ifdef EMU_DEVICE_H +extern const device_t *mouse_get_device(int mouse); +#endif +extern int mouse_get_buttons(void); +extern int mouse_get_ndev(void); +extern void mouse_set_raw(int raw); +extern void mouse_reset(void); +extern void mouse_close(void); +extern void mouse_init(void); -extern void mouse_bus_set_irq(void *priv, int irq); - -extern void mouse_set_sample_rate(double new_rate); - -extern char *mouse_get_name(int mouse); -extern char *mouse_get_internal_name(int mouse); -extern int mouse_get_from_internal_name(char *s); -extern int mouse_has_config(int mouse); -extern int mouse_get_type(int mouse); -extern int mouse_get_ndev(void); -extern int mouse_get_buttons(void); - -extern void mouse_clear_data(void *priv); +extern void mouse_bus_set_irq(void *priv, int irq); #ifdef __cplusplus } diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index df9c4c573..6ea53c51d 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -11,146 +11,261 @@ * * * Authors: Miran Grca, - * Fred N. van Kempen, - * Sarah Walker, * - * 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 void pci_add_bridge(uint8_t agp, 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 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; diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index dcc6f1358..a66e511b8 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -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*/ diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 2b0809c2e..44b0c691f 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -55,8 +55,13 @@ extern int strnicmp(const char *s1, const char *s2, size_t n); # define off64_t off_t #endif -#if !defined (__APPLE__) && !defined(__clang__) -# define FALLTHROUGH_ANNOTATION +#if __has_attribute(fallthrough) +# define fallthrough __attribute__((fallthrough)) +#else +# if __has_attribute(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +# endif +# define fallthrough do {} while (0) /* fallthrough */ #endif #ifdef _MSC_VER @@ -137,6 +142,8 @@ extern void plat_vidapi_reload(void); extern void plat_vid_reload_options(void); extern uint32_t plat_language_code(char *langcode); extern void plat_language_code_r(uint32_t lcid, char *outbuf, int len); +extern void plat_get_cpu_string(char *outbuf, uint8_t len); +extern double plat_get_dpi(void); /* Resource management. */ extern void set_language(uint32_t id); diff --git a/src/include/86box/plat_fallthrough.h b/src/include/86box/plat_fallthrough.h index 212d662fe..8d3f4581b 100644 --- a/src/include/86box/plat_fallthrough.h +++ b/src/include/86box/plat_fallthrough.h @@ -18,8 +18,13 @@ #ifndef EMU_PLAT_FALLTHROUGH_H #define EMU_PLAT_FALLTHROUGH_H -#if !defined (__APPLE__) && !defined(__clang__) -# define FALLTHROUGH_ANNOTATION +#if __has_attribute(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +#else +# if __has_attribute(fallthrough) +# define fallthrough __attribute__((fallthrough)) +# endif +# define fallthrough do {} while (0) /* fallthrough */ #endif #endif /*EMU_PLAT_FALLTHROUGH_H*/ diff --git a/src/include/86box/scsi_x54x.h b/src/include/86box/scsi_x54x.h index 213873c5a..29b7eb4fb 100644 --- a/src/include/86box/scsi_x54x.h +++ b/src/include/86box/scsi_x54x.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; diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index b27e54c5e..2b31a153b 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -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); diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index b2932c725..72235520a 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -19,8 +19,24 @@ #ifndef VIDEO_8514A_H #define VIDEO_8514A_H +typedef struct hwcursor8514_t { + int ena; + int x; + int y; + int xoff; + int yoff; + int cur_xsize; + int cur_ysize; + int v_acc; + int h_acc; + uint32_t addr; + uint32_t pitch; +} hwcursor8514_t; + typedef struct ibm8514_t { - uint8_t pos_regs[8]; + hwcursor8514_t hwcursor; + hwcursor8514_t hwcursor_latch; + uint8_t pos_regs[8]; int force_old_addr; int type; @@ -29,8 +45,10 @@ typedef struct ibm8514_t { uint32_t vram_size; uint32_t vram_mask; + uint32_t pallook[512]; PALETTE vgapal; + uint8_t hwcursor_oddeven; uint8_t dac_mask; uint8_t dac_status; uint32_t *map8; @@ -38,7 +56,9 @@ typedef struct ibm8514_t { int dac_pos; int dac_r; int dac_g; + int dac_b; int internal_pitch; + int hwcursor_on; struct { uint16_t subsys_cntl; diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index 97a08b583..180803c8a 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -44,9 +44,9 @@ typedef struct ega_t { uint8_t colournocare; uint8_t scrblank; uint8_t plane_mask; - uint8_t pad; - uint8_t pad0; - uint8_t pad1; + uint8_t ctl_mode; + uint8_t color_mux; + uint8_t dot; uint8_t crtc[32]; uint8_t gdcreg[16]; uint8_t attrregs[32]; @@ -108,6 +108,7 @@ typedef struct ega_t { int res_y; int bpp; int index; + int remap_required; uint32_t charseta; uint32_t charsetb; @@ -117,21 +118,24 @@ typedef struct ega_t { uint32_t ca; uint32_t vram_limit; uint32_t overscan_color; + uint32_t cca; uint32_t *pallook; uint64_t dispontime; uint64_t dispofftime; + + uint64_t dot_time; + pc_timer_t timer; + pc_timer_t dot_timer; - double clock; + double dot_clock; - int remap_required; - uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); + void * eeprom; - void (*render)(struct ega_t *svga); - - void *eeprom; + uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); + void (*render)(struct ega_t *svga); } ega_t; #endif diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index ab8144a77..2456f40d6 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -89,6 +89,7 @@ typedef struct svga_t { int dac_pos; int dac_r; int dac_g; + int dac_b; int vtotal; int dispend; int vsyncstart; @@ -341,6 +342,9 @@ extern void ati68860_ramdac_set_render(void *priv, svga_t *svga); extern void ati68860_ramdac_set_pallook(void *priv, int i, uint32_t col); extern void ati68860_hwcursor_draw(svga_t *svga, int displine); +extern void ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga); +extern uint8_t ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga); + extern void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); extern uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); @@ -396,6 +400,7 @@ extern float tvp3026_getclock(int clock, void *priv); # ifdef EMU_DEVICE_H extern const device_t ati68860_ramdac_device; +extern const device_t ati68875_ramdac_device; extern const device_t att490_ramdac_device; extern const device_t att491_ramdac_device; extern const device_t att492_ramdac_device; @@ -409,6 +414,9 @@ extern const device_t bt485a_ramdac_device; extern const device_t gendac_ramdac_device; extern const device_t ibm_rgb528_ramdac_device; extern const device_t ics2494an_305_device; +extern const device_t ati18810_device; +extern const device_t ati18811_0_device; +extern const device_t ati18811_1_device; extern const device_t ics2595_device; extern const device_t icd2061_device; extern const device_t ics9161_device; diff --git a/src/include/86box/vid_svga_render.h b/src/include/86box/vid_svga_render.h index 1f587d4f5..0c48303c9 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -73,6 +73,15 @@ void svga_render_ABGR8888_highres(svga_t *svga); void svga_render_RGBA8888_lowres(svga_t *svga); void svga_render_RGBA8888_highres(svga_t *svga); +void ibm8514_render_8bpp(svga_t *svga); +void ibm8514_render_15bpp(svga_t *svga); +void ibm8514_render_16bpp(svga_t *svga); +void ibm8514_render_24bpp(svga_t *svga); +void ibm8514_render_BGR(svga_t *svga); +void ibm8514_render_32bpp(svga_t *svga); +void ibm8514_render_ABGR8888(svga_t *svga); +void ibm8514_render_RGBA8888(svga_t *svga); + extern void (*svga_render)(svga_t *svga); #endif /*VID_SVGA_RENDER_H*/ diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index 92c608789..64a96fe53 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -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; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index b915fe35d..bc76d60fd 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -103,8 +103,8 @@ typedef struct monitor_t { int mon_efscrnsz_y; int mon_unscaled_size_x; int mon_unscaled_size_y; - int mon_res_x; - int mon_res_y; + double mon_res_x; + double mon_res_y; int mon_bpp; bitmap_t *target_buffer; int mon_video_timing_read_b; @@ -263,6 +263,8 @@ extern void video_close(void); extern void video_reset_close(void); extern void video_pre_reset(int card); extern void video_reset(int card); +extern void video_post_reset(void); +extern void video_voodoo_init(void); extern uint8_t video_force_resize_get_monitor(int monitor_index); extern void video_force_resize_set_monitor(uint8_t res, int monitor_index); extern void video_update_timing(void); @@ -300,7 +302,9 @@ extern void ibm8514_device_add(void); extern const device_t mach8_isa_device; extern const device_t mach32_isa_device; extern const device_t mach32_vlb_device; +extern const device_t mach32_mca_device; extern const device_t mach32_pci_device; +extern const device_t mach32_onboard_pci_device; /* ATi Mach64 */ extern const device_t mach64gx_isa_device; diff --git a/src/io.c b/src/io.c index 173e6707b..0e68049c3 100644 --- a/src/io.c +++ b/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; } diff --git a/src/lpt.c b/src/lpt.c index 7eb96a278..eafcd7d34 100644 --- a/src/lpt.c +++ b/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) { diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 543ebfc11..a64561cf2 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -152,8 +152,6 @@ typedef struct amstrad_t { pc_timer_t send_delay_timer; /* Mouse stuff. */ - uint8_t mousex; - uint8_t mousey; int oldb; /* Video stuff. */ @@ -2012,9 +2010,9 @@ ms_write(uint16_t addr, UNUSED(uint8_t val), void *priv) amstrad_t *ams = (amstrad_t *) priv; if ((addr == 0x78) || (addr == 0x79)) - ams->mousex = 0; + mouse_clear_x(); else - ams->mousey = 0; + mouse_clear_y(); } static uint8_t @@ -2022,25 +2020,26 @@ ms_read(uint16_t addr, void *priv) { amstrad_t *ams = (amstrad_t *) priv; uint8_t ret; + int delta = 0; if ((addr == 0x78) || (addr == 0x79)) { - ret = ams->mousex; - ams->mousex = 0; + mouse_subtract_x(&delta, NULL, -128, 127, 0); + mouse_clear_x(); } else { - ret = ams->mousey; - ams->mousey = 0; + mouse_subtract_y(&delta, NULL, -128, 127, 1, 0); + mouse_clear_y(); } + ret = (uint8_t) (int8_t) delta; + return ret; } static int -ms_poll(int x, int y, UNUSED(int z), int b, void *priv) +ms_poll(void *priv) { amstrad_t *ams = (amstrad_t *) priv; - - ams->mousex += x; - ams->mousey -= y; + int b = mouse_get_buttons_ex(); if ((b & 1) && !(ams->oldb & 1)) keyboard_send(0x7e); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 3f37c13c4..57f65811b 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -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); diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 0731aa810..3e342a950 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -31,6 +31,7 @@ #include <86box/mem.h> #include <86box/rom.h> #include <86box/device.h> +#include <86box/chipset.h> #include <86box/keyboard.h> #include <86box/fdd.h> #include <86box/fdc.h> @@ -795,34 +796,28 @@ machine_at_compaq_init(const machine_t *model, int type) { compaq_machine_type = type; - if ((type != COMPAQ_DESKPRO386) && (type != COMPAQ_DESKPRO386_01_1988)) - mem_remap_top(384); - if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - if ((type == COMPAQ_DESKPRO386) || (type == COMPAQ_DESKPRO386_01_1988) || (type == COMPAQ_PORTABLEIII386)) - mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, - read_ram, read_ramw, read_raml, - write_ram, write_ramw, write_raml, - 0xa0000 + ram, MEM_MAPPING_EXTERNAL, NULL); - else + if (type < COMPAQ_PORTABLEIII386) { + mem_remap_top(384); mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, read_ram, read_ramw, read_raml, write_ram, write_ramw, write_raml, 0xa0000 + ram, MEM_MAPPING_INTERNAL, NULL); + } video_reset(gfxcard[0]); switch (type) { case COMPAQ_PORTABLEII: - machine_at_init(model); + machine_at_init(model); break; case COMPAQ_PORTABLEIII: if (gfxcard[0] == VID_INTERNAL) device_add(&compaq_plasma_device); - machine_at_init(model); + machine_at_init(model); break; case COMPAQ_PORTABLEIII386: @@ -830,13 +825,14 @@ machine_at_compaq_init(const machine_t *model, int type) device_add(&ide_isa_device); if (gfxcard[0] == VID_INTERNAL) device_add(&compaq_plasma_device); - machine_at_init(model); + machine_at_init(model); break; case COMPAQ_DESKPRO386: case COMPAQ_DESKPRO386_01_1988: if (hdc_current == 1) device_add(&ide_isa_device); + device_add(&compaq_386_device); machine_at_common_init(model); device_add(&keyboard_at_compaq_device); break; diff --git a/src/machine/m_at_misc.c b/src/machine/m_at_misc.c index 71c9d2ab7..d4264f07e 100644 --- a/src/machine/m_at_misc.c +++ b/src/machine/m_at_misc.c @@ -1,74 +1,74 @@ -/* - * 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. - * - * Implementation of Miscellaneous, Fake, Hypervisor machines. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2019 Miran Grca. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/rom.h> -#include <86box/pci.h> -#include <86box/device.h> -#include <86box/chipset.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/keyboard.h> -#include <86box/flash.h> -#include <86box/sio.h> -#include <86box/hwm.h> -#include <86box/spd.h> -#include <86box/video.h> -#include "cpu.h" -#include <86box/machine.h> -#include <86box/sound.h> - -int -machine_at_vpc2007_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/vpc2007/13500.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - is_vpc = 1; - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&i440bx_no_agp_device); - device_add(&piix4e_device); - device_add(&w83977f_370_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */ - - return ret; -} +/* + * 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. + * + * Implementation of Miscellaneous, Fake, Hypervisor machines. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/keyboard.h> +#include <86box/flash.h> +#include <86box/sio.h> +#include <86box/hwm.h> +#include <86box/spd.h> +#include <86box/video.h> +#include "cpu.h" +#include <86box/machine.h> +#include <86box/sound.h> + +int +machine_at_vpc2007_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/vpc2007/13500.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + is_vpc = 1; + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i440bx_no_agp_device); + device_add(&piix4e_device); + device_add(&w83977f_370_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */ + + return ret; +} diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index fd91067ae..da160c138 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -1,153 +1,153 @@ -/* - * 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. - * - * Implementation of Slot 2 machines. - * - * Slot 2 is quite a rare type of Slot. Used mostly by Pentium II & III Xeons - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2019 Miran Grca. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/rom.h> -#include <86box/pci.h> -#include <86box/device.h> -#include <86box/chipset.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/keyboard.h> -#include <86box/flash.h> -#include <86box/sio.h> -#include <86box/hwm.h> -#include <86box/spd.h> -#include <86box/video.h> -#include <86box/clock.h> -#include "cpu.h" -#include <86box/machine.h> - -int -machine_at_6gxu_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/6gxu/6gxu.f1c", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* On-Board SCSI. Not emulated at the moment */ - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - - device_add(&i440gx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_pci_device); - device_add(&w83977ef_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 512); - device_add(&w83782d_device); /* fans: CPU, Power, System; temperatures: System, CPU, unused */ - hwm_values.temperatures[2] = 0; /* unused */ - hwm_values.voltages[1] = 1500; /* VGTL */ - - return ret; -} - -int -machine_at_s2dge_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/s2dge/2gu7301.rom", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); - - device_add(&i440gx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83977tf_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 512); - device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ - hwm_values.fans[1] = 0; /* no CPU2 fan */ - hwm_values.temperatures[0] = 0; /* unused */ - hwm_values.temperatures[2] = 0; /* CPU2? */ - - return ret; -} - -int -machine_at_fw6400gx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/fw6400gx/FWGX1211.ROM", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); - - device_add(&i440gx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87309_15c_device); - device_add(ics9xxx_get(ICS9250_08)); - device_add(&sst_flash_29ee020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 512); - device_add(&w83781d_device); /* fans: Chassis, Power, CPU; temperatures: System, CPU, unused */ - hwm_values.temperatures[3] = 0; /* unused */ - hwm_values.voltages[1] = 1500; /* Vtt */ - - return ret; -} +/* + * 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. + * + * Implementation of Slot 2 machines. + * + * Slot 2 is quite a rare type of Slot. Used mostly by Pentium II & III Xeons + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/keyboard.h> +#include <86box/flash.h> +#include <86box/sio.h> +#include <86box/hwm.h> +#include <86box/spd.h> +#include <86box/video.h> +#include <86box/clock.h> +#include "cpu.h" +#include <86box/machine.h> + +int +machine_at_6gxu_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/6gxu/6gxu.f1c", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* On-Board SCSI. Not emulated at the moment */ + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + + device_add(&i440gx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977ef_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&w83782d_device); /* fans: CPU, Power, System; temperatures: System, CPU, unused */ + hwm_values.temperatures[2] = 0; /* unused */ + hwm_values.voltages[1] = 1500; /* VGTL */ + + return ret; +} + +int +machine_at_s2dge_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/s2dge/2gu7301.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + + device_add(&i440gx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ + hwm_values.fans[1] = 0; /* no CPU2 fan */ + hwm_values.temperatures[0] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* CPU2? */ + + return ret; +} + +int +machine_at_fw6400gx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/fw6400gx/FWGX1211.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); + + device_add(&i440gx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&pc87309_15c_device); + device_add(ics9xxx_get(ICS9250_08)); + device_add(&sst_flash_29ee020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 512); + device_add(&w83781d_device); /* fans: Chassis, Power, CPU; temperatures: System, CPU, unused */ + hwm_values.temperatures[3] = 0; /* unused */ + hwm_values.voltages[1] = 1500; /* Vtt */ + + return ret; +} diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index b8cc437a1..db6013ae1 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -1,458 +1,458 @@ -/* - * 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. - * - * Implementation of Socket 370(PGA370) machines. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2016-2019 Miran Grca. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/rom.h> -#include <86box/pci.h> -#include <86box/device.h> -#include <86box/chipset.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/keyboard.h> -#include <86box/flash.h> -#include <86box/sio.h> -#include <86box/hwm.h> -#include <86box/spd.h> -#include <86box/video.h> -#include "cpu.h" -#include <86box/machine.h> -#include <86box/clock.h> -#include <86box/sound.h> -#include <86box/snd_ac97.h> - -int -machine_at_s370slm_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/s370slm/3LM1202.rom", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440lx_device); - device_add(&piix4e_device); - device_add(&w83977tf_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - device_add(&w83781d_device); /* fans: CPU, Fan 2, Chassis; temperatures: unused, CPU, unused */ - hwm_values.temperatures[0] = 0; /* unused */ - hwm_values.temperatures[2] = 0; /* unused */ - - return ret; -} - -int -machine_at_s1857_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/s1857/BX57200A.ROM", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_SOUND, 1, 0, 0, 0); - pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83977ef_370_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - if (sound_card_current[0] == SOUND_INTERNAL) { - device_add(&es1371_onboard_device); - device_add(&cs4297_device); /* found on other Tyan boards around the same time */ - } - - return ret; -} - -int -machine_at_p6bap_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/p6bap/bapa14a.BIN", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); - pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); - pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); - device_add(&via_apro133a_device); /* Rebranded as ET82C693A */ - device_add(&via_vt82c596b_device); /* Rebranded as ET82C696B */ - device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - return ret; -} - -int -machine_at_p6bat_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/p6bat/bata+56.BIN", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); - pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); - pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); - pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); - pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); - device_add(&via_apro133_device); - device_add(&via_vt82c596b_device); - device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - if (sound_card_current[0] == SOUND_INTERNAL) { - device_add(&cmi8738_onboard_device); - } - - return ret; -} - -int -machine_at_cubx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/cubx/1008cu.004", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x07, PCI_CARD_IDE, 2, 3, 4, 1); - pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&w83977ef_device); - device_add(ics9xxx_get(ICS9250_08)); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); - device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ - - return ret; -} - -int -machine_at_atc7020bxii_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/atc7020bxii/7020s102.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&slc90e66_device); - device_add(&keyboard_ps2_pci_device); - device_add(&w83977ef_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); - - return ret; -} - -int -machine_at_ambx133_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/ambx133/mkbx2vg2.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&piix4e_device); - device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - device_add(&gl518sm_2d_device); /* fans: CPUFAN1, CPUFAN2; temperature: CPU */ - hwm_values.fans[1] += 500; - hwm_values.temperatures[0] += 4; /* CPU offset */ - hwm_values.voltages[1] = RESISTOR_DIVIDER(12000, 10, 2); /* different 12V divider in BIOS (10K/2K?) */ - - return ret; -} - -int -machine_at_awo671r_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/awo671r/a08139c.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); - device_add(&piix4e_device); - device_add_inst(&w83977ef_device, 1); - device_add_inst(&w83977ef_device, 2); - device_add(&keyboard_ps2_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 256); - - return ret; -} - -int -machine_at_63a1_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/63a1/63a-q3.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Integrated Sound? */ - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440zx_device); - device_add(&piix4e_device); - device_add(&w83977tf_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 256); - - return ret; -} - -int -machine_at_apas3_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/apas3/V0218SAG.BIN", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&via_apro_device); - device_add(&via_vt82c586b_device); - device_add(&fdc37c669_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 256); - - return ret; -} - -int -machine_at_cuv4xls_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/cuv4xls/1005LS.001", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 4, 1, 2, 3); - pci_register_slot(0x05, PCI_CARD_SOUND, 3, 0, 0, 0); - pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 0, 0); - pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&via_apro133a_device); - device_add(&via_vt82c686b_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(ics9xxx_get(ICS9250_18)); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 1024); - device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ - - if (sound_card_current[0] == SOUND_INTERNAL) - device_add(&cmi8738_onboard_device); - - return ret; -} - -int -machine_at_6via90ap_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/6via90ap/90ap10.bin", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init_ex(model, 2); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&via_apro133a_device); - device_add(&via_vt82c686b_device); /* fans: CPU1, CPU2; temperatures: CPU, System, unused */ - device_add(&keyboard_ps2_ami_pci_device); - device_add(ics9xxx_get(ICS9250_18)); - device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0x7, 1024); - hwm_values.temperatures[0] += 2; /* CPU offset */ - hwm_values.temperatures[1] += 2; /* System offset */ - hwm_values.temperatures[2] = 0; /* unused */ - - if (sound_card_current[0] == SOUND_INTERNAL) - device_add(&alc100_device); /* ALC100P identified on similar Acorp boards (694TA, 6VIA90A1) */ - - return ret; -} +/* + * 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. + * + * Implementation of Socket 370(PGA370) machines. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/keyboard.h> +#include <86box/flash.h> +#include <86box/sio.h> +#include <86box/hwm.h> +#include <86box/spd.h> +#include <86box/video.h> +#include "cpu.h" +#include <86box/machine.h> +#include <86box/clock.h> +#include <86box/sound.h> +#include <86box/snd_ac97.h> + +int +machine_at_s370slm_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/s370slm/3LM1202.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440lx_device); + device_add(&piix4e_device); + device_add(&w83977tf_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + device_add(&w83781d_device); /* fans: CPU, Fan 2, Chassis; temperatures: unused, CPU, unused */ + hwm_values.temperatures[0] = 0; /* unused */ + hwm_values.temperatures[2] = 0; /* unused */ + + return ret; +} + +int +machine_at_s1857_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/s1857/BX57200A.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUND, 1, 0, 0, 0); + pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977ef_370_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + if (sound_card_current[0] == SOUND_INTERNAL) { + device_add(&es1371_onboard_device); + device_add(&cs4297_device); /* found on other Tyan boards around the same time */ + } + + return ret; +} + +int +machine_at_p6bap_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p6bap/bapa14a.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); + device_add(&via_apro133a_device); /* Rebranded as ET82C693A */ + device_add(&via_vt82c596b_device); /* Rebranded as ET82C696B */ + device_add(&w83977ef_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; +} + +int +machine_at_p6bat_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p6bat/bata+56.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 5); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 5); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 5, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 5, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 5, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_NORMAL, 5, 3, 2, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 5); + device_add(&via_apro133_device); + device_add(&via_vt82c596b_device); + device_add(&w83977ef_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + if (sound_card_current[0] == SOUND_INTERNAL) { + device_add(&cmi8738_onboard_device); + } + + return ret; +} + +int +machine_at_cubx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/cubx/1008cu.004", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_IDE, 2, 3, 4, 1); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977ef_device); + device_add(ics9xxx_get(ICS9250_08)); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ + + return ret; +} + +int +machine_at_atc7020bxii_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/atc7020bxii/7020s102.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&slc90e66_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977ef_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + + return ret; +} + +int +machine_at_ambx133_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ambx133/mkbx2vg2.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&w83977ef_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + device_add(&gl518sm_2d_device); /* fans: CPUFAN1, CPUFAN2; temperature: CPU */ + hwm_values.fans[1] += 500; + hwm_values.temperatures[0] += 4; /* CPU offset */ + hwm_values.voltages[1] = RESISTOR_DIVIDER(12000, 10, 2); /* different 12V divider in BIOS (10K/2K?) */ + + return ret; +} + +int +machine_at_awo671r_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/awo671r/a08139c.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add_inst(&w83977ef_device, 1); + device_add_inst(&w83977ef_device, 2); + device_add(&keyboard_ps2_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); + + return ret; +} + +int +machine_at_63a1_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/63a1/63a-q3.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Integrated Sound? */ + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440zx_device); + device_add(&piix4e_device); + device_add(&w83977tf_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); + + return ret; +} + +int +machine_at_apas3_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/apas3/V0218SAG.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&via_apro_device); + device_add(&via_vt82c586b_device); + device_add(&fdc37c669_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; +} + +int +machine_at_cuv4xls_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/cuv4xls/1005LS.001", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 4, 1, 2, 3); + pci_register_slot(0x05, PCI_CARD_SOUND, 3, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 0, 0); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&via_apro133a_device); + device_add(&via_vt82c686b_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(ics9xxx_get(ICS9250_18)); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 1024); + device_add(&as99127f_device); /* fans: Chassis, CPU, Power; temperatures: MB, JTPWR, CPU */ + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cmi8738_onboard_device); + + return ret; +} + +int +machine_at_6via90ap_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/6via90ap/90ap10.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&via_apro133a_device); + device_add(&via_vt82c686b_device); /* fans: CPU1, CPU2; temperatures: CPU, System, unused */ + device_add(&keyboard_ps2_ami_pci_device); + device_add(ics9xxx_get(ICS9250_18)); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 1024); + hwm_values.temperatures[0] += 2; /* CPU offset */ + hwm_values.temperatures[1] += 2; /* System offset */ + hwm_values.temperatures[2] = 0; /* unused */ + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&alc100_device); /* ALC100P identified on similar Acorp boards (694TA, 6VIA90A1) */ + + return ret; +} diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index b8e080d62..6d8611684 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -269,6 +269,7 @@ machine_at_valuepointp60_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_VIDEO, 3, 3, 3, 3); pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); @@ -280,6 +281,9 @@ machine_at_valuepointp60_init(const machine_t *model) device_add(&i430lx_device); + if (gfxcard[0] == VID_INTERNAL) + device_add(&mach32_onboard_pci_device); + return ret; } diff --git a/src/machine/m_elt.c b/src/machine/m_elt.c index 573095223..95ca52a3e 100644 --- a/src/machine/m_elt.c +++ b/src/machine/m_elt.c @@ -124,9 +124,7 @@ elt_vid_out(uint16_t addr, uint8_t val, void *priv) case 0x3d1: if (cga->crtcreg >= 32) return; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; default: cga->crtcreg &= 31; diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index f8c50a931..80a0ffbc1 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -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; diff --git a/src/machine/m_ps1_hdc.c b/src/machine/m_ps1_hdc.c index 225ae04a5..2636812d4 100644 --- a/src/machine/m_ps1_hdc.c +++ b/src/machine/m_ps1_hdc.c @@ -699,9 +699,7 @@ do_fmt: /* Done with this track. */ dev->state = STATE_FDONE; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case STATE_FDONE: /* One more track done. */ if (++start_cyl == end_cyl) { diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 0a638ce37..fa9afc321 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -131,9 +131,8 @@ typedef struct m24_kbd_t { /* Mouse stuff. */ int mouse_mode; - int x; - int y; int b; + pc_timer_t send_delay_timer; } m24_kbd_t; @@ -732,12 +731,14 @@ m24_kbd_reset(void *priv) } static int -ms_poll(int x, int y, UNUSED(int z), int b, void *priv) +ms_poll(void *priv) { m24_kbd_t *m24_kbd = (m24_kbd_t *) priv; - - m24_kbd->x += x; - m24_kbd->y += y; + int delta_x; + int delta_y; + int o_x; + int o_y; + int b = mouse_get_buttons_ex(); if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; @@ -770,53 +771,45 @@ ms_poll(int x, int y, UNUSED(int z), int b, void *priv) if (((key_queue_end - key_queue_start) & 0xf) > 12) return 0xff; - if (!m24_kbd->x && !m24_kbd->y) + if (!mouse_moved()) return 0xff; - m24_kbd->y = -m24_kbd->y; + mouse_subtract_coords(&delta_x, &delta_y, &o_x, &o_y, -127, 127, 1, 0); - if (m24_kbd->x < -127) - m24_kbd->x = -127; - if (m24_kbd->x > 127) - m24_kbd->x = 127; - if (m24_kbd->x < -127) - m24_kbd->x = 0x80 | ((-m24_kbd->x) & 0x7f); + if ((delta_x == -127) && o_x) + delta_x = 0x80 | ((-delta_x) & 0x7f); - if (m24_kbd->y < -127) - m24_kbd->y = -127; - if (m24_kbd->y > 127) - m24_kbd->y = 127; - if (m24_kbd->y < -127) - m24_kbd->y = 0x80 | ((-m24_kbd->y) & 0x7f); + if ((delta_y == -127) && o_y) + delta_y = 0x80 | ((-delta_y) & 0x7f); m24_kbd_adddata(0xfe); - m24_kbd_adddata(m24_kbd->x); - m24_kbd_adddata(m24_kbd->y); - - m24_kbd->x = m24_kbd->y = 0; + m24_kbd_adddata(delta_x); + m24_kbd_adddata(delta_y); } else { - while (m24_kbd->x < -4) { + mouse_subtract_coords(&delta_x, &delta_y, &o_x, &o_y, -127, 127, 1, 0); + + while (delta_x < -4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; - m24_kbd->x += 4; + delta_x += 4; m24_kbd_adddata(m24_kbd->scan[3]); } - while (m24_kbd->x > 4) { + while (delta_x > 4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; - m24_kbd->x -= 4; + delta_x -= 4; m24_kbd_adddata(m24_kbd->scan[4]); } - while (m24_kbd->y < -4) { + while (delta_y < -4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; - m24_kbd->y += 4; + delta_y += 4; m24_kbd_adddata(m24_kbd->scan[5]); } - while (m24_kbd->y > 4) { + while (delta_y > 4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) return 0xff; - m24_kbd->y -= 4; + delta_y -= 4; m24_kbd_adddata(m24_kbd->scan[6]); } } diff --git a/src/machine/machine.c b/src/machine/machine.c index 47e98e7b3..70228390d 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -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! */ @@ -118,17 +118,7 @@ machine_init_ex(int m) if (bios_only || !ret) return ret; - if (gfxcard[0] != VID_NONE) { - if (ibm8514_enabled) { - ibm8514_device_add(); - } - if (xga_enabled) - xga_device_add(); - } - - /* Reset the graphics card (or do nothing if it was already done - by the machine's init function). */ - video_reset(gfxcard[0]); + video_post_reset(); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 33268a463..255115bf7 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -302,7 +302,7 @@ const machine_t machines[] = { .bus_flags = MACHINE_PCJR, .flags = MACHINE_VIDEO_FIXED, .ram = { - .min = 128, + .min = 64, .max = 640, .step = 64 }, @@ -4694,9 +4694,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_AT, .flags = MACHINE_IDE, .ram = { - .min = 640, + .min = 1024, .max = 16384, - .step = 128 + .step = 1024 }, .nvrmask = 63, .kbc_device = NULL, @@ -4732,9 +4732,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_AT, .flags = MACHINE_IDE, .ram = { - .min = 640, + .min = 1024, .max = 16384, - .step = 128 + .step = 1024 }, .nvrmask = 63, .kbc_device = NULL, @@ -7754,7 +7754,7 @@ const machine_t machines[] = { .max_multi = MACHINE_MULTIPLIER_FIXED }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, .ram = { .min = 2048, .max = 131072, @@ -7764,7 +7764,7 @@ const machine_t machines[] = { .kbc_device = NULL, .kbc_p1 = 0, .gpio = 0, - .device = NULL, + .device = &mach32_onboard_pci_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index 001e7b5bc..d3d5d1ce7 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -13,5 +13,5 @@ # Copyright 2020-2021 David Hrdlička. # -add_library(mem OBJECT 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 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) diff --git a/src/mem/mem.c b/src/mem/mem.c index 419501a40..14bd32da7 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -120,14 +120,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]; diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c new file mode 100644 index 000000000..af7d8192c --- /dev/null +++ b/src/mem/mmu_2386.c @@ -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, + * Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. + */ +#include +#include +#include +#include +#include +#include +#include +#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++; + } +} diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 80dc4ec27..56f7facff 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -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); @@ -750,9 +759,7 @@ nic_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x10: /* PCI_BAR */ val &= 0xe0; /* 0xe0 acc to RTL DS */ val |= 0x01; /* re-enable IOIN bit */ -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x11: /* PCI_BAR */ case 0x12: /* PCI_BAR */ @@ -1087,8 +1094,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. */ diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 85d2cb8bb..7cbe10e31 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -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; diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 61c35986d..04b922aaf 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -735,9 +735,8 @@ wd_init(const device_t *info) /* Ethernet, MCA, 5x3 interface chip, RAM 16k */ case WD8003EA: dev->board_chip = WE_ID_SOFT_CONFIG; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; + /* Ethernet, MCA, no interface chip, RAM 16k */ case WD8003ETA: dev->board_chip |= WE_TYPE_WD8013EBT | WE_ID_BUS_MCA; diff --git a/src/nvr_at.c b/src/nvr_at.c index 62598c4be..570eb4714 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -309,7 +309,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]; @@ -437,6 +437,23 @@ 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 || (local->irq_state != !!irq)) { + 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) @@ -445,45 +462,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; } } @@ -528,13 +538,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); } } @@ -544,15 +548,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); } } @@ -586,32 +589,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 */ @@ -701,9 +701,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: diff --git a/src/pci.c b/src/pci.c index c86006a1a..9a7fb664b 100644 --- a/src/pci.c +++ b/src/pci.c @@ -11,12 +11,8 @@ * * * Authors: Miran Grca, - * Fred N. van Kempen, - * Sarah Walker, * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2008-2020 Sarah Walker. + * Copyright 2023 Miran Grca. */ #include #include @@ -36,53 +32,67 @@ #include <86box/keyboard.h> #include <86box/plat_unused.h> -typedef struct pci_card_t { - uint8_t bus; - uint8_t id; - uint8_t type; - uint8_t irq_routing[4]; +#define PCI_ENABLED 0x80000000 - void *priv; - void (*write)(int func, int addr, uint8_t val, void *priv); - uint8_t (*read)(int func, int addr, void *priv); +typedef struct pci_card_t { + uint8_t bus; + uint8_t id; + uint8_t type; + uint8_t irq_routing[PCI_INT_PINS_NUM]; + + void * priv; + void (*write)(int func, int addr, uint8_t val, void *priv); + uint8_t (*read)(int func, int addr, void *priv); } pci_card_t; +typedef struct pci_card_desc_t { + uint8_t type; + void * priv; + void (*write)(int func, int addr, uint8_t val, void *priv); + uint8_t (*read)(int func, int addr, void *priv); + uint8_t *slot; +} pci_card_desc_t; + typedef struct pci_mirq_t { - uint8_t enabled; - uint8_t irq_line; + uint8_t enabled; + uint8_t irq_line; } pci_mirq_t; -int pci_burst_time; -int agp_burst_time; -int pci_nonburst_time; -int agp_nonburst_time; -int pci_take_over_io; +int pci_burst_time; +int agp_burst_time; +int pci_nonburst_time; +int agp_nonburst_time; -uint32_t pci_base = 0xc000; -uint32_t pci_size = 0x1000; +int pci_flags; -static pci_card_t pci_cards[32]; -static uint8_t pci_pmc = 0; -static uint8_t last_pci_card = 0; -static uint8_t last_normal_pci_card = 0; -static uint8_t last_pci_bus = 1; -static uint8_t pci_card_to_slot_mapping[256][32]; -static uint8_t pci_bus_number_to_index_mapping[256]; -static uint8_t pci_irqs[16]; -static uint8_t pci_irq_level[16]; -static uint64_t pci_irq_hold[16]; -static pci_mirq_t pci_mirqs[8]; -static int pci_type; -static int pci_switch; -static int pci_index; -static int pci_func; -static int pci_card; -static int pci_bus; -static int pci_enable; -static int pci_key; -static int trc_reg = 0; +uint32_t pci_base = 0xc000; +uint32_t pci_size = 0x1000; -static void pci_reset_regs(void); +static pci_card_t pci_cards[PCI_CARDS_NUM]; +static pci_card_desc_t pci_card_descs[PCI_CARDS_NUM]; +static uint8_t pci_pmc = 0; +static uint8_t last_pci_card = 0; +static uint8_t last_normal_pci_card = 0; +static uint8_t last_normal_pci_card_id = 0; +static uint8_t last_pci_bus = 1; +static uint8_t next_pci_card = 0; +static uint8_t normal_pci_cards = 0; +static uint8_t next_normal_pci_card = 0; +static uint8_t pci_card_to_slot_mapping[256][PCI_CARDS_NUM]; +static uint8_t pci_bus_number_to_index_mapping[256]; +static uint8_t pci_irqs[PCI_IRQS_NUM]; +static uint8_t pci_irq_level[PCI_IRQS_NUM]; +static uint64_t pci_irq_hold[PCI_IRQS_NUM]; +static pci_mirq_t pci_mirqs[PCI_MIRQS_NUM]; +static int pci_index; +static int pci_func; +static int pci_card; +static int pci_bus; +static int pci_key; +static int pci_trc_reg = 0; +static uint32 pci_enable = 0x00000000; + +static void pci_reset_regs(void); #ifdef ENABLE_PCI_LOG int pci_do_log = ENABLE_PCI_LOG; @@ -102,548 +112,6 @@ pci_log(const char *fmt, ...) # define pci_log(fmt, ...) #endif -static void -pci_clear_slot(int card) -{ - pci_card_to_slot_mapping[pci_cards[card].bus][pci_cards[card].id] = 0xff; - - pci_cards[card].id = 0xff; - pci_cards[card].type = 0xff; - - for (uint8_t i = 0; i < 4; i++) - pci_cards[card].irq_routing[i] = 0; - - pci_cards[card].read = NULL; - pci_cards[card].write = NULL; - pci_cards[card].priv = NULL; -} - -void -pci_relocate_slot(int type, int new_slot) -{ - int card = -1; - int old_slot; - uint8_t mapping; - - if ((new_slot < 0) || (new_slot > 31)) - return; - - for (uint8_t i = 0; i < 32; i++) { - if ((pci_cards[i].bus == 0) && (pci_cards[i].type == type)) { - card = i; - break; - } - } - - if (card == -1) - return; - - old_slot = pci_cards[card].id; - pci_cards[card].id = new_slot; - mapping = pci_card_to_slot_mapping[0][old_slot]; - pci_card_to_slot_mapping[0][old_slot] = 0xff; - pci_card_to_slot_mapping[0][new_slot] = mapping; -} - -static void -pci_cf8_write(UNUSED(uint16_t port), uint32_t val, UNUSED(void *priv)) -{ - pci_log("cf8 write: %08X\n", val); - pci_index = val & 0xff; - pci_func = (val >> 8) & 7; - pci_card = (val >> 11) & 31; - pci_bus = (val >> 16) & 0xff; - pci_enable = (val >> 31) & 1; -} - -static uint32_t -pci_cf8_read(UNUSED(uint16_t port), UNUSED(void *priv)) -{ - return pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16) | (pci_enable << 31); -} - -static void -pci_write(uint16_t port, uint8_t val, UNUSED(void *priv)) -{ - uint8_t slot = 0; - - if (in_smm) - pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return; - - pci_log("Writing %02X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].write) { - pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); - pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - - break; - - default: - break; - } -} - -static void -pci_writew(uint16_t port, uint16_t val, UNUSED(void *priv)) -{ - uint8_t slot = 0; - - if (in_smm) - pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return; - - pci_log("Writing %04X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].write) { - pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); - pci_cards[slot].write(pci_func, pci_index | (port & 3), val & 0xff, pci_cards[slot].priv); - pci_cards[slot].write(pci_func, pci_index | ((port & 3) + 1), val >> 8, pci_cards[slot].priv); - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - - break; - - default: - break; - } -} - -static void -pci_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) -{ - uint8_t slot = 0; - - if (in_smm) - pci_log("(%i) %03x write: %02X\n", pci_enable, port, val); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return; - - pci_log("Writing %08X to PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", val, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].write) { - pci_log("Writing to PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); - pci_cards[slot].write(pci_func, pci_index | (port & 3), val & 0xff, pci_cards[slot].priv); - pci_cards[slot].write(pci_func, pci_index | ((port & 3) + 1), (val >> 8) & 0xff, pci_cards[slot].priv); - pci_cards[slot].write(pci_func, pci_index | ((port & 3) + 2), (val >> 16) & 0xff, pci_cards[slot].priv); - pci_cards[slot].write(pci_func, pci_index | ((port & 3) + 3), (val >> 24) & 0xff, pci_cards[slot].priv); - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - - break; - - default: - break; - } -} - -static uint8_t -pci_read(uint16_t port, UNUSED(void *priv)) -{ - uint8_t slot = 0; - uint8_t ret = 0xff; - - if (in_smm) - pci_log("(%i) %03x read\n", pci_enable, port); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) - ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - break; - - default: - break; - } - - pci_log("Reading %02X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - - return ret; -} - -static uint16_t -pci_readw(uint16_t port, UNUSED(void *priv)) -{ - uint8_t slot = 0; - uint16_t ret = 0xffff; - - if (in_smm) - pci_log("(%i) %03x read\n", pci_enable, port); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) { - ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); - ret |= (pci_cards[slot].read(pci_func, (pci_index | (port & 3)) + 1, pci_cards[slot].priv) << 8); - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - break; - - default: - break; - } - - pci_log("Reading %04X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - - return ret; -} - -static uint32_t -pci_readl(uint16_t port, UNUSED(void *priv)) -{ - uint8_t slot = 0; - uint32_t ret = 0xffffffff; - - if (in_smm) - pci_log("(%i) %03x read\n", pci_enable, port); - - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) { - ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); - ret |= (pci_cards[slot].read(pci_func, (pci_index | (port & 3)) + 1, pci_cards[slot].priv) << 8); - ret |= (pci_cards[slot].read(pci_func, (pci_index | (port & 3)) + 2, pci_cards[slot].priv) << 16); - ret |= (pci_cards[slot].read(pci_func, (pci_index | (port & 3)) + 3, pci_cards[slot].priv) << 24); - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index | (port & 3)); -#endif - break; - - default: - break; - } - - pci_log("Reading %08X, from PCI card on bus %i, slot %02X (pci_cards[%i]) (%02X:%02X)...\n", ret, pci_bus, pci_card, slot, pci_func, pci_index | (port & 3)); - - return ret; -} - -void -pci_set_pmc(uint8_t pmc) -{ - pci_log("pci_set_pmc(%02X)\n", pmc); -#if 0 - pci_reset_regs(); -#endif - - if (!pci_pmc && (pmc & 0x01)) { - pci_log("PMC: Dellocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io &= ~PCI_IO_ON; - - io_removehandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_removehandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cf8, 1, - NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); - io_sethandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cfc, 4, - pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - } else if (pci_pmc && !(pmc & 0x01)) { - pci_log("PMC: Redellocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io &= ~PCI_IO_ON; - if (pci_key) { - pci_log("PMC: Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io |= PCI_IO_ON; - } - - io_removehandler(0x0cf8, 1, - NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); - io_removehandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_removehandler(0x0cfc, 4, - pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - io_sethandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - } - - pci_pmc = (pmc & 0x01); -} - -static void -pci_type2_write_reg(uint16_t port, uint8_t val) -{ - uint8_t slot = 0; - - pci_card = (port >> 8) & 0xf; - pci_index = port & 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].write) - pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to empty PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to unassigned PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index); -#endif -} - -void -pci_type2_write(uint16_t port, uint8_t val, UNUSED(void *priv)) -{ - switch (port) { - case 0xcf8: - pci_func = (val >> 1) & 7; - - if (val & 0xf0) { - pci_log("CF8: Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io |= PCI_IO_ON; - } else { - pci_log("CF8: Dellocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io &= ~PCI_IO_ON; - } - - pci_key = val & 0xf0; - break; - case 0xcfa: - pci_bus = val; - - pci_log("CFA: Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - - /* Evidently, writing here, we should also enable the - configuration space. */ - pci_take_over_io |= PCI_IO_ON; - - /* Mark as enabled. */ - pci_key |= 0x100; - break; - case 0xcfb: - pci_log("Write %02X to port 0CFB\n", val); - pci_set_pmc(val); - break; - - case 0xc000 ... 0xc0ff: - if (pci_take_over_io == 0x00000000) - break; - - pci_type2_write_reg(port, val); - break; - - case 0xc100 ... 0xcfff: - if (!(pci_take_over_io & PCI_IO_ON)) - break; - - pci_type2_write_reg(port, val); - break; - - default: - break; - } -} - -void -pci_type2_writew(uint16_t port, uint16_t val, void *priv) -{ - pci_type2_write(port, val & 0xff, priv); - pci_type2_write(port + 1, val >> 8, priv); -} - -void -pci_type2_writel(uint16_t port, uint32_t val, void *priv) -{ - pci_type2_writew(port, val & 0xffff, priv); - pci_type2_writew(port + 2, val >> 16, priv); -} - -static void -pci_type2_cfb_writel(uint16_t port, uint32_t val, void *priv) -{ - for (uint8_t i = 0; i < 4; i++) { - /* Make sure to have the DWORD write not pass through to PMC if mechanism 1 is in use, - as otherwise, the PCI enable bits clobber it. */ - if (!pci_pmc || ((port + i) != 0x0cfb)) - pci_type2_write(port + i, val >> 8, priv); - } -} - -static uint8_t -pci_type2_read_reg(uint16_t port) -{ - uint8_t slot = 0; - uint8_t ret = 0xff; - - pci_card = (port >> 8) & 0xf; - pci_index = port & 0xff; - - slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; - if (slot != 0xff) { - if (pci_cards[slot].read) - ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from empty PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index); -#endif - - pci_log("Reading %02X at PCI register %02X at bus %02X, card %02X, function %02X\n", ret, pci_index, pci_bus, pci_card, pci_func); - - return ret; -} - -uint8_t -pci_type2_read(uint16_t port, UNUSED(void *priv)) -{ - uint8_t ret = 0xff; - - switch (port) { - case 0xcf8: - ret = pci_key | (pci_func << 1); - break; - case 0xcfa: - ret = pci_bus; - break; - case 0xcfb: - ret = pci_pmc; - break; - - case 0xc000 ... 0xc0ff: - if (pci_take_over_io == 0x00000000) - break; - - ret = pci_type2_read_reg(port); - break; - - case 0xc100 ... 0xcfff: - if (!(pci_take_over_io & PCI_IO_ON)) - break; - - ret = pci_type2_read_reg(port); - break; - - default: - break; - } - - return ret; -} - -uint16_t -pci_type2_readw(uint16_t port, void *priv) -{ - uint16_t ret = pci_type2_read(port, priv); - ret |= ((uint16_t) pci_type2_read(port + 1, priv)) << 8; - - return ret; -} - -uint32_t -pci_type2_readl(uint16_t port, void *priv) -{ - uint32_t ret = pci_type2_readw(port, priv); - ret |= ((uint32_t) pci_type2_readw(port + 2, priv)) << 16; - - return ret; -} - void pci_set_irq_routing(int pci_int, int irq) { @@ -668,250 +136,79 @@ pci_set_mirq_routing(int mirq, int irq) pci_mirqs[mirq].irq_line = irq; } +/* 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). */ void -pci_set_mirq(uint8_t mirq, int level) +pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state) { - uint8_t irq_line = 0; - uint8_t irq_bit; - - if (mirq >= 0xf0) { - irq_line = mirq & 0x0f; - irq_bit = 0x1D; - } else { - if (!pci_mirqs[mirq].enabled) { - pci_log("pci_set_mirq(%02X): MIRQ0 disabled\n", mirq); - return; - } - - if (pci_mirqs[mirq].irq_line > 0x0f) { - pci_log("pci_set_mirq(%02X): IRQ line is disabled\n", mirq); - return; - } - - irq_line = pci_mirqs[mirq].irq_line; - irq_bit = (0x1E + mirq); - } - pci_log("pci_set_mirq(%02X): Using IRQ %i\n", mirq, irq_line); - - if (level && (pci_irq_hold[irq_line] & (1ULL << irq_bit))) { - /* IRQ already held, do nothing. */ - pci_log("pci_set_mirq(%02X): MIRQ is already holding the IRQ\n", mirq); - picintlevel(1 << irq_line); - return; - } - pci_log("pci_set_mirq(%02X): MIRQ not yet holding the IRQ\n", mirq); - - if (!level || !pci_irq_hold[irq_line]) { - pci_log("pci_set_mirq(%02X): Issuing %s-triggered IRQ (%sheld)\n", mirq, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not "); - - /* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */ - if (level) - picintlevel(1 << irq_line); - else - picint(1 << irq_line); - } else if (level && pci_irq_hold[irq_line]) { - pci_log("pci_set_mirq(%02X): IRQ line already being held\n", mirq); - picintlevel(1 << irq_line); - } - - /* If the IRQ is level-triggered, mark that this MIRQ is holding it. */ - if (level) { - pci_log("pci_set_mirq(%02X): Marking that this card is holding the IRQ\n", mirq); - pci_irq_hold[irq_line] |= (1ULL << irq_bit); - } - - pci_log("pci_set_mirq(%02X): Edge-triggered interrupt, not marking\n", mirq); -} - -void -pci_set_irq(uint8_t card, uint8_t pci_int) -{ - uint8_t slot = 0; uint8_t irq_routing = 0; uint8_t pci_int_index = pci_int - PCI_INTA; uint8_t irq_line = 0; - uint8_t level = 0; + uint8_t is_vfio = 0; - if (!last_pci_card) { - pci_log("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); + /* The fast path out an invalid PCI card. */ + if (slot == PCI_CARD_INVALID) return; - } - pci_log("pci_set_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card); - slot = card; - if (slot == 0xff) { - pci_log("pci_set_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int); - return; - } - pci_log("pci_set_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot); - - if (!pci_cards[slot].irq_routing[pci_int_index]) { - pci_log("pci_set_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int); - return; - } - - if (pci_type & PCI_NO_IRQ_STEERING) - irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); - else { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15; - pci_log("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); - - irq_line = pci_irqs[irq_routing]; - level = pci_irq_level[irq_routing]; - } - - if (irq_line > 0x0f) { - pci_log("pci_set_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int); - return; - } else - pci_log("pci_set_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line); - - if (level && (pci_irq_hold[irq_line] & (1ULL << slot))) { - /* IRQ already held, do nothing. */ - pci_log("pci_set_irq(%02X, %02X): Card is already holding the IRQ\n", card, pci_int); - picintlevel(1 << irq_line); - return; - } - pci_log("pci_set_irq(%02X, %02X): Card not yet holding the IRQ\n", card, pci_int); - - if (!level || !pci_irq_hold[irq_line]) { - pci_log("pci_set_irq(%02X, %02X): Issuing %s-triggered IRQ (%sheld)\n", card, pci_int, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not "); - - /* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */ - if (level) - picintlevel(1 << irq_line); - else - picint(1 << irq_line); - } else if (level && pci_irq_hold[irq_line]) { - pci_log("pci_set_irq(%02X, %02X): IRQ line already being held\n", card, pci_int); - picintlevel(1 << irq_line); - } - - /* If the IRQ is level-triggered, mark that this card is holding it. */ - if (level) { - pci_log("pci_set_irq(%02X, %02X): Marking that this card is holding the IRQ\n", card, pci_int); - pci_irq_hold[irq_line] |= (1ULL << slot); - } else { - pci_log("pci_set_irq(%02X, %02X): Edge-triggered interrupt, not marking\n", card, pci_int); - } -} - -void -pci_clear_mirq(uint8_t mirq, int level) -{ - uint8_t irq_line = 0; - uint8_t irq_bit; - - if (mirq >= 0xf0) { - irq_line = mirq & 0x0f; - irq_bit = 0x1D; - } else { - if (mirq > 1) { - pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq); + switch (slot) { + default: return; - } - if (!pci_mirqs[mirq].enabled) { - pci_log("pci_clear_mirq(%02X): MIRQ0 disabled\n", mirq); - return; - } + case 0x00 ... PCI_CARD_MAX: + /* PCI card. */ + if (!last_pci_card) + return; - if (pci_mirqs[mirq].irq_line > 0x0f) { - pci_log("pci_clear_mirq(%02X): IRQ line is disabled\n", mirq); - return; - } + if (pci_flags & FLAG_NO_IRQ_STEERING) + irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); + else { + irq_routing = pci_cards[slot].irq_routing[pci_int_index]; - irq_line = pci_mirqs[mirq].irq_line; - irq_bit = (0x1E + mirq); + switch (irq_routing) { + default: + case 0x00: + return; + + case 0x01 ... PCI_IRQS_NUM: + is_vfio = pci_cards[slot].type & PCI_CARD_VFIO; + irq_routing = (irq_routing - PCI_INTA) & PCI_IRQ_MAX; + + irq_line = pci_irqs[irq_routing]; + /* Ignore what was provided to us as a parameter and override it with whatever + the chipset is set to. */ + level = !!pci_irq_level[irq_routing]; + if (level && is_vfio) + level--; + break; + + /* Sometimes, PCI devices are mapped to direct IRQ's. */ + case (PCI_DIRQ_BASE | 0x00) ... (PCI_DIRQ_BASE | PCI_DIRQ_MAX): + /* Direct IRQ line, always edge-triggered. */ + irq_line = slot & PCI_IRQ_MAX; + break; + } + } + break; + case (PCI_MIRQ_BASE | 0x00) ... (PCI_MIRQ_BASE | PCI_MIRQ_MAX): + /* MIRQ */ + slot &= PCI_MIRQ_MAX; + + if (!pci_mirqs[slot].enabled) + return; + + irq_line = pci_mirqs[slot].irq_line; + break; + case (PCI_DIRQ_BASE | 0x00) ... (PCI_DIRQ_BASE | PCI_DIRQ_MAX): + /* Direct IRQ line (RichardG's ACPI workaround, may no longer be needed). */ + irq_line = slot & PCI_IRQ_MAX; + break; } - pci_log("pci_clear_mirq(%02X): Using IRQ %i\n", mirq, irq_line); - if (level && !(pci_irq_hold[irq_line] & (1ULL << irq_bit))) { - /* IRQ not held, do nothing. */ - pci_log("pci_clear_mirq(%02X): MIRQ is not holding the IRQ\n", mirq); + if (irq_line > PCI_IRQ_MAX) return; - } - if (level) { - pci_log("pci_clear_mirq(%02X): Releasing this MIRQ's hold on the IRQ\n", mirq); - pci_irq_hold[irq_line] &= ~(1 << irq_bit); - - if (!pci_irq_hold[irq_line]) { - pci_log("pci_clear_mirq(%02X): IRQ no longer held by any card, clearing it\n", mirq); - picintc(1 << irq_line); - } else { - pci_log("pci_clear_mirq(%02X): IRQ is still being held\n", mirq); - } - } else { - pci_log("pci_clear_mirq(%02X): Clearing edge-triggered interrupt\n", mirq); - picintc(1 << irq_line); - } -} - -void -pci_clear_irq(uint8_t card, uint8_t pci_int) -{ - uint8_t slot = 0; - uint8_t irq_routing = 0; - uint8_t pci_int_index = pci_int - PCI_INTA; - uint8_t irq_line = 0; - uint8_t level = 0; - - if (!last_pci_card) { - // pci_log("pci_clear_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); - return; - } - // pci_log("pci_clear_irq(%02X, %02X): %i PCI slots\n", card, pci_int, last_pci_card); - - slot = card; - if (slot == 0xff) { - // pci_log("pci_clear_irq(%02X, %02X): Card is not on a PCI slot (how are we even here?!)\n", card, pci_int); - return; - } - // pci_log("pci_clear_irq(%02X, %02X): Card is on PCI slot %02X\n", card, pci_int, slot); - - if (!pci_cards[slot].irq_routing[pci_int_index]) { - // pci_log("pci_clear_irq(%02X, %02X): No IRQ routing for this slot and INT pin combination\n", card, pci_int); - return; - } - - if (pci_type & PCI_NO_IRQ_STEERING) - irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); - else { - irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15; - // pci_log("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing); - - irq_line = pci_irqs[irq_routing]; - level = pci_irq_level[irq_routing]; - } - - if (irq_line > 0x0f) { - // pci_log("pci_clear_irq(%02X, %02X): IRQ line is disabled\n", card, pci_int); - return; - } - - // pci_log("pci_clear_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line); - - if (level && !(pci_irq_hold[irq_line] & (1ULL << slot))) { - /* IRQ not held, do nothing. */ - // pci_log("pci_clear_irq(%02X, %02X): Card is not holding the IRQ\n", card, pci_int); - return; - } - - if (level) { - // pci_log("pci_clear_irq(%02X, %02X): Releasing this card's hold on the IRQ\n", card, pci_int); - pci_irq_hold[irq_line] &= ~(1 << slot); - - if (!pci_irq_hold[irq_line]) { - // pci_log("pci_clear_irq(%02X, %02X): IRQ no longer held by any card, clearing it\n", card, pci_int); - picintc(1 << irq_line); - } // else { - // pci_log("pci_clear_irq(%02X, %02X): IRQ is still being held\n", card, pci_int); - // } - } else { - // pci_log("pci_clear_irq(%02X, %02X): Clearing edge-triggered interrupt\n", card, pci_int); - picintc(1 << irq_line); - } + picint_common(1 << irq_line, level, set, irq_state); } uint8_t @@ -920,12 +217,123 @@ pci_get_int(uint8_t slot, uint8_t pci_int) return pci_cards[slot].irq_routing[pci_int - PCI_INTA]; } +static void +pci_clear_slot(int card) +{ + pci_card_to_slot_mapping[pci_cards[card].bus][pci_cards[card].id] = PCI_CARD_INVALID; + + pci_cards[card].id = 0xff; + pci_cards[card].type = 0xff; + + for (uint8_t i = 0; i < 4; i++) + pci_cards[card].irq_routing[i] = 0; + + pci_cards[card].read = NULL; + pci_cards[card].write = NULL; + pci_cards[card].priv = NULL; +} + +/* Relocate a PCI device to a new slot, required for the configurable + IDSEL's of ALi M1543(c). */ +void +pci_relocate_slot(int type, int new_slot) +{ + int card = -1; + int old_slot; + uint8_t mapping; + + if ((new_slot < 0) || (new_slot > 31)) + return; + + for (uint8_t i = 0; i < PCI_CARDS_NUM; i++) { + if ((pci_cards[i].bus == 0) && (pci_cards[i].type == type)) { + card = i; + break; + } + } + + if (card == -1) + return; + + old_slot = pci_cards[card].id; + pci_cards[card].id = new_slot; + mapping = pci_card_to_slot_mapping[0][old_slot]; + pci_card_to_slot_mapping[0][old_slot] = PCI_CARD_INVALID; + pci_card_to_slot_mapping[0][new_slot] = mapping; +} + +/* Write PCI enable/disable key, split for the ALi M1435. */ +void +pci_key_write(uint8_t val) +{ + pci_key = val & 0xf0; + + if (pci_key) + pci_flags |= FLAG_CONFIG_IO_ON; + else + pci_flags &= ~FLAG_CONFIG_IO_ON; +} + +static void +pci_io_handlers(int set) +{ + io_handler(set, 0x0cf8, 4, pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); + + if (pci_flags & FLAG_MECHANISM_1) + io_handler(set, 0x0cfc, 4, pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); + + if (pci_flags & FLAG_MECHANISM_2) { + if (set && pci_key) + pci_flags |= FLAG_CONFIG_IO_ON; + else + pci_flags &= ~FLAG_CONFIG_IO_ON; + } +} + +/* Set PMC (ie. change PCI configuration mechanism), 0 = #2, 1 = #1. */ +void +pci_set_pmc(uint8_t pmc) +{ + pci_log("pci_set_pmc(%02X)\n", pmc); + + pci_io_handlers(0); + + pci_flags &= ~FLAG_MECHANISM_MASK; + pci_flags |= (FLAG_MECHANISM_1 + !(pmc & 0x01)); + + pci_io_handlers(1); + + pci_pmc = (pmc & 0x01); +} + +static void +pci_reg_write(uint16_t port, uint8_t val) +{ + uint8_t slot = 0; + + if (port >= 0xc000) { + pci_card = (port >> 8) & 0xf; + pci_index = port & 0xfc; + } + + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != PCI_CARD_INVALID) { + if (pci_cards[slot].write) + pci_cards[slot].write(pci_func, pci_index | (port & 0x03), val, pci_cards[slot].priv); + } + pci_log("PCI: [WB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X = %02X\n", + (port >= 0xc000) ? 2 : 1, slot, + (slot == PCI_CARD_INVALID) ? "non-existent" : (pci_cards[slot].write ? "used" : "unused"), + pci_card, pci_bus, pci_func, pci_index | (port & 0x03), val); +} + static void pci_reset_regs(void) { pci_index = pci_card = pci_func = pci_bus = pci_key = 0; + pci_enable = 0x00000000; - pci_take_over_io &= ~PCI_IO_ON; + pci_flags &= ~(FLAG_CONFIG_IO_ON | FLAG_CONFIG_M1_IO_ON); } void @@ -940,7 +348,7 @@ pci_reset_hard(void) { pci_reset_regs(); - for (uint8_t i = 0; i < 16; i++) { + for (uint8_t i = 0; i < PCI_IRQS_NUM; i++) { if (pci_irq_hold[i]) { pci_irq_hold[i] = 0; @@ -954,68 +362,16 @@ pci_reset_hard(void) void pci_reset(void) { - if (pci_switch) { + if (pci_flags & FLAG_MECHANISM_SWITCH) { pci_log("pci_reset(): Switchable configuration mechanism\n"); - pci_pmc = 0x00; - - io_removehandler(0x0cf8, 1, - NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); - io_removehandler(0x0cfc, 4, - pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - io_removehandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_removehandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); + pci_set_pmc(0x00); } pci_reset_hard(); } static void -pci_slots_clear(void) -{ - uint8_t i; - - last_pci_card = last_normal_pci_card = 0; - last_pci_bus = 1; - - for (i = 0; i < 32; i++) - pci_clear_slot(i); - - i = 0; - do { - for (uint8_t j = 0; j < 32; j++) - pci_card_to_slot_mapping[i][j] = 0xff; - pci_bus_number_to_index_mapping[i] = 0xff; - } while (i++ < 0xff); - - pci_bus_number_to_index_mapping[0] = 0; /* always map bus 0 to index 0 */ -} - -uint32_t -trc_readl(UNUSED(uint16_t port), UNUSED(void *priv)) -{ - return 0xffffffff; -} - -uint16_t -trc_readw(UNUSED(uint16_t port), UNUSED(void *priv)) -{ - return 0xffff; -} - -uint8_t -trc_read(UNUSED(uint16_t port), UNUSED(void *priv)) -{ - return trc_reg & 0xfb; -} - -static void -trc_reset(uint8_t val) +pci_trc_reset(uint8_t val) { if (val & 2) { dma_reset(); @@ -1037,110 +393,247 @@ trc_reset(uint8_t val) } void -trc_writel(UNUSED(uint16_t port), UNUSED(uint32_t val), UNUSED(void *priv)) +pci_write(uint16_t port, uint8_t val, UNUSED(void *priv)) { - // + pci_log("PCI: [WB] Mechanism #%i port %04X = %02X\n", ((port >= 0xcfc) && (port <= 0xcff)) ? 1 : 2, port, val); + + switch (port) { + case 0xcf8: + if (pci_flags & FLAG_MECHANISM_2) { + pci_func = (val >> 1) & 7; + pci_key_write(val); + + pci_log("PCI: Mechanism #2 CF8: %sllocating ports %04X-%04X...\n", (pci_flags & FLAG_CONFIG_IO_ON) ? "A" : "Dea", + pci_base, pci_base + pci_size - 1); + } + break; + case 0xcf9: + if (!(pci_trc_reg & 4) && (val & 4)) + pci_trc_reset(val); + + pci_trc_reg = val & 0xfd; + + if (val & 2) + pci_trc_reg &= 0xfb; + break; + case 0xcfa: + if (pci_flags & FLAG_MECHANISM_2) + pci_bus = val; + break; + case 0xcfb: + if (pci_flags & FLAG_MECHANISM_SWITCH) + pci_set_pmc(val); + break; + + case 0xcfc: + case 0xcfd: + case 0xcfe: + case 0xcff: + if ((pci_flags & FLAG_MECHANISM_1) && (pci_flags & FLAG_CONFIG_M1_IO_ON)) + pci_reg_write(port, val); + break; + + case 0xc000 ... 0xc0ff: + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & (FLAG_CONFIG_IO_ON | FLAG_CONFIG_DEV0_IO_ON))) + pci_reg_write(port, val); + break; + + case 0xc100 ... 0xcfff: + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & FLAG_CONFIG_IO_ON)) + pci_reg_write(port, val); + break; + } } void -trc_writew(UNUSED(uint16_t port), UNUSED(uint16_t val), UNUSED(void *priv)) +pci_writew(uint16_t port, uint16_t val, UNUSED(void *priv)) { - // + if (port & 0x0001) { + /* Non-aligned access, split into two byte accesses. */ + pci_write(port, val & 0xff, priv); + pci_write(port + 1, val >> 8, priv); + } else { + /* Aligned access, still split because we cheat. */ + switch (port) { + case 0xcfc: + case 0xcfe: + case 0xc000 ... 0xcffe: + pci_write(port, val & 0xff, priv); + pci_write(port + 1, val >> 8, priv); + break; + } + } } void -trc_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) +pci_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) { - pci_log("TRC Write: %02X\n", val); + if (port & 0x0003) { + /* Non-aligned access, split into two word accesses. */ + pci_writew(port, val & 0xffff, priv); + pci_writew(port + 2, val >> 16, priv); + } else { + /* Aligned access. */ + switch (port) { + case 0xcf8: + /* No split here, actual 32-bit access. */ + if (pci_flags & FLAG_MECHANISM_1) { + pci_log("PCI: [WL] Mechanism #1 port 0CF8 = %08X\n", val); - if (!(trc_reg & 4) && (val & 4)) - trc_reset(val); + pci_index = val & 0xff; + pci_func = (val >> 8) & 7; + pci_card = (val >> 11) & 31; + pci_bus = (val >> 16) & 0xff; + pci_enable = (val & PCI_ENABLED); - trc_reg = val & 0xfd; - - if (val & 2) - trc_reg &= 0xfb; + if (pci_enable) + pci_flags |= FLAG_CONFIG_M1_IO_ON; + else + pci_flags &= ~FLAG_CONFIG_M1_IO_ON; + break; + } + break; + case 0xcfc: + case 0xc000 ... 0xcffc: + /* Still split because we cheat. */ + pci_writew(port, val & 0xffff, priv); + pci_writew(port + 2, val >> 16, priv); + break; + } + } } -void -trc_init(void) +static uint8_t +pci_reg_read(uint16_t port) { - trc_reg = 0; + uint8_t slot = 0; + uint8_t ret = 0xff; - io_sethandler(0x0cf9, 0x0001, - trc_read, trc_readw, trc_readl, trc_write, trc_writew, trc_writel, NULL); -} - -void -pci_init(int type) -{ - int c; - - pci_base = 0xc000; - pci_size = 0x1000; - - pci_slots_clear(); - - pci_reset_hard(); - - trc_init(); - - pci_type = type; - pci_switch = !!(type & PCI_CAN_SWITCH_TYPE); - - if (pci_switch) { - pci_log("PCI: Switchable configuration mechanism\n"); - pci_pmc = 0x00; - - io_sethandler(0x0cfb, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, pci_type2_cfb_writel, NULL); + if (port >= 0xc000) { + pci_card = (port >> 8) & 0xf; + pci_index = port & 0xfc; } - if (type & PCI_NO_IRQ_STEERING) { - pic_elcr_io_handler(0); - pic_elcr_set_enabled(0); - } else { - pic_elcr_io_handler(1); - pic_elcr_set_enabled(1); + slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; + if (slot != PCI_CARD_INVALID) { + if (pci_cards[slot].read) + ret = pci_cards[slot].read(pci_func, pci_index | (port & 0x03), pci_cards[slot].priv); + } + pci_log("PCI: [RB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X = %02X\n", + (port >= 0xc000) ? 2 : 1, slot, + (slot == PCI_CARD_INVALID) ? "non-existent" : (pci_cards[slot].read ? "used" : "unused"), + pci_card, pci_bus, pci_func, pci_index | (port & 0x03), ret); + + return ret; +} + +uint8_t +pci_read(uint16_t port, UNUSED(void *priv)) +{ + uint8_t ret = 0xff; + + switch (port) { + case 0xcf8: + if (pci_flags & FLAG_MECHANISM_2) + ret = pci_key | (pci_func << 1); + break; + case 0xcf9: + ret = pci_trc_reg & 0xfb; + break; + case 0xcfa: + if (pci_flags & FLAG_MECHANISM_2) + ret = pci_bus; + break; + case 0xcfb: + if (pci_flags & FLAG_MECHANISM_SWITCH) + ret = pci_pmc; + break; + + case 0xcfc: + case 0xcfd: + case 0xcfe: + case 0xcff: + if ((pci_flags & FLAG_MECHANISM_1) && (pci_flags & FLAG_CONFIG_M1_IO_ON)) + ret = pci_reg_read(port); + break; + + case 0xc000 ... 0xc0ff: + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & (FLAG_CONFIG_IO_ON | FLAG_CONFIG_DEV0_IO_ON))) + ret = pci_reg_read(port); + break; + + case 0xc100 ... 0xcfff: + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & FLAG_CONFIG_IO_ON)) + ret = pci_reg_read(port); + break; + + default: + break; } - pci_take_over_io = 0x00000000; + pci_log("PCI: [RB] Mechanism #%i port %04X = %02X\n", ((port >= 0xcfc) && (port <= 0xcff)) ? 1 : 2, port, ret); - if ((type & PCI_CONFIG_TYPE_MASK) == PCI_CONFIG_TYPE_1) { - pci_log("PCI: Configuration mechanism #1\n"); - io_sethandler(0x0cf8, 1, - NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); - io_sethandler(0x0cfc, 4, - pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); - pci_pmc = 1; + return ret; +} + +uint16_t +pci_readw(uint16_t port, UNUSED(void *priv)) +{ + uint16_t ret = 0xffff; + + if (port & 0x0001) { + /* Non-aligned access, split into two byte accesses. */ + ret = pci_read(port, priv); + ret |= ((uint16_t) pci_read(port + 1, priv)) << 8; } else { - pci_log("PCI: Configuration mechanism #2\n"); - io_sethandler(0x0cf8, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - io_sethandler(0x0cfa, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); - pci_pmc = 0; - - if (type & PCI_ALWAYS_EXPOSE_DEV0) { - pci_log("PCI: Always expose device 0\n"); - pci_base = 0xc100; - pci_size = 0x0f00; - - pci_take_over_io |= PCI_IO_DEV0; + /* Aligned access, still split because we cheat. */ + switch (port) { + case 0xcfc: + case 0xcfe: + case 0xc000 ... 0xcffe: + ret = pci_read(port, priv); + ret |= ((uint16_t) pci_read(port + 1, priv)) << 8; + break; } } - for (c = 0; c < 4; c++) { - pci_irqs[c] = PCI_IRQ_DISABLED; - pci_irq_level[c] = (type & PCI_NO_IRQ_STEERING) ? 0 : 1; + return ret; +} + +uint32_t +pci_readl(uint16_t port, UNUSED(void *priv)) +{ + uint32_t ret = 0xffffffff; + + if (port & 0x0003) { + /* Non-aligned access, split into two word accesses. */ + ret = pci_readw(port, priv); + ret |= ((uint32_t) pci_readw(port + 2, priv)) << 16; + } else { + /* Aligned access. */ + switch (port) { + case 0xcf8: + /* No split here, actual 32-bit access. */ + if (pci_flags & FLAG_MECHANISM_1) { + ret = pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16); + if (pci_flags & FLAG_CONFIG_IO_ON) + ret |= PCI_ENABLED; + + pci_log("PCI: [RL] Mechanism #1 port 0CF8 = %08X\n", ret); + + return ret; + } + break; + case 0xcfc: + case 0xc000 ... 0xcffc: + /* Still split because we cheat. */ + ret = pci_readw(port, priv); + ret |= ((uint32_t) pci_readw(port + 2, priv)) << 16; + break; + } } - for (c = 0; c < 3; c++) { - pci_mirqs[c].enabled = 0; - pci_mirqs[c].irq_line = PCI_IRQ_DISABLED; - } - - pic_set_pci_flag(1); + return ret; } uint8_t @@ -1155,19 +648,13 @@ pci_remap_bus(uint8_t bus_index, uint8_t bus_number) uint8_t i = 1; do { if (pci_bus_number_to_index_mapping[i] == bus_index) - pci_bus_number_to_index_mapping[i] = 0xff; + pci_bus_number_to_index_mapping[i] = PCI_BUS_INVALID; } while (i++ < 0xff); if ((bus_number > 0) && (bus_number < 0xff)) pci_bus_number_to_index_mapping[bus_number] = bus_index; } -void -pci_register_slot(int card, int type, int inta, int intb, int intc, int intd) -{ - pci_register_bus_slot(0, card, type, inta, intb, intc, intd); -} - void pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc, int intd) { @@ -1187,73 +674,259 @@ pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc, pci_log("pci_register_slot(): pci_cards[%i].bus = %02X; .id = %02X\n", last_pci_card, bus, card); - if (type == PCI_CARD_NORMAL) - last_normal_pci_card = last_pci_card; + if (type == PCI_CARD_NORMAL) { + last_normal_pci_card++; + /* This is needed to know at what position to add the bridge. */ + last_normal_pci_card_id = last_pci_card; + } + last_pci_card++; } -uint8_t +static uint8_t pci_find_slot(uint8_t add_type, uint8_t ignore_slot) { const pci_card_t *dev; - uint8_t ret = 0xff; + /* Is the device being added with a strict slot type matching requirement? */ + uint8_t strict = (add_type & PCI_ADD_STRICT); + /* The actual type of the device being added, with the strip flag, if any, + masked. */ + uint8_t masked_add_type = (add_type & PCI_ADD_MASK); + /* Is the device being added normal, ie. without the possibility of ever + being used as an on-board device? */ + uint8_t normal_add_type = (masked_add_type >= PCI_CARD_NORMAL); + uint8_t match; + uint8_t normal; + uint8_t empty; + uint8_t process; + uint8_t ret = PCI_CARD_INVALID; - for (uint8_t i = 0; i < last_pci_card; i++) { + /* Iterate i until we have either exhausted all the slot or the value of + ret has changed to something other than PCI_CARD_INVALID. */ + for (uint8_t i = 0; (ret == PCI_CARD_INVALID) && (i < last_pci_card); i++) { dev = &pci_cards[i]; - if (!dev->read && !dev->write && ((ignore_slot == 0xff) || (i != ignore_slot))) { - if (add_type & PCI_ADD_STRICT) { - if (dev->type == (add_type & 0x7f)) { - ret = i; - break; - } - } else { - if (((dev->type == PCI_CARD_NORMAL) && ((add_type & 0x7f) >= PCI_ADD_NORMAL)) || (dev->type == (add_type & 0x7f))) { - ret = i; - break; - } - } - } + /* Is the slot we are looking at of the exact same type as the device being + added? */ + match = (dev->type == masked_add_type); + /* Is the slot we are looking at a normal slot (ie. not an on-board chip)? */ + normal = (dev->type == PCI_CARD_NORMAL); + /* Is the slot we are looking at empty? */ + empty = !dev->read && !dev->write; + /* Should we process this slot, ie. were we told to ignore it, if any at all? */ + process = (ignore_slot == PCI_IGNORE_NO_SLOT) || (i != ignore_slot); + + /* This condition is now refactored and made to be easily human-readable. */ + if (empty && process && (match || (!strict && normal && normal_add_type))) + ret = i; } return ret; } -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) +/* Add a PCI card. */ +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) { - pci_card_t *dev; - uint8_t i; - uint8_t j; + pci_card_desc_t *dev; - if (add_type < PCI_ADD_AGP) - pci_log("pci_add_card(): Adding PCI CARD at specific slot %02X [SPECIFIC]\n", add_type); + pci_log("pci_add_card(): PCI card #%02i: type = %i\n", next_pci_card, add_type); - if (!last_pci_card) { - pci_log("pci_add_card(): Adding PCI CARD failed (no PCI slots) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_AGP) ? "AGP" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))))); - return 0xff; - } - - /* First, find the next available slot. */ - i = pci_find_slot(add_type, 0xff); - - if (i != 0xff) { - dev = &pci_cards[i]; - j = pci_find_slot(add_type, i); - - if (!(pci_type & PCI_NO_BRIDGES) && (dev->type == PCI_CARD_NORMAL) && (add_type != PCI_ADD_BRIDGE) && (j == 0xff)) { - pci_log("pci_add_card(): Reached last NORMAL slot, adding bridge to pci_cards[%i]\n", i); - device_add_inst(&dec21150_device, last_pci_bus); - i = pci_find_slot(add_type, 0xff); - dev = &pci_cards[i]; - } + if (next_pci_card < PCI_CARDS_NUM) { + dev = &pci_card_descs[next_pci_card]; + dev->type = add_type; dev->read = read; dev->write = write; dev->priv = priv; - pci_log("pci_add_card(): Adding PCI CARD to pci_cards[%i] (bus %02X slot %02X) [%s]\n", i, dev->bus, dev->id, (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_AGP) ? "AGP" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))))); - return i; + dev->slot = slot; + + *(dev->slot) = PCI_CARD_INVALID; + + next_pci_card++; + if (add_type == PCI_ADD_NORMAL) + normal_pci_cards++; + } +} + +static void +pci_clear_card(int pci_card) +{ + pci_card_desc_t *dev; + + if (next_pci_card < PCI_CARDS_NUM) { + dev = &pci_card_descs[next_pci_card]; + + memset(dev, 0x00, sizeof(pci_card_desc_t)); + } +} + +static uint8_t +pci_register_card(int pci_card) +{ + pci_card_desc_t *dev; + pci_card_t *card; + uint8_t i; + uint8_t ret = PCI_CARD_INVALID; + + if (pci_card < PCI_CARDS_NUM) { + dev = &pci_card_descs[pci_card]; + + if (last_pci_card) { + /* First, find the next available slot. */ + i = pci_find_slot(dev->type, 0xff); + + if (i != PCI_CARD_INVALID) { + card = &pci_cards[i]; + card->read = dev->read; + card->write = dev->write; + card->priv = dev->priv; + card->type |= (dev->type & PCI_CARD_VFIO); + + *(dev->slot) = i; + + ret = i; + } + } + + pci_clear_card(pci_card); } - return 0xff; + return ret; +} + +/* Add an instance of the PCI bridge. */ +void +pci_add_bridge(uint8_t agp, 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) +{ + pci_card_t *card; + uint8_t bridge_slot = agp ? pci_find_slot(PCI_ADD_AGPBRIDGE, 0xff) : last_normal_pci_card_id; + + card = &pci_cards[bridge_slot]; + card->read = read; + card->write = write; + card->priv = priv; + + *slot = bridge_slot; +} + +/* Register the cards that have been added into slots. */ +void +pci_register_cards(void) +{ + uint8_t i; + uint8_t normal; +#ifdef ENABLE_PCI_LOG + uint8_t type; + uint8_t *slot; +#endif + + next_normal_pci_card = 0; + + if (next_pci_card > 0) { + for (i = 0; i < next_pci_card; i++) { +#ifdef ENABLE_PCI_LOG + type = pci_card_descs[i].type; + slot = pci_card_descs[i].slot; +#endif + normal = (pci_card_descs[i].type == PCI_CARD_NORMAL); + + /* If this is a normal card, increase the next normal card index. */ + if (normal) + next_normal_pci_card++; + + /* If this is a normal card and the next one is going to be beyond the last slot, + add the bridge. */ + if (normal && (next_normal_pci_card >= last_normal_pci_card) && + (normal_pci_cards > last_normal_pci_card) && !(pci_flags & FLAG_NO_BRIDGES)) + device_add_inst(&dec21150_device, last_pci_bus); + + pci_register_card(i); + pci_log("pci_register_cards(): PCI card #%02i: type = %02X, pci device = %02X:%02X\n", + i, type, pci_cards[*slot].bus, pci_cards[*slot].id); + } + } + + next_pci_card = 0; + normal_pci_cards = 0; + + next_normal_pci_card = 0; +} + +static void +pci_slots_clear(void) +{ + uint8_t i; + + last_pci_card = last_normal_pci_card = 0; + last_normal_pci_card = 0; + last_pci_bus = 1; + + next_pci_card = 0; + normal_pci_cards = 0; + + next_normal_pci_card = 0; + + for (i = 0; i < PCI_CARDS_NUM; i++) + pci_clear_slot(i); + + i = 0; + do { + for (uint8_t j = 0; j < PCI_CARDS_NUM; j++) + pci_card_to_slot_mapping[i][j] = PCI_CARD_INVALID; + pci_bus_number_to_index_mapping[i] = PCI_BUS_INVALID; + } while (i++ < 0xff); + + pci_bus_number_to_index_mapping[0] = 0; /* always map bus 0 to index 0 */ +} + +void +pci_init(int flags) +{ + int c; + + pci_base = 0xc000; + pci_size = 0x1000; + + pci_slots_clear(); + + pci_reset_hard(); + + pci_trc_reg = 0; + pci_flags = flags; + + if (pci_flags & FLAG_NO_IRQ_STEERING) { + pic_elcr_io_handler(0); + pic_elcr_set_enabled(0); + } else { + pic_elcr_io_handler(1); + pic_elcr_set_enabled(1); + } + + pci_pmc = (pci_flags & FLAG_MECHANISM_1) ? 0x01 : 0x00; + + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & FLAG_CONFIG_DEV0_IO_ON)) { + pci_log("PCI: Always expose device 0\n"); + pci_base = 0xc100; + pci_size = 0x0f00; + } + + if (pci_flags & FLAG_MECHANISM_SWITCH) { + pci_log("PCI: Switchable configuration mechanism\n"); + pci_set_pmc(pci_pmc); + } else + pci_io_handlers(1); + + for (c = 0; c < PCI_IRQS_NUM; c++) { + pci_irqs[c] = PCI_IRQ_DISABLED; + pci_irq_level[c] = (pci_flags & FLAG_NO_IRQ_STEERING) ? 0 : 1; + } + + for (c = 0; c < PCI_MIRQS_NUM; c++) { + pci_mirqs[c].enabled = 0; + pci_mirqs[c].irq_line = PCI_IRQ_DISABLED; + } + + pic_set_pci_flag(1); } diff --git a/src/pci_dummy.c b/src/pci_dummy.c index 8ed6f9f30..704f85d8c 100644 --- a/src/pci_dummy.c +++ b/src/pci_dummy.c @@ -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 */ @@ -211,9 +218,7 @@ pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv) case 0x10: /* PCI_BAR */ val &= 0xe0; /* 0xe0 acc to RTL DS */ -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x11: /* PCI_BAR */ /* Remove old I/O. */ @@ -236,7 +241,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 +278,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; } diff --git a/src/pic.c b/src/pic.c index 6173291b4..56a6a927f 100644 --- a/src/pic.c +++ b/src/pic.c @@ -51,20 +51,23 @@ 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 pic_update_request(pic_t *dev, int irq); +static void pic_update_irr(pic_t *dev, uint16_t num); -static void (*update_pending)(void); +static void pic_cascade(int set); #ifdef ENABLE_PIC_LOG int pic_do_log = ENABLE_PIC_LOG; @@ -223,37 +226,29 @@ 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; + if (!(pic.flags & PIC_FREEZE)) + pic.int_pending = (find_best_interrupt(&pic) != -1); } static __inline void pic_update_pending_at(void) { - pic2.int_pending = (find_best_interrupt(&pic2) != -1); + if (!(pic2.flags & PIC_FREEZE)) { + 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); + if (!(pic.flags & PIC_FREEZE)) + pic.int_pending = (find_best_interrupt(&pic) != -1); + + pic_log("pic_update_pending_at(): dev->int_pending = %i (%i)\n", pic.int_pending, !!(pic.flags & PIC_FREEZE)); } 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 +263,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); @@ -320,14 +320,25 @@ picint_is_level(int irq) } static void -pic_acknowledge(pic_t *dev) +pic_acknowledge(pic_t *dev, int poll) { int pic_int = dev->interrupt & 7; 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; + + if (!poll) { + 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 @@ -364,6 +375,7 @@ pic_action(pic_t *dev, uint8_t irq, uint8_t eoi, uint8_t rotate) if (rotate) dev->priority = (irq + 1) & 7; + pic_update_request(dev, irq); update_pending(); } } @@ -403,13 +415,10 @@ 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): %04X\n", enabled_latches, latched_irqs & 0x1002); - if (kbd_latch && (latched_irqs & 0x0002)) - picintc(0x0002); - - if (mouse_latch && (latched_irqs & 0x1000)) - picintc(0x1000); + if (latched_irqs & 0x1002) + picintc(latched_irqs & 0x1002); /* Return FF - we just lower IRQ 1 and IRQ 12. */ return ret; @@ -433,29 +442,24 @@ 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. */ if (dev->int_pending) { dev->data_bus = 0x80 | (dev->interrupt & 7); - pic_acknowledge(dev); + pic_acknowledge(dev, 1); dev->int_pending = 0; - update_pending(); } else dev->data_bus = 0x00; dev->ocw3 &= ~0x04; + dev->flags &= ~PIC_FREEZE; /* Freeze the interrupt until the poll is over. */ + pic_update_irr(dev, 0x00ff); /* Update IRR, just in case anything came while frozen. */ + update_pending(); } else if (addr & 0x0001) dev->data_bus = dev->imr; 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 +474,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 +499,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 +519,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->flags = PIC_MASTER_CLEAR; + dev->irr = 0x00; + dev->edge_lines = 0x00; + dev->irq_latch = 0x00; + 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 +536,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 { @@ -549,12 +563,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); @@ -563,12 +580,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); @@ -580,11 +600,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); @@ -621,30 +641,120 @@ 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)); + + 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); + + 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)); + + 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)); + + 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)); + + return ret; +} + +static void +pic_update_request(pic_t *dev, int irq) +{ + dev->irr &= ~(1 << irq); + + if (!(dev->flags & PIC_FREEZE)) + dev->irr |= (pic_irq_request_nor(dev, irq) << irq); +} + +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); + } +} + +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) { @@ -655,77 +765,40 @@ 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)) - update_pending(); + 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); + } + + 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 @@ -737,16 +810,13 @@ 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); + pic_acknowledge(dev, 0); if (slave) dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase); else @@ -778,6 +848,9 @@ pic_irq_ack_read(pic_t *dev, int phase) return dev->data_bus; } +/* 808x: Update the requests for all interrupts since any of them + could have arrived during the freeze. */ + uint8_t pic_irq_ack(void) { @@ -791,7 +864,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); @@ -799,8 +872,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_irr(&pic2, 0x00ff); pic2.interrupt = 0x17; + } + pic.flags &= ~(PIC_SLAVE_PENDING | PIC_FREEZE); + pic_update_irr(&pic, 0x00ff); pic.interrupt = 0x17; update_pending(); } @@ -808,6 +886,9 @@ pic_irq_ack(void) return ret; } +/* 286+: Only update the request for the pending interrupt as it is + impossible that any other interrupt has arrived during the + freeze. */ int picinterrupt(void) { @@ -821,7 +902,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)) @@ -833,8 +914,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(); } diff --git a/src/pit.c b/src/pit.c index 648e0018b..de7cedc49 100644 --- a/src/pit.c +++ b/src/pit.c @@ -1014,7 +1014,11 @@ pit_set_clock(int clock) PITCONSTD = (cpuclock / 1193182.0); PITCONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32)); +#ifdef IMPRECISE_CGACONST CGACONST = (uint64_t) ((cpuclock / (19687503.0 / 11.0)) * (double) (1ULL << 32)); +#else + CGACONST = (uint64_t) ((cpuclock / (157500000.0 / 88.0)) * (double) (1ULL << 32)); +#endif ISACONST = (uint64_t) ((cpuclock / (double) cpu_isa_speed) * (double) (1ULL << 32)); xt_cpu_multi = 1ULL; } else { @@ -1064,7 +1068,11 @@ pit_set_clock(int clock) } else if (cpuclock != 14318184.0) { PITCONSTD = (cpuclock / 1193182.0); PITCONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32)); +#ifdef IMPRECISE_CGACONST CGACONST = (uint64_t) ((cpuclock / (19687503.0 / 11.0)) * (double) (1ULL << 32)); +#else + CGACONST = (uint64_t) ((cpuclock / (157500000.0 / 88.0)) * (double) (1ULL << 32)); +#endif } ISACONST = (1ULL << 32ULL); @@ -1074,7 +1082,11 @@ pit_set_clock(int clock) /* Delay for empty I/O ports. */ io_delay = (int) round(((double) cpu_s->rspeed) / 3000000.0); +#ifdef WRONG_MDACONST MDACONST = (uint64_t) (cpuclock / 2032125.0 * (double) (1ULL << 32)); +#else + MDACONST = (uint64_t) (cpuclock / (16257000.0 / 9.0) * (double) (1ULL << 32)); +#endif HERCCONST = MDACONST; VGACONST1 = (uint64_t) (cpuclock / 25175000.0 * (double) (1ULL << 32)); VGACONST2 = (uint64_t) (cpuclock / 28322000.0 * (double) (1ULL << 32)); diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 612a07cac..707590134 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1462,9 +1462,7 @@ process_char(escp_t *dev, uint8_t ch) dev->curr_x = dev->left_margin; if (!dev->autofeed) return 1; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x0a: /* Line feed */ if (dev->font_style & STYLE_DOUBLEWIDTHONELINE) { diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index e1183f0c0..ddf9faf53 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -283,9 +283,7 @@ process_char(prnt_t *dev, uint8_t ch) dev->curr_x = 0; if (!dev->autofeed) return 1; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x0a: /* Line feed */ dev->curr_x = 0; diff --git a/src/qt/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp index 4b487e65d..b5f68a286 100644 --- a/src/qt/evdev_mouse.cpp +++ b/src/qt/evdev_mouse.cpp @@ -37,21 +37,6 @@ static std::vector> evdev_mice; static std::atomic stopped = false; static QThread *evdev_thread; -static std::atomic 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); } } } diff --git a/src/qt/evdev_mouse.hpp b/src/qt/evdev_mouse.hpp index 7681771c6..0b0b8b26f 100644 --- a/src/qt/evdev_mouse.hpp +++ b/src/qt/evdev_mouse.hpp @@ -1,4 +1,3 @@ #ifdef EVDEV_INPUT void evdev_init(); -void evdev_mouse_poll(); #endif diff --git a/src/qt/macos_event_filter.mm b/src/qt/macos_event_filter.mm index 6f84beee5..ff4e7c4d2 100644 --- a/src/qt/macos_event_filter.mm +++ b/src/qt/macos_event_filter.mm @@ -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_scalef((double) [event deltaX], (double) [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; -} diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index daf13f72d..04fb01ffb 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -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 diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index ef39765dd..4bb30c56f 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -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); @@ -295,7 +293,9 @@ MainWindow::MainWindow(QWidget *parent) connect(this, &MainWindow::resizeContentsMonitor, this, [this](int w, int h, int monitor_index) { if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { +#ifdef QT_RESIZE_DEBUG qDebug() << "Resize"; +#endif w = (w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); int modifiedHeight = (h / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); @@ -630,7 +630,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 +764,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 +889,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()) { diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index d5a6b1967..7e4032a31 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -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); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 0274bc44a..7a028bfac 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -36,13 +36,18 @@ #include #include #include +#include +#include #include #include +#include + #include "qt_rendererstack.hpp" #include "qt_mainwindow.hpp" #include "qt_progsettings.hpp" +#include "qt_util.hpp" #ifdef Q_OS_UNIX # include @@ -639,7 +644,7 @@ plat_get_global_config_dir(char* strptr) } void -plat_init_rom_paths() +plat_init_rom_paths(void) { auto paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); @@ -660,3 +665,75 @@ plat_init_rom_paths() #endif } } + +void +plat_get_cpu_string(char *outbuf, uint8_t len) { + auto cpu_string = QString("Unknown"); + /* Write the default string now in case we have to exit early from an error */ + qstrncpy(outbuf, cpu_string.toUtf8().constData(), len); + +#if defined(Q_OS_MACOS) + auto *process = new QProcess(nullptr); + QStringList arguments; + QString program = "/usr/sbin/sysctl"; + arguments << "machdep.cpu.brand_string"; + process->start(program, arguments); + if (!process->waitForStarted()) { + return; + } + if (!process->waitForFinished()) { + return; + } + QByteArray result = process->readAll(); + auto command_result = QString(result).split(": ").last(); + if(!command_result.isEmpty()) { + cpu_string = command_result; + } +#elif defined(Q_OS_WINDOWS) + const LPCSTR keyName = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; + const LPCSTR valueName = "ProcessorNameString"; + unsigned char buf[32768]; + DWORD bufSize; + HKEY hKey; + bufSize = 32768; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { + cpu_string = reinterpret_cast(buf); + } + RegCloseKey(hKey); + } +#elif defined(Q_OS_LINUX) + auto cpuinfo = QString("/proc/cpuinfo"); + auto cpuinfo_fi = QFileInfo(cpuinfo); + if(!cpuinfo_fi.isReadable()) { + return; + } + QFile file(cpuinfo); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream textStream(&file); + while(true) { + QString line = textStream.readLine(); + if (line.isNull()) { + break; + } + if(QRegularExpression("model name.*:").match(line).hasMatch()) { + auto list = line.split(": "); + if(!list.last().isEmpty()) { + cpu_string = list.last(); + break; + } + } + + } + } +#endif + + qstrncpy(outbuf, cpu_string.toUtf8().constData(), len); + +} + +double +plat_get_dpi(void) +{ + return util::screenOfWidget(main_window)->devicePixelRatio(); +} diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index c2b38cd52..6685eede5 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -27,6 +27,7 @@ extern "C" { #include <86box/86box.h> +#include <86box/plat.h> #include <86box/video.h> } @@ -51,62 +52,71 @@ integer_scale(double *d, double *g) void RendererCommon::onResize(int width, int height) { - if ((video_fullscreen == 0) && (video_fullscreen_scale_maximized ? ((parentWidget->isMaximized() == false) && (main_window->isAncestorOf(parentWidget) && main_window->isMaximized() == false)) : 1)) { + /* This is needed so that the if below does not take like, 5 lines. */ + bool is_fs = (video_fullscreen == 0); + bool parent_max = (parentWidget->isMaximized() == false); + bool main_is_ancestor = main_window->isAncestorOf(parentWidget); + bool main_max = main_window->isMaximized(); + bool main_is_max = (main_is_ancestor && main_max == false); + + if (is_fs && (video_fullscreen_scale_maximized ? (parent_max && main_is_max) : 1)) destination.setRect(0, 0, width, height); - return; - } - double dx; - double dy; - double dw; - double dh; - double gsr; + else { + double dx; + double dy; + double dw; + double dh; + double gsr; - double hw = width; - double hh = height; - double gw = source.width(); - double gh = source.height(); - double hsr = hw / hh; + double hw = width; + double hh = height; + double gw = source.width(); + double gh = source.height(); + double hsr = hw / hh; - switch (video_fullscreen_scale) { - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - integer_scale(&dw, &gw); - integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - destination.setRect(dx, dy, dw, dh); - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) { - gsr = 4.0 / 3.0; - } else { + switch (video_fullscreen_scale) { + case FULLSCR_SCALE_INT: gsr = gw / gh; - } + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + integer_scale(&dw, &gw); + integer_scale(&dh, &gh); + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect((int) dx, (int) dy, (int) dw, (int) dh); + break; + case FULLSCR_SCALE_43: + case FULLSCR_SCALE_KEEPRATIO: + if (video_fullscreen_scale == FULLSCR_SCALE_43) + gsr = 4.0 / 3.0; + else + gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - destination.setRect(dx, dy, dw, dh); - break; - case FULLSCR_SCALE_FULL: - default: - destination.setRect(0, 0, hw, hh); - break; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect((int) dx, (int) dy, (int) dw, (int) dh); + break; + case FULLSCR_SCALE_FULL: + default: + destination.setRect(0, 0, (int) hw, (int) hh); + break; + } } + + monitors[r_monitor_index].mon_res_x = (double) destination.width(); + monitors[r_monitor_index].mon_res_y = (double) destination.height(); } bool diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 34b28fb30..4385a0b73 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -38,8 +38,10 @@ public: virtual bool hasBlitFunc() { return false; } virtual void blit(int x, int y, int w, int h) { } + int r_monitor_index = 0; + protected: - bool eventDelegate(QEvent *event, bool &result); + bool eventDelegate(QEvent *event, bool &result); QRect source { 0, 0, 0, 0 }; QRect destination; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index ee87dccb8..55ab814c2 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -49,37 +49,39 @@ 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 x_abs; std::atomic 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) , ui(new Ui::RendererStack) { +#ifdef Q_OS_WINDOWS + int raw = 1; +#else + int raw = 0; +#endif + ui->setupUi(this); 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 +90,32 @@ 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; + raw = 0; } # 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 + + if (monitor_index == 0) + mouse_set_raw(raw); } RendererStack::~RendererStack() @@ -149,49 +148,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(scaled_x); - mouse_y = static_cast(scaled_y); - - mouse_x_error = scaled_x - mouse_x; - mouse_y_error = scaled_y - mouse_y; } int ignoreNextMouseEvent = 1; @@ -212,8 +187,19 @@ RendererStack::mouseReleaseEvent(QMouseEvent *event) isMouseDown &= ~1; return; } - if (mouse_capture || mouse_mode >= 1) { - mousedata.mousebuttons &= ~event->button(); + if (mouse_capture || (mouse_mode >= 1)) { +#ifdef Q_OS_WINDOWS + if (((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + ((m_monitor_index < 1) && (mouse_mode >= 1))) +#else +#ifndef __APPLE__ + if (((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + (m_monitor_index < 1)) +#else + if ((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) +#endif +#endif + mouse_set_buttons_ex(mouse_get_buttons_ex() & ~event->button()); } isMouseDown &= ~1; } @@ -222,8 +208,19 @@ void RendererStack::mousePressEvent(QMouseEvent *event) { isMouseDown |= 1; - if (mouse_capture || mouse_mode >= 1) { - mousedata.mousebuttons |= event->button(); + if (mouse_capture || (mouse_mode >= 1)) { +#ifdef Q_OS_WINDOWS + if (((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + ((m_monitor_index < 1) && (mouse_mode >= 1))) +#else +#ifndef __APPLE__ + if (((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) || + (m_monitor_index < 1)) +#else + if ((m_monitor_index >= 1) && (mouse_mode >= 1) && mousedata.mouse_tablet_in_proximity) +#endif +#endif + mouse_set_buttons_ex(mouse_get_buttons_ex() | event->button()); } event->accept(); } @@ -231,9 +228,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 +253,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--; @@ -564,3 +563,19 @@ RendererStack::event(QEvent* event) } return QStackedWidget::event(event); } + +void +RendererStack::setFocusRenderer() +{ + if (current) + current->setFocus(); +} + +void +RendererStack::onResize(int width, int height) +{ + if (rendererWindow) { + rendererWindow->r_monitor_index = m_monitor_index; + rendererWindow->onResize(width, height); + } +} diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index df52a9542..f59849dda 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -71,20 +71,12 @@ public: /* Returns options dialog for current renderer */ QDialog *getOptions(QWidget *parent) { return rendererWindow ? rendererWindow->getOptions(parent) : nullptr; } - void setFocusRenderer() - { - if (current) - current->setFocus(); - } - void onResize(int width, int height) - { - if (rendererWindow) - rendererWindow->onResize(width, height); - } + void setFocusRenderer(); + void onResize(int width, int height); - void (*mouse_poll_func)() = nullptr; void (*mouse_capture_func)(QWindow *window) = nullptr; void (*mouse_uncapture_func)() = nullptr; + void (*mouse_exit_func)() = nullptr; signals: diff --git a/src/qt/qt_sdl.c b/src/qt/qt_sdl.c index 6d04acd25..166ea88fa 100644 --- a/src/qt/qt_sdl.c +++ b/src/qt/qt_sdl.c @@ -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; -} diff --git a/src/qt/qt_sdl.h b/src/qt/qt_sdl.h index 29804c278..f9709c857 100644 --- a/src/qt/qt_sdl.h +++ b/src/qt/qt_sdl.h @@ -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*/ diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index fb878b716..3ec61dfb7 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -1,62 +1,62 @@ -#ifndef QT_SETTINGS_BUS_TRACKING_HPP -#define QT_SETTINGS_BUS_TRACKING_HPP - -#include - -#define TRACK_CLEAR 0 -#define TRACK_SET 1 - -#define DEV_HDD 0x01 -#define DEV_CDROM 0x02 -#define DEV_ZIP 0x04 -#define DEV_MO 0x08 - -#define BUS_MFM 0 -#define BUS_ESDI 1 -#define BUS_XTA 2 -#define BUS_IDE 3 -#define BUS_SCSI 4 - -#define CHANNEL_NONE 0xff - -namespace Ui { -class SettingsBusTracking; -} - -class SettingsBusTracking { -public: - explicit SettingsBusTracking(); - ~SettingsBusTracking() = default; - - /* These return 0xff is none is free. */ - uint8_t next_free_mfm_channel(); - uint8_t next_free_esdi_channel(); - uint8_t next_free_xta_channel(); - uint8_t next_free_ide_channel(); - uint8_t next_free_scsi_id(); - - int mfm_bus_full(); - int esdi_bus_full(); - int xta_bus_full(); - int ide_bus_full(); - int scsi_bus_full(); - - /* Set: 0 = Clear the device from the tracking, 1 = Set the device on the tracking. - Device type: 1 = Hard Disk, 2 = CD-ROM, 4 = ZIP, 8 = Magneto-Optical. - Bus: 0 = MFM, 1 = ESDI, 2 = XTA, 3 = IDE, 4 = SCSI. */ - void device_track(int set, uint8_t dev_type, int bus, int channel); - -private: - /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t mfm_tracking { 0 }; - /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t esdi_tracking { 0 }; - /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t xta_tracking { 0 }; - /* 16 channels (prepatation for that weird IDE card), 2 devices per channel, 8 bits per device = 256 bits. */ - uint64_t ide_tracking[4] { 0, 0, 0, 0 }; - /* 4 buses, 16 devices per bus, 8 bits per device (future-proofing) = 512 bits. */ - uint64_t scsi_tracking[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; -}; - -#endif // QT_SETTINGS_BUS_TRACKING_HPP +#ifndef QT_SETTINGS_BUS_TRACKING_HPP +#define QT_SETTINGS_BUS_TRACKING_HPP + +#include + +#define TRACK_CLEAR 0 +#define TRACK_SET 1 + +#define DEV_HDD 0x01 +#define DEV_CDROM 0x02 +#define DEV_ZIP 0x04 +#define DEV_MO 0x08 + +#define BUS_MFM 0 +#define BUS_ESDI 1 +#define BUS_XTA 2 +#define BUS_IDE 3 +#define BUS_SCSI 4 + +#define CHANNEL_NONE 0xff + +namespace Ui { +class SettingsBusTracking; +} + +class SettingsBusTracking { +public: + explicit SettingsBusTracking(); + ~SettingsBusTracking() = default; + + /* These return 0xff is none is free. */ + uint8_t next_free_mfm_channel(); + uint8_t next_free_esdi_channel(); + uint8_t next_free_xta_channel(); + uint8_t next_free_ide_channel(); + uint8_t next_free_scsi_id(); + + int mfm_bus_full(); + int esdi_bus_full(); + int xta_bus_full(); + int ide_bus_full(); + int scsi_bus_full(); + + /* Set: 0 = Clear the device from the tracking, 1 = Set the device on the tracking. + Device type: 1 = Hard Disk, 2 = CD-ROM, 4 = ZIP, 8 = Magneto-Optical. + Bus: 0 = MFM, 1 = ESDI, 2 = XTA, 3 = IDE, 4 = SCSI. */ + void device_track(int set, uint8_t dev_type, int bus, int channel); + +private: + /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ + uint64_t mfm_tracking { 0 }; + /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ + uint64_t esdi_tracking { 0 }; + /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ + uint64_t xta_tracking { 0 }; + /* 16 channels (prepatation for that weird IDE card), 2 devices per channel, 8 bits per device = 256 bits. */ + uint64_t ide_tracking[4] { 0, 0, 0, 0 }; + /* 4 buses, 16 devices per bus, 8 bits per device (future-proofing) = 512 bits. */ + uint64_t scsi_tracking[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; +}; + +#endif // QT_SETTINGS_BUS_TRACKING_HPP diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 5f2f81c58..a22ba29da 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -102,11 +102,17 @@ SettingsDisplay::onCurrentMachineChanged(int machineId) ui->comboBoxVideoSecondary->setEnabled(true); ui->pushButtonConfigureSecondary->setEnabled(true); } - if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_8514) - ibm8514_has_vga = 0; - if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_XGA) - xga_has_vga = 0; - + if (gfxcard[0] == VID_INTERNAL) { + if (video_get_type_monitor(0) != VIDEO_FLAG_TYPE_8514) + ibm8514_has_vga = 0; + if (video_get_type_monitor(0) != VIDEO_FLAG_TYPE_XGA) + xga_has_vga = 0; + } else { + if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_8514) + ibm8514_has_vga = 0; + if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_XGA) + xga_has_vga = 0; + } ui->comboBoxVideo->setCurrentIndex(selectedRow); if (gfxcard[1] == 0) ui->pushButtonConfigureSecondary->setEnabled(false); diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 22dad3fa1..47e6b48a2 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -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) diff --git a/src/qt/qt_vulkanrenderer.cpp b/src/qt/qt_vulkanrenderer.cpp index 73594ea9e..9227cdcb3 100644 --- a/src/qt/qt_vulkanrenderer.cpp +++ b/src/qt/qt_vulkanrenderer.cpp @@ -938,9 +938,6 @@ VulkanRenderer2::startNextFrame() if (err != VK_SUCCESS) qFatal("Failed to map memory: %d", err); QMatrix4x4 m = m_proj; -#if 0 - m.rotate(m_rotation, 0, 0, 1); -#endif memcpy(p, m.constData(), 16 * sizeof(float)); m_devFuncs->vkUnmapMemory(dev, m_bufMem); p = nullptr; diff --git a/src/qt/qt_vulkanrenderer.hpp b/src/qt/qt_vulkanrenderer.hpp index 7961dd7f9..d4580d848 100644 --- a/src/qt/qt_vulkanrenderer.hpp +++ b/src/qt/qt_vulkanrenderer.hpp @@ -1,94 +1,93 @@ -#pragma once -/**************************************************************************** -** -** Copyright (C) 2022 Cacodemon345 -** Copyright (C) 2017 The Qt Company Ltd. -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -****************************************************************************/ - -#include -#include - -#if QT_CONFIG(vulkan) -# include "qt_vulkanwindowrenderer.hpp" - -class VulkanRenderer2 : public QVulkanWindowRenderer { -public: - void *mappedPtr = nullptr; - size_t imagePitch = 2048 * 4; - VulkanRenderer2(QVulkanWindow *w); - - void initResources() override; - void initSwapChainResources() override; - void releaseSwapChainResources() override; - void releaseResources() override; - - void startNextFrame() override; - -private: - VkShaderModule createShader(const QString &name); - bool createTexture(); - bool createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, - VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex); - bool writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory); - void ensureTexture(); - void updateSamplers(); - - QVulkanWindow *m_window; - QVulkanDeviceFunctions *m_devFuncs; - - VkDeviceMemory m_bufMem = VK_NULL_HANDLE; - VkBuffer m_buf = VK_NULL_HANDLE; - VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - - VkDescriptorPool m_descPool = VK_NULL_HANDLE; - VkDescriptorSetLayout m_descSetLayout = VK_NULL_HANDLE; - VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - - VkPipelineCache m_pipelineCache = VK_NULL_HANDLE; - VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; - VkPipeline m_pipeline = VK_NULL_HANDLE; - - VkSampler m_sampler = VK_NULL_HANDLE; - VkSampler m_linearSampler = VK_NULL_HANDLE; - VkImage m_texImage = VK_NULL_HANDLE; - VkDeviceMemory m_texMem = VK_NULL_HANDLE; - bool m_texLayoutPending = false; - VkImageView m_texView = VK_NULL_HANDLE; - VkImage m_texStaging = VK_NULL_HANDLE; - VkDeviceMemory m_texStagingMem = VK_NULL_HANDLE; - bool m_texStagingPending = false; - bool m_texStagingTransferLayout = false; - QSize m_texSize; - VkFormat m_texFormat; - - QMatrix4x4 m_proj; - float m_rotation = 0.0f; -}; -#endif +#pragma once +/**************************************************************************** +** +** Copyright (C) 2022 Cacodemon345 +** Copyright (C) 2017 The Qt Company Ltd. +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + +#include +#include + +#if QT_CONFIG(vulkan) +# include "qt_vulkanwindowrenderer.hpp" + +class VulkanRenderer2 : public QVulkanWindowRenderer { +public: + void *mappedPtr = nullptr; + size_t imagePitch = 2048 * 4; + VulkanRenderer2(QVulkanWindow *w); + + void initResources() override; + void initSwapChainResources() override; + void releaseSwapChainResources() override; + void releaseResources() override; + + void startNextFrame() override; + +private: + VkShaderModule createShader(const QString &name); + bool createTexture(); + bool createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, + VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex); + bool writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory); + void ensureTexture(); + void updateSamplers(); + + QVulkanWindow *m_window; + QVulkanDeviceFunctions *m_devFuncs; + + VkDeviceMemory m_bufMem = VK_NULL_HANDLE; + VkBuffer m_buf = VK_NULL_HANDLE; + VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; + + VkDescriptorPool m_descPool = VK_NULL_HANDLE; + VkDescriptorSetLayout m_descSetLayout = VK_NULL_HANDLE; + VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; + + VkPipelineCache m_pipelineCache = VK_NULL_HANDLE; + VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; + VkPipeline m_pipeline = VK_NULL_HANDLE; + + VkSampler m_sampler = VK_NULL_HANDLE; + VkSampler m_linearSampler = VK_NULL_HANDLE; + VkImage m_texImage = VK_NULL_HANDLE; + VkDeviceMemory m_texMem = VK_NULL_HANDLE; + bool m_texLayoutPending = false; + VkImageView m_texView = VK_NULL_HANDLE; + VkImage m_texStaging = VK_NULL_HANDLE; + VkDeviceMemory m_texStagingMem = VK_NULL_HANDLE; + bool m_texStagingPending = false; + bool m_texStagingTransferLayout = false; + QSize m_texSize; + VkFormat m_texFormat; + + QMatrix4x4 m_proj; +}; +#endif diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 73eea9ad8..1beddba51 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -35,6 +35,8 @@ #include +#include + #include #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; - } - } -} diff --git a/src/qt/qt_winrawinputfilter.hpp b/src/qt/qt_winrawinputfilter.hpp index 81b2c0d48..f687164ca 100644 --- a/src/qt/qt_winrawinputfilter.hpp +++ b/src/qt/qt_winrawinputfilter.hpp @@ -59,9 +59,6 @@ public: ~WindowsRawInputFilter(); -public slots: - void mousePoll(); - private: MainWindow *window; uint16_t scancode_map[768]; diff --git a/src/qt/sdl_joystick.cpp b/src/qt/sdl_joystick.cpp index bc540fcf6..cdbf102b8 100644 --- a/src/qt/sdl_joystick.cpp +++ b/src/qt/sdl_joystick.cpp @@ -41,15 +41,15 @@ joystick_init() plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) { - sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d); + snprintf(plat_joystick_state[c].axis[d].name, sizeof(plat_joystick_state[c].axis[d].name), "Axis %i", d); plat_joystick_state[c].axis[d].id = d; } for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) { - sprintf(plat_joystick_state[c].button[d].name, "Button %i", d); + snprintf(plat_joystick_state[c].button[d].name, sizeof(plat_joystick_state[c].button[d].name), "Button %i", d); plat_joystick_state[c].button[d].id = d; } for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) { - sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d); + snprintf(plat_joystick_state[c].pov[d].name, sizeof(plat_joystick_state[c].pov[d].name), "POV %i", d); plat_joystick_state[c].pov[d].id = d; } } diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index e5d477296..4d47fb309 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -98,8 +98,6 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) void joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - LONG center; - if (joy->nr_axes >= 8) return; @@ -139,14 +137,11 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS * Some joysticks will send -1 in LogicalMax, like Xbox Controllers * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) */ - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1); + rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1ULL << prop->BitSize) - 1); } rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; - center = (rawjoy->axis[joy->nr_axes].max - rawjoy->axis[joy->nr_axes].min + 1) / 2; - - if (center != 0x00) - joy->nr_axes++; + joy->nr_axes++; } void @@ -450,7 +445,7 @@ joystick_process(void) { int d; - if (joystick_type == 7) + if (joystick_type == 0) return; for (int c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { diff --git a/src/qt/wl_mouse.cpp b/src/qt/wl_mouse.cpp index 789712de5..5d6d95a0a 100644 --- a/src/qt/wl_mouse.cpp +++ b/src/qt/wl_mouse.cpp @@ -26,6 +26,7 @@ #include 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 = { diff --git a/src/qt/wl_mouse.hpp b/src/qt/wl_mouse.hpp index 25d4de66c..e1751fd82 100644 --- a/src/qt/wl_mouse.hpp +++ b/src/qt/wl_mouse.hpp @@ -1,5 +1,4 @@ class QWindow; void wl_mouse_capture(QWindow *window); void wl_mouse_uncapture(); -void wl_mouse_poll(); void wl_init(); diff --git a/src/qt/xinput2_mouse.cpp b/src/qt/xinput2_mouse.cpp index dafa4ffda..1be6ec826 100644 --- a/src/qt/xinput2_mouse.cpp +++ b/src/qt/xinput2_mouse.cpp @@ -48,7 +48,7 @@ static Display *disp = nullptr; static QThread *procThread = nullptr; static XIEventMask ximask; static std::atomic exitfromthread = false; -static std::atomic xi2_mouse_x = 0, xi2_mouse_y = 0, xi2_mouse_abs_x = 0, xi2_mouse_abs_y = 0; +static std::atomic xi2_mouse_abs_x = 0, xi2_mouse_abs_y = 0; static int xi2opcode = 0; static double prev_coords[2] = { 0.0 }; static Time prev_time = 0; @@ -168,9 +168,9 @@ common_motion: if ((v->mode == XIModeRelative) && (rawev->sourceid != xtest_pointer)) { /* Set relative coordinates. */ if (axis == 0) - xi2_mouse_x = xi2_mouse_x + coords[axis]; + mouse_scale_x(coords[axis]); else - xi2_mouse_y = xi2_mouse_y + coords[axis]; + mouse_scale_y(coords[axis]); } else { /* Convert absolute value range to pixel granularity, then to relative coordinates. */ int disp_screen = XDefaultScreen(disp); @@ -188,7 +188,7 @@ common_motion: } if (xi2_mouse_abs_x != 0) - xi2_mouse_x = xi2_mouse_x + (abs_div - xi2_mouse_abs_x); + mouse_scale_x(abs_div - xi2_mouse_abs_x); xi2_mouse_abs_x = abs_div; } else { if (v->mode == XIModeRelative) { @@ -202,7 +202,7 @@ common_motion: } if (xi2_mouse_abs_y != 0) - xi2_mouse_y = xi2_mouse_y + (abs_div - xi2_mouse_abs_y); + mouse_scale_y(abs_div - xi2_mouse_abs_y); xi2_mouse_abs_y = abs_div; } } @@ -273,14 +273,3 @@ xinput2_init() } } } - -void -xinput2_poll() -{ - if (procThread && mouse_capture) { - mouse_x = xi2_mouse_x; - mouse_y = xi2_mouse_y; - } - xi2_mouse_x = 0; - xi2_mouse_y = 0; -} diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index d38a967bd..93efeb354 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1232,9 +1232,7 @@ BuslogicPCIWrite(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x10: val &= 0xe0; val |= 1; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x11: case 0x12: @@ -1258,9 +1256,7 @@ BuslogicPCIWrite(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x14: val &= 0xe0; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x15: case 0x16: @@ -1748,7 +1744,7 @@ buslogic_init(const device_t *info) } if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev); + pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev, &dev->pci_slot); buslogic_pci_bar[0].addr_regs[0] = 1; buslogic_pci_bar[1].addr_regs[0] = 0; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index d192aec53..1fc1af81e 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -883,9 +883,7 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) break; } } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; default: dev->packet_len = len; @@ -961,9 +959,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", dev->id, (uint64_t) period); dev->callback += period; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x25: case 0x42: case 0x43: @@ -1940,9 +1936,7 @@ begin: /* IMPORTANT: Convert the command to new read CD for pass through purposes. */ dev->current_cdb[0] = GPCMD_READ_CD; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case GPCMD_READ_6: case GPCMD_READ_10: diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 2bd61313b..89db4a1f5 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -597,9 +597,7 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) scsi_disk_invalid_field(dev); return; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 897f37d1d..8c70b753b 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -234,6 +234,7 @@ typedef struct ncr53c8xx_t { int waiting; uint8_t current_lun; + uint8_t irq_state; uint8_t istat; uint8_t dcmd; @@ -498,10 +499,10 @@ static void do_irq(ncr53c8xx_t *dev, int level) { if (level) { - pci_set_irq(dev->pci_slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); ncr53c8xx_log("Raising IRQ...\n"); } else { - pci_clear_irq(dev->pci_slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); ncr53c8xx_log("Lowering IRQ...\n"); } } @@ -534,12 +535,16 @@ ncr53c8xx_update_irq(ncr53c8xx_t *dev) level = 1; } +#ifdef STATE_KEEPING if (level != dev->last_level) { +#endif ncr53c8xx_log("Update IRQ level %d dstat %02x sist %02x%02x\n", level, dev->dstat, dev->sist1, dev->sist0); dev->last_level = level; do_irq(dev, level); /* Only do something with the IRQ if the new level differs from the previous one. */ +#ifdef STATE_KEEPING } +#endif } /* Stop SCRIPTS execution and raise a SCSI interrupt. */ @@ -2552,9 +2557,9 @@ ncr53c8xx_init(const device_t *info) dev->has_bios = 0; if (info->local & 0x8000) - dev->pci_slot = pci_add_card(PCI_ADD_SCSI, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); + pci_add_card(PCI_ADD_SCSI, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev, &dev->pci_slot); else - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); + pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev, &dev->pci_slot); if (dev->chip == CHIP_875) { dev->chip_rev = 0x04; diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 7fa359396..0a4297caa 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -197,6 +197,7 @@ typedef struct esp_t { int pos; } dma_86c01; + uint8_t irq_state; uint8_t pos_regs[8]; } esp_t; @@ -247,10 +248,10 @@ esp_irq(esp_t *dev, int level) } } else { if (level) { - pci_set_irq(dev->pci_slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); esp_log("Raising IRQ...\n"); } else { - pci_clear_irq(dev->pci_slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); esp_log("Lowering IRQ...\n"); } } @@ -1029,9 +1030,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) switch (saddr) { case ESP_TCHI: dev->tchi_written = 1; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case ESP_TCLO: case ESP_TCMID: esp_log("Transfer count regs %02x = %i\n", saddr, val); @@ -1842,7 +1841,7 @@ dc390_init(UNUSED(const device_t *info)) dev->PCIBase = 0; dev->MMIOBase = 0; - dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, esp_pci_read, esp_pci_write, dev); + pci_add_card(PCI_ADD_NORMAL, esp_pci_read, esp_pci_write, dev, &dev->pci_slot); esp_pci_bar[0].addr_regs[0] = 1; esp_pci_regs[0x04] = 3; diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 7a6923def..96088e200 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -83,23 +83,27 @@ x54x_irq(x54x_t *dev, int set) if (dev->card_bus & DEVICE_PCI) { x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot); if (set) - pci_set_irq(dev->pci_slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); else - pci_clear_irq(dev->pci_slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); } else { x54x_log("%sing IRQ %i\n", set ? "Rais" : "Lower", irq); - if (set) { - if (dev->interrupt_type) - int_type = dev->interrupt_type(dev); + if (dev->interrupt_type) + int_type = dev->interrupt_type(dev); + if (set) { if (int_type) - picintlevel(1 << irq); + picintlevel(1 << irq, &dev->irq_state); else picint(1 << irq); - } else - picintc(1 << irq); - } + } else { + if (int_type) + picintclevel(1 << irq, &dev->irq_state); + else + picintc(1 << irq); + } + } } static void @@ -486,9 +490,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) default: x54x_log("BIOS: Unimplemented command: %02X\n", cmd->command); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x05: /* Format Track, invalid since SCSI has no tracks */ case 0x0a: /* ???? */ case 0x0b: /* ???? */ @@ -1415,6 +1417,7 @@ static void x54x_reset(x54x_t *dev) { clear_irq(dev); + dev->irq_state = 0; if (dev->flags & X54X_INT_GEOM_WRITABLE) dev->Geometry = 0x90; else diff --git a/src/sio/sio_um8669f.c b/src/sio/sio_um8669f.c index 256c614ae..7ddb143af 100644 --- a/src/sio/sio_um8669f.c +++ b/src/sio/sio_um8669f.c @@ -39,7 +39,9 @@ #include <86box/isapnp.h> #include <86box/plat_unused.h> -/* This ROM was reconstructed out of many assumptions, some of which based on the IT8671F. */ +/* Real chips don't have a PnP ROM and instead rely on the BIOS going in blind. + We create a fake ROM here (with values based on the IT8671F) to delegate + all the logical device register handling over to the ISAPnP subsystem. */ static uint8_t um8669f_pnp_rom[] = { 0x55, 0xa3, 0x86, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, /* UMC8669, dummy checksum (filled in by isapnp_add_card) */ 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ @@ -61,7 +63,7 @@ static uint8_t um8669f_pnp_rom[] = { 0x22, 0xfa, 0x1f, /* IRQ 1/3/4/5/6/7/8/9/10/11/12 */ 0x47, 0x00, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x08, /* I/O 0x100-0x3F8, decodes 10-bit, 8-byte alignment, 8 addresses */ - 0x15, 0x41, 0xd0, 0xff, 0xff, 0x00, /* logical device PNPFFFF (just a dummy to create a gap in LDNs) */ + 0x15, 0x41, 0xd0, 0xff, 0xff, 0x00, /* logical device PNPFFFF (dummy to create a gap in LDNs) */ 0x15, 0x41, 0xd0, 0xb0, 0x2f, 0x01, /* logical device PNPB02F, can participate in boot */ 0x47, 0x00, 0x00, 0x01, 0xf8, 0x03, 0x08, 0x08, /* I/O 0x100-0x3F8, decodes 10-bit, 8-byte alignment, 8 addresses */ @@ -113,10 +115,9 @@ um8669f_log(const char *fmt, ...) #endif typedef struct um8669f_t { - int locked; - int cur_reg_108; - void *pnp_card; - isapnp_device_config_t *pnp_config[5]; + uint8_t locked; + uint8_t cur_reg_108; + void *pnp_card; uint8_t regs_108[256]; diff --git a/src/sound/munt/MidiStreamParser.cpp b/src/sound/munt/MidiStreamParser.cpp index 7b64f97f9..f91a81828 100644 --- a/src/sound/munt/MidiStreamParser.cpp +++ b/src/sound/munt/MidiStreamParser.cpp @@ -191,7 +191,7 @@ Bit32u MidiStreamParserImpl::parseShortMessageDataBytes(const Bit8u stream[], Bi } else if (dataByte < 0xF8) { // Discard invalid bytes and start over char s[128]; - sprintf(s, "parseShortMessageDataBytes: Invalid short message: status %02x, expected length %i, actual %i -> ignored", *streamBuffer, shortMessageLength, streamBufferSize); + snprintf(s, sizeof(s), "parseShortMessageDataBytes: Invalid short message: status %02x, expected length %i, actual %i -> ignored", *streamBuffer, shortMessageLength, streamBufferSize); midiReporter.printDebug(s); streamBufferSize = 0; // Clear streamBuffer return parsedLength; diff --git a/src/sound/munt/Part.cpp b/src/sound/munt/Part.cpp index 5888b97b2..f536f2ab8 100644 --- a/src/sound/munt/Part.cpp +++ b/src/sound/munt/Part.cpp @@ -54,7 +54,7 @@ Part::Part(Synth *useSynth, unsigned int usePartNum) { // Nasty hack for rhythm timbreTemp = NULL; } else { - sprintf(name, "Part %d", partNum + 1); + snprintf(name, sizeof(name), "Part %d", partNum + 1); timbreTemp = &synth->mt32ram.timbreTemp[partNum]; } currentInstr[0] = 0; diff --git a/src/sound/resid-fp/sid.cc b/src/sound/resid-fp/sid.cc index 6f7544423..ad72d9d51 100644 --- a/src/sound/resid-fp/sid.cc +++ b/src/sound/resid-fp/sid.cc @@ -91,6 +91,7 @@ static int host_cpu_features_by_cpuid(void) return features; } +#if (RESID_USE_SSE==1) static int host_cpu_features(void) { static int features = 0; @@ -152,6 +153,7 @@ static int host_cpu_features(void) return 0; } #endif +#endif float SIDFP::kinked_dac(const int x, const float nonlinearity, const int max) { diff --git a/src/sound/snd_ac97_codec.c b/src/sound/snd_ac97_codec.c index 929574dce..d302db6ae 100644 --- a/src/sound/snd_ac97_codec.c +++ b/src/sound/snd_ac97_codec.c @@ -418,9 +418,7 @@ rate: /* Writable only if VRA/VRM is set. */ /* Get actual previous value. */ prev = dev->vendor_reg_pages[(i << 3) | ((reg & 0x0e) >> 1)]; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x5a ... 0x5e: /* Vendor Reserved */ case 0x70 ... 0x7a: @@ -587,7 +585,7 @@ ac97_codec_init(const device_t *info) break; } if (dev->model >= (sizeof(ac97_codecs) / sizeof(ac97_codecs[0]))) { - fatal("AC97 Codec %d: Unknown ID %c%c%c%02X\n", ac97_codec_id, (info->local >> 24) & 0xff, (info->local >> 16) & 0xff, (info->local >> 8) & 0xff, info->local & 0xff); + fatal("AC97 Codec %d: Unknown ID %c%c%c%02X\n", ac97_codec_id, (uint32_t) ((info->local >> 24) & 0xff), (uint32_t) ((info->local >> 16) & 0xff), (uint32_t) ((info->local >> 8) & 0xff), (uint32_t) (info->local & 0xff)); free(dev); return NULL; } diff --git a/src/sound/snd_ac97_via.c b/src/sound/snd_ac97_via.c index e074d17e2..ceac42387 100644 --- a/src/sound/snd_ac97_via.c +++ b/src/sound/snd_ac97_via.c @@ -73,7 +73,8 @@ typedef struct _ac97_via_ { uint8_t regs_linear[256]; }; } codec_shadow[2]; - int slot; + uint8_t pci_slot; + uint8_t irq_state; int irq_pin; ac97_codec_t *codec[2][2]; @@ -115,8 +116,8 @@ ac97_via_set_slot(void *priv, int slot, int irq_pin) ac97_via_log("AC97 VIA: set_slot(%d, %d)\n", slot, irq_pin); - dev->slot = slot; - dev->irq_pin = irq_pin; + dev->pci_slot = slot; + dev->irq_pin = irq_pin; } uint8_t @@ -182,12 +183,12 @@ ac97_via_update_irqs(ac97_via_t *dev) /* Stop immediately if any flag is set. Doing it this way optimizes rising edges for the playback SGD (0 - first to be checked). */ if (dev->sgd_regs[i] & (dev->sgd_regs[i | 0x2] & 0x03)) { - pci_set_irq(dev->slot, dev->irq_pin); + pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); return; } } - pci_clear_irq(dev->slot, dev->irq_pin); + pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); } static void diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index acc143636..d2a05fd6f 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -242,9 +242,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 10: if (ad1848->type < AD1848_TYPE_CS4235) break; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 8: updatefreq = 1; diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 984a06ea9..6cbcea69b 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -692,7 +692,7 @@ adgold_timer_poll(void *priv) { adgold_t *adgold = (adgold_t *) priv; - /*A small timer period will result in hangs.*/ + /*A small timer period will result in hangs.*/ timer_on_auto(&adgold->adgold_mma_timer_count, 4.88964); if (adgold->adgold_midi_ctrl & 0x3f) { diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index fb156a205..436f99897 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -53,6 +53,7 @@ typedef struct es1371_t { uint32_t base_addr; uint8_t int_line; + uint8_t irq_state; uint16_t pmcsr; @@ -120,7 +121,7 @@ typedef struct es1371_t { int cd_vol_l; int cd_vol_r; - int card; + uint8_t pci_slot; int pos; int16_t buffer[SOUNDBUFLEN * 2]; @@ -235,9 +236,9 @@ es1371_update_irqs(es1371_t *dev) irq = 1; if (irq) - 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); } static void @@ -2100,7 +2101,7 @@ es1371_init(const device_t *info) dev->gameport = gameport_add(&gameport_pnp_device); gameport_remap(dev->gameport, 0x200); - dev->card = pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev); + pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev, &dev->pci_slot); timer_add(&dev->dac[1].timer, es1371_poll, dev, 1); diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index ea81230a9..359563b99 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -97,7 +97,8 @@ typedef struct _cmi8x38_ { uint16_t mpu_base; uint8_t pci_regs[256]; uint8_t io_regs[256]; - int slot; + uint8_t pci_slot; + uint8_t irq_state; sb_t *sb; void *gameport; @@ -148,11 +149,11 @@ cmi8x38_update_irqs(cmi8x38_t *dev) /* Calculate and use the INTR flag. */ if (*((uint32_t *) &dev->io_regs[0x10]) & 0x0401c003) { dev->io_regs[0x13] |= 0x80; - pci_set_irq(dev->slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); cmi8x38_log("CMI8x38: Raising IRQ\n"); } else { dev->io_regs[0x13] &= ~0x80; - pci_clear_irq(dev->slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); } } @@ -468,9 +469,7 @@ cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0xf8 ... 0xff: if (dev->type == CMEDIA_CMI8338) mixer->regs[mixer->index] = val; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0xf1 ... 0xf7: return; @@ -823,9 +822,9 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv) /* Force IRQ if requested. Clearing this bit is undefined. */ if (val & 0x10) - pci_set_irq(dev->slot, PCI_INTA); + pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); else if ((dev->io_regs[0x17] & 0x10) && !(val & 0x10)) - pci_clear_irq(dev->slot, PCI_INTA); + pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); /* Enable or disable I/O traps. */ dev->io_regs[addr] = val; @@ -1473,7 +1472,7 @@ cmi8x38_init(const device_t *info) } /* Add PCI card. */ - dev->slot = pci_add_card((info->local & (1 << 13)) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, cmi8x38_pci_read, cmi8x38_pci_write, dev); + pci_add_card((info->local & (1 << 13)) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, cmi8x38_pci_read, cmi8x38_pci_write, dev, &dev->pci_slot); /* Perform initial reset. */ cmi8x38_reset(dev); diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index fff716e28..5c6b019a4 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -300,9 +300,7 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) switch (val) { case 0x55: /* Disable PnP Key */ dev->pnp_enable = 0; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x5a: /* Update Hardware Configuration Data */ cs423x_pnp_enable(dev, 0, 1); diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index c7e6d39f9..6d0416277 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -98,6 +98,9 @@ typedef struct gus_t { int irqnext; + uint8_t irq_state; + uint8_t midi_irq_state; + pc_timer_t timer_1; pc_timer_t timer_2; @@ -157,8 +160,10 @@ double vol16bit[4096]; void gus_update_int_status(gus_t *gus) { - int irq_pending = 0; - int midi_irq_pending = 0; + int irq_pending = 0; + int midi_irq_pending = 0; + int intr_pending = 0; + int midi_intr_pending = 0; gus->irqstatus &= ~0x60; gus->irqstatus2 = 0xE0; @@ -187,24 +192,35 @@ gus_update_int_status(gus_t *gus) midi_irq_pending = gus->midi_status & MIDI_INT_MASTER; - if (gus->irq == gus->irq_midi && gus->irq != -1) { + if (gus->irq == gus->irq_midi) { if (irq_pending || midi_irq_pending) - picintlevel(1 << gus->irq); + intr_pending = 1; else - picintc(1 << gus->irq); + intr_pending = 0; } else { - if (gus->irq != -1) { - if (irq_pending) - picintlevel(1 << gus->irq); - else - picintc(1 << gus->irq); - } - if (gus->irq_midi != -1) { - if (midi_irq_pending) - picintlevel(1 << gus->irq_midi); - else - picintc(1 << gus->irq_midi); - } + if (irq_pending) + intr_pending = 1; + else + intr_pending = 0; + + if (midi_irq_pending) + midi_intr_pending = 1; + else + midi_intr_pending = 0; + } + + if (gus->irq != -1) { + if (intr_pending) + picintlevel(1 << gus->irq, &gus->irq_state); + else + picintclevel(1 << gus->irq, &gus->irq_state); + } + + if (gus->irq_midi != -1) { + if (midi_intr_pending) + picintlevel(1 << gus->irq_midi, &gus->midi_irq_state); + else + picintclevel(1 << gus->irq_midi, &gus->midi_irq_state); } } @@ -627,9 +643,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) else if (gus->irq != -1) picint(1 << gus->irq); } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x20d: gus->sb_2xc = val; break; @@ -1174,6 +1188,103 @@ gus_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) return 0; } +static void +gus_reset(void *p) +{ + gus_t *gus = (gus_t *) p; + int c; + double out = 1.0; + + if (gus == NULL) + return; + + memset(gus->ram, 0x00, (gus->gus_end_ram)); + + for (c = 0; c < 32; c++) { + gus->ctrl[c] = 1; + gus->rctrl[c] = 1; + gus->rfreq[c] = 63 * 512; + } + + for (c = 4095; c >= 0; c--) { + vol16bit[c] = out; + out /= 1.002709201; /* 0.0235 dB Steps */ + } + + gus->voices = 14; + + gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0)); + + gus->t1l = gus->t2l = 0xff; + + gus->global = 0; + gus->addr = 0; + gus->dmaaddr = 0; + gus->voice = 0; + memset(gus->start, 0x00, 32 * sizeof(uint32_t)); + memset(gus->end, 0x00, 32 * sizeof(uint32_t)); + memset(gus->cur, 0x00, 32 * sizeof(uint32_t)); + memset(gus->startx, 0x00, 32 * sizeof(uint32_t)); + memset(gus->endx, 0x00, 32 * sizeof(uint32_t)); + memset(gus->curx, 0x00, 32 * sizeof(uint32_t)); + memset(gus->rstart, 0x00, 32 * sizeof(int)); + memset(gus->rend, 0x00, 32 * sizeof(int)); + memset(gus->rcur, 0x00, 32 * sizeof(int)); + memset(gus->freq, 0x00, 32 * sizeof(uint16_t)); + memset(gus->curvol, 0x00, 32 * sizeof(int)); + memset(gus->pan_l, 0x00, 32 * sizeof(int)); + memset(gus->pan_r, 0x00, 32 * sizeof(int)); + gus->t1on = 0; + gus->t2on = 0; + gus->tctrl = 0; + gus->t1 = 0; + gus->t2 = 0; + gus->irqstatus = 0; + gus->irqstatus2 = 0; + gus->adcommand = 0; + memset(gus->waveirqs, 0x00, 32 * sizeof(int)); + memset(gus->rampirqs, 0x00, 32 * sizeof(int)); + gus->dmactrl = 0; + + gus->uart_out = 1; + + gus->sb_2xa = 0; + gus->sb_2xc = 0; + gus->sb_2xe = 0; + gus->sb_ctrl = 0; + gus->sb_nmi = 0; + + gus->reg_ctrl = 0; + + gus->ad_status = 0; + gus->ad_data = 0; + gus->ad_timer_ctrl = 0; + + gus->midi_ctrl = 0; + gus->midi_status = 0; + memset(gus->midi_queue, 0x00, 64 * sizeof(uint8_t)); + gus->midi_data = 0; + gus->midi_r = 0; + gus->midi_w = 0; + gus->uart_in = 0; + gus->uart_out = 0; + gus->sysex = 0; + + gus->gp1 = 0; + gus->gp2 = 0; + gus->gp1_addr = 0; + gus->gp2_addr = 0; + + gus->usrr = 0; + + gus->max_ctrl = 0; + + gus->irq_state = 0; + gus->midi_irq_state = 0; + + gus_update_int_status(gus); +} + void * gus_init(UNUSED(const device_t *info)) { @@ -1181,7 +1292,7 @@ gus_init(UNUSED(const device_t *info)) double out = 1.0; uint8_t gus_ram = device_get_config_int("gus_ram"); gus_t *gus = malloc(sizeof(gus_t)); - memset(gus, 0, sizeof(gus_t)); + memset(gus, 0x00, sizeof(gus_t)); gus->gus_end_ram = 1 << (18 + gus_ram); gus->ram = (uint8_t *) malloc(gus->gus_end_ram); @@ -1359,7 +1470,7 @@ const device_t gus_device = { .local = 0, .init = gus_init, .close = gus_close, - .reset = NULL, + .reset = gus_reset, { .available = NULL }, .speed_changed = gus_speed_changed, .force_redraw = NULL, diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index c6cf13a33..7558a65ba 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -150,12 +150,15 @@ public: { for (uint32_t i = 0; i < num_samples; i++) { m_chip.generate(&m_output); - if (ChipType::OUTPUTS == 1) { - *data++ = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; - *data++ = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; + if(m_type == FM_YMF278B) { + *data++ += m_output.data[4 % ChipType::OUTPUTS]; + *data++ += m_output.data[5 % ChipType::OUTPUTS]; + } else if (ChipType::OUTPUTS == 1) { + *data++ = m_output.data[0]; + *data++ = m_output.data[0]; } else { - *data++ = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; - *data++ = m_output.data[(m_type == FM_YMF278B) ? 5 : (1 % ChipType::OUTPUTS)]; + *data++ = m_output.data[0]; + *data++ = m_output.data[1 % ChipType::OUTPUTS]; } } } @@ -167,12 +170,15 @@ public: m_oldsamples[0] = m_samples[0]; m_oldsamples[1] = m_samples[1]; m_chip.generate(&m_output); - if (ChipType::OUTPUTS == 1) { - m_samples[0] = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; - m_samples[1] = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; + if(m_type == FM_YMF278B) { + m_samples[0] += m_output.data[4 % ChipType::OUTPUTS]; + m_samples[1] += m_output.data[5 % ChipType::OUTPUTS]; + } else if (ChipType::OUTPUTS == 1) { + m_samples[0] = m_output.data[0]; + m_samples[1] = m_output.data[0]; } else { - m_samples[0] = m_output.data[(m_type == FM_YMF278B) ? 4 : 0]; - m_samples[1] = m_output.data[(m_type == FM_YMF278B) ? 5 : (1 % ChipType::OUTPUTS)]; + m_samples[0] = m_output.data[0]; + m_samples[1] = m_output.data[1 % ChipType::OUTPUTS]; } m_samplecnt -= m_rateratio; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index d4dcd5a79..72feaf19f 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -601,9 +601,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x75: /* 4-bit ADPCM output with reference */ dsp->sbref = dsp->dma_readb(dsp->dma_priv); dsp->sbstep = 0; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x74: /* 4-bit ADPCM output */ sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); diff --git a/src/sound/ymfm/ymfm.h b/src/sound/ymfm/ymfm.h index bc0cf8b6c..4f8ba1243 100644 --- a/src/sound/ymfm/ymfm.h +++ b/src/sound/ymfm/ymfm.h @@ -46,6 +46,8 @@ #include #include +#define SNPRINTF_BUFFER_SIZE_CALC (256 - (end - &buffer[0])) + namespace ymfm { @@ -350,7 +352,7 @@ public: { // create file char name[20]; - sprintf(name, "wavlog-%02d.wav", m_index); + snprintf(name, sizeof(name), "wavlog-%02d.wav", m_index); FILE *out = fopen(name, "wb"); // make the wav file header diff --git a/src/sound/ymfm/ymfm_fm.ipp b/src/sound/ymfm/ymfm_fm.ipp index 14c1aa965..6e8d39e3e 100644 --- a/src/sound/ymfm/ymfm_fm.ipp +++ b/src/sound/ymfm/ymfm_fm.ipp @@ -1522,8 +1522,11 @@ void fm_engine_base::engine_timer_expired(uint32_t tnum) m_modified_channels |= 1 << chnum; } - // reset - m_timer_running[tnum] = false; + // Make sure the array does not go out of bounds to keep gcc happy + if(tnum < 2) { + // reset + m_timer_running[tnum] = false; + } update_timer(tnum, 1, 0); } diff --git a/src/sound/ymfm/ymfm_opl.cpp b/src/sound/ymfm/ymfm_opl.cpp index 499bfceef..bb91c5dc0 100644 --- a/src/sound/ymfm/ymfm_opl.cpp +++ b/src/sound/ymfm/ymfm_opl.cpp @@ -388,7 +388,7 @@ std::string opl_registers_base::log_keyon(uint32_t choffs, uint32_t op char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%2u.%02u freq=%04X fb=%u alg=%X mul=%X tl=%02X ksr=%u ns=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%2u.%02u freq=%04X fb=%u alg=%X mul=%X tl=%02X ksr=%u ns=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u", chnum, opnum, ch_block_freq(choffs), ch_feedback(choffs), @@ -405,25 +405,25 @@ std::string opl_registers_base::log_keyon(uint32_t choffs, uint32_t op op_eg_sustain(opoffs)); if (OUTPUTS > 1) - end += sprintf(end, " out=%c%c%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " out=%c%c%c%c", ch_output_0(choffs) ? 'L' : '-', ch_output_1(choffs) ? 'R' : '-', ch_output_2(choffs) ? '0' : '-', ch_output_3(choffs) ? '1' : '-'); if (op_lfo_am_enable(opoffs) != 0) - end += sprintf(end, " am=%u", lfo_am_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u", lfo_am_depth()); if (op_lfo_pm_enable(opoffs) != 0) - end += sprintf(end, " pm=%u", lfo_pm_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u", lfo_pm_depth()); if (waveform_enable() && op_waveform(opoffs) != 0) - end += sprintf(end, " wf=%u", op_waveform(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " wf=%u", op_waveform(opoffs)); if (is_rhythm(choffs)) - end += sprintf(end, " rhy=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " rhy=1"); if (DYNAMIC_OPS) { operator_mapping map; operator_map(map); if (bitfield(map.chan[chnum], 16, 8) != 0xff) - end += sprintf(end, " 4op"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " 4op"); } return buffer; @@ -687,7 +687,7 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs) char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u freq=%04X inst=%X fb=%u mul=%X", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X inst=%X fb=%u mul=%X", chnum, opnum, ch_block_freq(choffs), ch_instrument(choffs), @@ -695,11 +695,11 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs) op_multiple(opoffs)); if (bitfield(opoffs, 0) == 1 || (is_rhythm(choffs) && choffs >= 6)) - end += sprintf(end, " vol=%X", op_volume(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " vol=%X", op_volume(opoffs)); else - end += sprintf(end, " tl=%02X", ch_total_level(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " tl=%02X", ch_total_level(choffs)); - end += sprintf(end, " ksr=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u/%u", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " ksr=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u/%u", op_ksr(opoffs), op_ksl(opoffs), op_attack_rate(opoffs), @@ -710,13 +710,13 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs) ch_sustain(choffs)); if (op_lfo_am_enable(opoffs)) - end += sprintf(end, " am=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=1"); if (op_lfo_pm_enable(opoffs)) - end += sprintf(end, " pm=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=1"); if (op_waveform(opoffs) != 0) - end += sprintf(end, " wf=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " wf=1"); if (is_rhythm(choffs)) - end += sprintf(end, " rhy=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " rhy=1"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opm.cpp b/src/sound/ymfm/ymfm_opm.cpp index 544bbe89a..c72badb57 100644 --- a/src/sound/ymfm/ymfm_opm.cpp +++ b/src/sound/ymfm/ymfm_opm.cpp @@ -356,7 +356,7 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs) char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u freq=%04X dt2=%u dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X dt2=%u dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", chnum, opnum, ch_block_freq(choffs), op_detune2(opoffs), @@ -376,14 +376,14 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs) bool am = (lfo_am_depth() != 0 && ch_lfo_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0); if (am) - end += sprintf(end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); bool pm = (lfo_pm_depth() != 0 && ch_lfo_pm_sens(choffs) != 0); if (pm) - end += sprintf(end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); if (am || pm) - end += sprintf(end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); if (noise_enable() && opoffs == 31) - end += sprintf(end, " noise=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " noise=1"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opn.cpp b/src/sound/ymfm/ymfm_opn.cpp index 053ad9770..388162dfe 100644 --- a/src/sound/ymfm/ymfm_opn.cpp +++ b/src/sound/ymfm/ymfm_opn.cpp @@ -411,7 +411,7 @@ std::string opn_registers_base::log_keyon(uint32_t choffs, uint32_t opof char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u freq=%04X dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X", chnum, opnum, block_freq, op_detune(opoffs), @@ -427,21 +427,21 @@ std::string opn_registers_base::log_keyon(uint32_t choffs, uint32_t opof op_sustain_level(opoffs)); if (OUTPUTS > 1) - end += sprintf(end, " out=%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " out=%c%c", ch_output_0(choffs) ? 'L' : '-', ch_output_1(choffs) ? 'R' : '-'); if (op_ssg_eg_enable(opoffs)) - end += sprintf(end, " ssg=%X", op_ssg_eg_mode(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " ssg=%X", op_ssg_eg_mode(opoffs)); bool am = (op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0); if (am) - end += sprintf(end, " am=%u", ch_lfo_am_sens(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u", ch_lfo_am_sens(choffs)); bool pm = (ch_lfo_pm_sens(choffs) != 0); if (pm) - end += sprintf(end, " pm=%u", ch_lfo_pm_sens(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u", ch_lfo_pm_sens(choffs)); if (am || pm) - end += sprintf(end, " lfo=%02X", lfo_rate()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X", lfo_rate()); if (multi_freq() && choffs == 2) - end += sprintf(end, " multi=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " multi=1"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opq.cpp b/src/sound/ymfm/ymfm_opq.cpp index 3467c0ddf..e6f6fa5ea 100644 --- a/src/sound/ymfm/ymfm_opq.cpp +++ b/src/sound/ymfm/ymfm_opq.cpp @@ -341,7 +341,7 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs) char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u freq=%04X dt=%+2d fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X dt=%+2d fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", chnum, opnum, (opoffs & 1) ? ch_block_freq_24(choffs) : ch_block_freq_13(choffs), int32_t(op_detune(opoffs)) - 0x20, @@ -360,14 +360,14 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs) bool am = (lfo_enable() && op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0); if (am) - end += sprintf(end, " am=%u", ch_lfo_am_sens(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u", ch_lfo_am_sens(choffs)); bool pm = (lfo_enable() && ch_lfo_pm_sens(choffs) != 0); if (pm) - end += sprintf(end, " pm=%u", ch_lfo_pm_sens(choffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u", ch_lfo_pm_sens(choffs)); if (am || pm) - end += sprintf(end, " lfo=%02X", lfo_rate()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X", lfo_rate()); if (ch_reverb(choffs)) - end += sprintf(end, " reverb"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " reverb"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opz.cpp b/src/sound/ymfm/ymfm_opz.cpp index adeefd79f..a5ec912aa 100644 --- a/src/sound/ymfm/ymfm_opz.cpp +++ b/src/sound/ymfm/ymfm_opz.cpp @@ -557,14 +557,14 @@ std::string opz_registers::log_keyon(uint32_t choffs, uint32_t opoffs) char buffer[256]; char *end = &buffer[0]; - end += sprintf(end, "%u.%02u", chnum, opnum); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u", chnum, opnum); if (op_fix_mode(opoffs)) - end += sprintf(end, " fixfreq=%X fine=%X shift=%X", op_fix_frequency(opoffs), op_fine(opoffs), op_fix_range(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " fixfreq=%X fine=%X shift=%X", op_fix_frequency(opoffs), op_fine(opoffs), op_fix_range(opoffs)); else - end += sprintf(end, " freq=%04X dt2=%u fine=%X", ch_block_freq(choffs), op_detune2(opoffs), op_fine(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " freq=%04X dt2=%u fine=%X", ch_block_freq(choffs), op_detune2(opoffs), op_fine(opoffs)); - end += sprintf(end, " dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", op_detune(opoffs), ch_feedback(choffs), ch_algorithm(choffs), @@ -580,32 +580,32 @@ std::string opz_registers::log_keyon(uint32_t choffs, uint32_t opoffs) ch_output_1(choffs) ? 'R' : '-'); if (op_eg_shift(opoffs) != 0) - end += sprintf(end, " egshift=%u", op_eg_shift(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " egshift=%u", op_eg_shift(opoffs)); bool am = (lfo_am_depth() != 0 && ch_lfo_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0); if (am) - end += sprintf(end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); bool pm = (lfo_pm_depth() != 0 && ch_lfo_pm_sens(choffs) != 0); if (pm) - end += sprintf(end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); if (am || pm) - end += sprintf(end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); bool am2 = (lfo2_am_depth() != 0 && ch_lfo2_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0); if (am2) - end += sprintf(end, " am2=%u/%02X", ch_lfo2_am_sens(choffs), lfo2_am_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am2=%u/%02X", ch_lfo2_am_sens(choffs), lfo2_am_depth()); bool pm2 = (lfo2_pm_depth() != 0 && ch_lfo2_pm_sens(choffs) != 0); if (pm2) - end += sprintf(end, " pm2=%u/%02X", ch_lfo2_pm_sens(choffs), lfo2_pm_depth()); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm2=%u/%02X", ch_lfo2_pm_sens(choffs), lfo2_pm_depth()); if (am2 || pm2) - end += sprintf(end, " lfo2=%02X/%c", lfo2_rate(), "WQTN"[lfo2_waveform()]); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo2=%02X/%c", lfo2_rate(), "WQTN"[lfo2_waveform()]); if (op_reverb_rate(opoffs) != 0) - end += sprintf(end, " rev=%u", op_reverb_rate(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " rev=%u", op_reverb_rate(opoffs)); if (op_waveform(opoffs) != 0) - end += sprintf(end, " wf=%u", op_waveform(opoffs)); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " wf=%u", op_waveform(opoffs)); if (noise_enable() && opoffs == 31) - end += sprintf(end, " noise=1"); + end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " noise=1"); return buffer; } diff --git a/src/unix/unix.c b/src/unix/unix.c index b56022474..c389c9c45 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -699,19 +699,6 @@ typedef struct mouseinputdata { int mousebuttons; } mouseinputdata; SDL_mutex *mousemutex; -static mouseinputdata mousedata; -void -mouse_poll(void) -{ - SDL_LockMutex(mousemutex); - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; - mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; - SDL_UnlockMutex(mousemutex); -} - int real_sdl_w; int real_sdl_h; void @@ -1182,7 +1169,7 @@ main(int argc, char **argv) event.wheel.y *= -1; } SDL_LockMutex(mousemutex); - mousedata.deltaz = event.wheel.y; + mouse_set_z(event.wheel.y); SDL_UnlockMutex(mousemutex); } break; @@ -1191,8 +1178,7 @@ main(int argc, char **argv) { if (mouse_capture || video_fullscreen) { SDL_LockMutex(mousemutex); - mousedata.deltax += event.motion.xrel; - mousedata.deltay += event.motion.yrel; + mouse_scale(event.motion.xrel, event.motion.yrel); SDL_UnlockMutex(mousemutex); } break; @@ -1232,10 +1218,10 @@ main(int argc, char **argv) break; } SDL_LockMutex(mousemutex); - 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); SDL_UnlockMutex(mousemutex); } break; @@ -1323,6 +1309,12 @@ plat_language_code(char *langcode) return 0; } +void +plat_get_cpu_string(char *outbuf, uint8_t len) { + char cpu_string[] = "Unknown"; + strncpy(outbuf, cpu_string, len); +} + /* Converts back the language code to LCID */ void plat_language_code_r(uint32_t lcid, char *outbuf, int len) diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 4cf723b00..e20abbcd6 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -51,9 +51,6 @@ int title_set = 0; int resize_pending = 0; int resize_w = 0; int resize_h = 0; -double mouse_sensitivity = 1.0; /* Unused. */ -double mouse_x_error = 0.0; /* Unused. */ -double mouse_y_error = 0.0; /* Unused. */ static uint8_t interpixels[17842176]; extern void RenderImGui(void); diff --git a/src/unix/unix_serial_passthrough.c b/src/unix/unix_serial_passthrough.c index 61f23c345..78041397e 100644 --- a/src/unix/unix_serial_passthrough.c +++ b/src/unix/unix_serial_passthrough.c @@ -94,6 +94,7 @@ plat_serpt_write_vcon(serial_passthrough_t *dev, uint8_t data) fd_set wrfds; int res; #endif + size_t res; /* We cannot use select here, this would block the hypervisor! */ #if 0 @@ -109,12 +110,11 @@ plat_serpt_write_vcon(serial_passthrough_t *dev, uint8_t data) /* just write it out */ if (dev->mode == SERPT_MODE_HOSTSER) { - int res = 0; do { res = write(dev->master_fd, &data, 1); } while (res == 0 || (res == -1 && (errno == EAGAIN || res == EWOULDBLOCK))); } else - write(dev->master_fd, &data, 1); + res = write(dev->master_fd, &data, 1); } void diff --git a/src/usb.c b/src/usb.c index 0ed98fc12..e6818d849 100644 --- a/src/usb.c +++ b/src/usb.c @@ -317,10 +317,14 @@ ohci_update_irq(usb_t *dev) { uint32_t level = !!(dev->ohci_mmio[OHCI_HcInterruptStatus].l & dev->ohci_mmio[OHCI_HcInterruptEnable].l); +#ifdef STATE_KEEPING if (level != dev->irq_level) { +#endif dev->irq_level = level; usb_interrupt_ohci(dev, level); +#ifdef STATE_KEEPING } +#endif } void diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 3d3d2d466..59205f235 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -18,7 +18,8 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c - vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c + vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68875_ramdac.c + vid_ati68860_ramdac.c vid_bt48x_ramdac.c vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index b4719a539..e24054b93 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -63,30 +63,16 @@ ibm8514_log(const char *fmt, ...) #define READ_PIXTRANS_WORD(cx, n) \ if ((cmd <= 1) || (cmd == 5)) { \ - if (dev->local) { \ - temp = svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } else { \ - temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } \ + temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ } else { \ - if (dev->local) { \ - temp = svga->vram[(dev->accel.dest + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[(dev->accel.dest + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } else { \ - temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } \ + temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \ } #define READ(addr, dat) \ - if (dev->local) { \ - if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - dat = vram_w[(addr) & (svga->vram_mask >> 1)]; \ - } else { \ - dat = (svga->vram[(addr) & (svga->vram_mask)]); \ - } \ + if (dev->bpp) { \ + dat = vram_w[(addr) & (dev->vram_mask >> 1)]; \ } else { \ dat = (dev->vram[(addr) & (dev->vram_mask)]); \ } @@ -194,14 +180,9 @@ ibm8514_log(const char *fmt, ...) } #define WRITE(addr, dat) \ - if (dev->local) { \ - if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - vram_w[((addr)) & (svga->vram_mask >> 1)] = dat; \ - svga->changedvram[(((addr)) & (svga->vram_mask >> 1)) >> 11] = changeframecount; \ - } else { \ - svga->vram[((addr)) & (svga->vram_mask)] = dat; \ - svga->changedvram[(((addr)) & (svga->vram_mask)) >> 12] = changeframecount; \ - } \ + if (dev->bpp) { \ + vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask >> 1)) >> 11] = changeframecount; \ } else { \ dev->vram[((addr)) & (dev->vram_mask)] = dat; \ dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ @@ -536,9 +517,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) case 0x92e8: if (len != 1) dev->test = val; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0xd2e8: if (len == 1) dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; @@ -581,8 +560,10 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->data_available = 0; dev->data_available2 = 0; dev->accel.cmd = val; - if (dev->accel.cmd & 0x100) - dev->accel.cmd_back = 0; + if (port == 0xdae8) { + if (dev->accel.cmd & 0x100) + dev->accel.cmd_back = 0; + } ibm8514_accel_start(-1, 0, -1, 0, svga, len); } break; @@ -980,8 +961,8 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x4ae8: if (!val) break; - dev->accel.advfunc_cntl = val & 7; - ibm8514_on = (dev->accel.advfunc_cntl & 1); + dev->accel.advfunc_cntl = val & 0x0f; + ibm8514_on = val & 0x01; vga_on = !ibm8514_on; ibm8514_log("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); svga_recalctimings(svga); @@ -997,6 +978,7 @@ static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; + ibm8514_accel_out(port, val, svga, 1); } @@ -1004,6 +986,7 @@ static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv) { svga_t *svga = (svga_t *) priv; + ibm8514_accel_out(port, val, svga, 2); } @@ -1013,14 +996,14 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) ibm8514_t *dev = &svga->dev8514; uint32_t temp = 0; int cmd; - int vpos = dev->displine + svga->y_add; + int vpos = 0; int vblankend = svga->vblankstart + svga->crtc[0x16]; switch (port) { case 0x2e8: - vpos = dev->displine + svga->y_add; - if (vblankend > dev->vtotal) { - vblankend -= dev->vtotal; + vpos = dev->vc & 0x7ff; + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; if (vpos >= svga->vblankstart || vpos <= vblankend) temp |= 2; } else { @@ -1053,13 +1036,13 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) break; case 0x42e8: - vpos = dev->displine + svga->y_add; - if (vblankend > dev->vtotal) { - vblankend -= dev->vtotal; + vpos = dev->vc & 0x7ff; + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; if (vpos >= svga->vblankstart || vpos <= vblankend) dev->subsys_stat |= 1; } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) + if (vpos >= svga->vblankstart && vpos <= vblankend) dev->subsys_stat |= 1; } if (len != 1) { @@ -1174,7 +1157,7 @@ void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, UNUSED(int len)) { ibm8514_t *dev = &svga->dev8514; - uint16_t *vram_w = (uint16_t *) svga->vram; + uint16_t *vram_w = (uint16_t *) dev->vram; uint16_t src_dat = 0; uint16_t dest_dat; uint16_t old_dest_dat; @@ -1183,7 +1166,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint16_t clip_b = dev->accel.multifunc[3]; uint16_t clip_r = dev->accel.multifunc[4]; int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; - uint16_t mix_mask = ((svga->bpp == 8) || (svga->bpp == 24)) ? 0x80 : 0x8000; + uint16_t mix_mask = dev->bpp ? 0x8000 : 0x80; uint16_t compare = dev->accel.color_cmp; int compare_mode = dev->accel.multifunc[0x0a] & 0x38; int cmd = dev->accel.cmd >> 13; @@ -1196,7 +1179,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat int and3 = dev->accel.cur_x & 3; uint16_t poly_src = 0; - if ((svga->bpp == 8) || (svga->bpp == 24)) { + if (!dev->bpp) { compare &= 0xff; frgd_color &= 0xff; bkgd_color &= 0xff; @@ -1227,7 +1210,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat count >>= 3; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { + if (dev->bpp) { if ((dev->accel.cmd & 0x200) && (count == 2)) count >>= 1; } @@ -1314,6 +1297,8 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ + ibm8514_log("CMD8514: CMD=%d, full=%04x, ssvdraw=%x.\n", cmd, dev->accel.cmd, dev->accel.ssv_draw); + switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ if (dev->accel.ssv_state == 0) @@ -1358,7 +1343,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -1443,7 +1428,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -1695,7 +1680,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -1788,7 +1773,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.temp_cnt--; mix_dat >>= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -1916,7 +1901,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2022,7 +2007,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) + if ((dev->local >= 2) && dev->accel.ge_offset && (svga->bpp == 24)) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; @@ -2074,7 +2059,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (!(dev->accel.cmd & 0x40) && (frgd_mix == 2) && (bkgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { if (!(dev->accel.sx & 1)) { dev->accel.output = 1; - if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) + if ((dev->local >= 2) && dev->accel.ge_offset && (svga->bpp == 24)) dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); else dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; @@ -2197,7 +2182,7 @@ rect_fill_pix: mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2322,7 +2307,7 @@ rect_fill_pix: mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2350,7 +2335,7 @@ rect_fill_pix: else dev->accel.cy--; - if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) + if ((dev->local >= 2) && dev->accel.ge_offset && (svga->bpp == 24)) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; @@ -2405,7 +2390,7 @@ rect_fill_pix: } } mix_dat >>= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2442,7 +2427,7 @@ rect_fill_pix: else dev->accel.cy--; - if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) + if ((dev->local >= 2) && dev->accel.ge_offset && (svga->bpp == 24)) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); else dev->accel.dest = dev->accel.cy * dev->pitch; @@ -2549,7 +2534,7 @@ rect_fill_pix: } mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2651,7 +2636,7 @@ rect_fill_pix: mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2856,7 +2841,7 @@ rect_fill: } if (poly_src) { - dev->accel.fill_state = !dev->accel.fill_state; + dev->accel.fill_state ^= 1; } if (dev->accel.fill_state) { @@ -3038,7 +3023,7 @@ rect_fill: mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -3224,7 +3209,7 @@ bitblt_pix: mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -3314,7 +3299,7 @@ bitblt_pix: } } mix_dat >>= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -3425,7 +3410,7 @@ bitblt_pix: } mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -3624,7 +3609,7 @@ bitblt: } } } else { - if ((svga->bpp == 24) && dev->local && (dev->accel.cmd == 0xc2b5)) { + if ((svga->bpp == 24) && (dev->local >= 2) && (dev->accel.cmd == 0xc2b5)) { int64_t cx; int64_t dx; @@ -3755,7 +3740,7 @@ bitblt: } } -static void +void ibm8514_render_8bpp(svga_t *svga) { ibm8514_t *dev = &svga->dev8514; @@ -3775,16 +3760,16 @@ ibm8514_render_8bpp(svga_t *svga) for (int x = 0; x <= dev->h_disp; x += 8) { dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); - p[0] = dev->map8[dat & 0xff]; - p[1] = dev->map8[(dat >> 8) & 0xff]; - p[2] = dev->map8[(dat >> 16) & 0xff]; - p[3] = dev->map8[(dat >> 24) & 0xff]; + p[0] = dev->pallook[dat & 0xff]; + p[1] = dev->pallook[(dat >> 8) & 0xff]; + p[2] = dev->pallook[(dat >> 16) & 0xff]; + p[3] = dev->pallook[(dat >> 24) & 0xff]; dat = *(uint32_t *) (&dev->vram[(dev->ma + 4) & dev->vram_mask]); - p[4] = dev->map8[dat & 0xff]; - p[5] = dev->map8[(dat >> 8) & 0xff]; - p[6] = dev->map8[(dat >> 16) & 0xff]; - p[7] = dev->map8[(dat >> 24) & 0xff]; + p[4] = dev->pallook[dat & 0xff]; + p[5] = dev->pallook[(dat >> 8) & 0xff]; + p[6] = dev->pallook[(dat >> 16) & 0xff]; + p[7] = dev->pallook[(dat >> 24) & 0xff]; dev->ma += 8; p += 8; @@ -3793,6 +3778,214 @@ ibm8514_render_8bpp(svga_t *svga) } } +void +ibm8514_render_15bpp(svga_t *svga) +{ + ibm8514_t *dev = &svga->dev8514; + int x; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) { + return; + } + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (x = 0; x <= dev->h_disp; x += 8) { + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1)) & dev->vram_mask]); + p[x] = video_15to32[dat & 0xffff]; + p[x + 1] = video_15to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 4) & dev->vram_mask]); + p[x + 2] = video_15to32[dat & 0xffff]; + p[x + 3] = video_15to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 8) & dev->vram_mask]); + p[x + 4] = video_15to32[dat & 0xffff]; + p[x + 5] = video_15to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 12) & dev->vram_mask]); + p[x + 6] = video_15to32[dat & 0xffff]; + p[x + 7] = video_15to32[dat >> 16]; + } + dev->ma += (x << 1); + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_16bpp(svga_t *svga) +{ + ibm8514_t *dev = &svga->dev8514; + int x; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) { + return; + } + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (x = 0; x <= dev->h_disp; x += 8) { + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1)) & dev->vram_mask]); + p[x] = video_16to32[dat & 0xffff]; + p[x + 1] = video_16to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 4) & dev->vram_mask]); + p[x + 2] = video_16to32[dat & 0xffff]; + p[x + 3] = video_16to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 8) & dev->vram_mask]); + p[x + 4] = video_16to32[dat & 0xffff]; + p[x + 5] = video_16to32[dat >> 16]; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 1) + 12) & dev->vram_mask]); + p[x + 6] = video_16to32[dat & 0xffff]; + p[x + 7] = video_16to32[dat >> 16]; + } + dev->ma += (x << 1); + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_24bpp(svga_t *svga) +{ + ibm8514_t *dev = &svga->dev8514; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (int x = 0; x <= dev->h_disp; x += 4) { + dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); + p[x] = dat & 0xffffff; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + p[x + 1] = dat & 0xffffff; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]); + p[x + 2] = dat & 0xffffff; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]); + p[x + 3] = dat & 0xffffff; + + dev->ma += 12; + } + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_BGR(svga_t *svga) +{ + ibm8514_t *dev = &svga->dev8514; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (int x = 0; x <= dev->h_disp; x += 4) { + dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); + p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + p[x + 1] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]); + p[x + 2] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]); + p[x + 3] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dev->ma += 12; + } + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_ABGR8888(svga_t *svga) +{ + ibm8514_t *dev = &svga->dev8514; + int x; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (x = 0; x <= dev->h_disp; x++) { + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + } + dev->ma += (x * 4); + dev->ma &= dev->vram_mask; + } +} + +void +ibm8514_render_RGBA8888(svga_t *svga) +{ + ibm8514_t *dev = &svga->dev8514; + int x; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + for (x = 0; x <= dev->h_disp; x++) { + dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]); + *p++ = dat >> 8; + } + dev->ma += (x * 4); + dev->ma &= dev->vram_mask; + } +} + static void ibm8514_render_overscan_left(ibm8514_t *dev, svga_t *svga) { @@ -3830,7 +4023,18 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) int wy; if (!dev->linepos) { + if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; + dev->hwcursor_oddeven = 0; + } + + if ((dev->displine == (svga->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); + dev->hwcursor_oddeven = 1; + } + timer_advance_u64(&svga->timer, svga->dispofftime); + svga->cgastat |= 1; dev->linepos = 1; if (dev->dispon) { @@ -3843,6 +4047,9 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) video_wait_for_buffer(); } + if (dev->hwcursor_on) + dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2; + svga->render(svga); svga->x_add = (overscan_x >> 1); @@ -3850,6 +4057,14 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) ibm8514_render_overscan_right(dev, svga); svga->x_add = (overscan_x >> 1); + if (dev->hwcursor_on) { + if (svga->hwcursor_draw) + svga->hwcursor_draw(svga, dev->displine + svga->y_add); + dev->hwcursor_on--; + if (dev->hwcursor_on && dev->interlace) + dev->hwcursor_on--; + } + if (dev->lastline < dev->displine) dev->lastline = dev->displine; } @@ -3857,10 +4072,15 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->displine++; if (dev->interlace) dev->displine++; + if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + svga->vslines++; if (dev->displine > 1500) dev->displine = 0; } else { timer_advance_u64(&svga->timer, svga->dispontime); + if (dev->dispon) + svga->cgastat &= ~1; dev->hdisp_on = 0; dev->linepos = 0; @@ -3874,13 +4094,13 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->ma = dev->maback; } else { dev->sc++; - dev->sc &= 31; + dev->sc &= 0x1f; dev->ma = dev->maback; } } dev->vc++; - dev->vc &= 2047; + dev->vc &= 0x7ff; if (dev->vc == dev->dispend) { dev->dispon = 0; @@ -3895,6 +4115,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) } if (dev->vc == dev->v_syncstart) { dev->dispon = 0; + svga->cgastat |= 8; x = dev->h_disp; if (dev->interlace && !dev->oddeven) @@ -3916,6 +4137,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->oddeven ^= 1; changeframecount = dev->interlace ? 3 : 2; + svga->vslines = 0; if (dev->interlace && dev->oddeven) dev->ma = dev->maback = (dev->rowoffset << 1); @@ -3932,6 +4154,9 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; svga->x_add = (overscan_x >> 1); + + dev->hwcursor_on = 0; + dev->hwcursor_latch = dev->hwcursor; } } } @@ -3950,19 +4175,17 @@ ibm8514_recalctimings(svga_t *svga) dev->rowcount = !!(dev->disp_cntl & 0x08); dev->dispend = ((dev->vdisp >> 1) + 1); if (dev->dispend == 766) - dev->dispend = 768; + dev->dispend += 2; if (dev->dispend == 598) - dev->dispend = 600; + dev->dispend += 2; if (dev->accel.advfunc_cntl & 4) { - if (!vga_on && dev->ibm_mode) { - if (dev->h_disp == 8) { - dev->h_disp = 1024; - dev->dispend = 768; - dev->v_total = 1536; - dev->v_syncstart = 1536; - } + if (dev->h_disp == 8) { + dev->h_disp = 1024; + dev->dispend = 768; + dev->v_total = 1536; + dev->v_syncstart = 1536; } if (dev->dispend == 598) @@ -3977,20 +4200,14 @@ ibm8514_recalctimings(svga_t *svga) dev->v_total >>= 1; } - if (ibm8514_has_vga) { - dev->pitch = dev->ext_pitch; - dev->rowoffset = dev->ext_crt_pitch; - } else - dev->rowoffset = 128; + dev->rowoffset = 0x80; ibm8514_log("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace); svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { - if (!vga_on && dev->ibm_mode) { - if (dev->h_disp == 1024) { - dev->h_disp = 640; - dev->dispend = 480; - } + if (dev->h_disp == 1024) { + dev->h_disp = 640; + dev->dispend = 480; } if (dev->interlace) { @@ -4002,11 +4219,7 @@ ibm8514_recalctimings(svga_t *svga) dev->v_total >>= 1; } - if (ibm8514_has_vga) { - dev->pitch = dev->ext_pitch; - dev->rowoffset = dev->ext_crt_pitch; - } else - dev->rowoffset = 128; + dev->rowoffset = 0x80; svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } @@ -4061,15 +4274,14 @@ ibm8514_init(const device_t *info) dev->vram = calloc(dev->vram_size, 1); dev->changedvram = calloc(dev->vram_size >> 12, 1); dev->vram_mask = dev->vram_size - 1; - dev->map8 = svga->pallook; + dev->map8 = dev->pallook; dev->type = info->flags; - dev->ibm_mode = 1; - dev->bpp = 8; + dev->bpp = 0; ibm8514_io_set(svga); - if (info->flags & DEVICE_MCA) { + if (dev->type & DEVICE_MCA) { dev->pos_regs[0] = 0x7f; dev->pos_regs[1] = 0xef; mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, NULL, svga); diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index 5a8de5455..4038e24d8 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -65,22 +65,22 @@ typedef struct ati68860_ramdac_t { } ati68860_ramdac_t; void -ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; switch (addr) { case 0: - svga_out(0x3c8, val, svga); + svga_out(ibm8514_on ? 0x2ec : 0x3c8, val, svga); break; case 1: - svga_out(0x3c9, val, svga); + svga_out(ibm8514_on ? 0x2ed : 0x3c9, val, svga); break; case 2: - svga_out(0x3c6, val, svga); + svga_out(ibm8514_on ? 0x2ea : 0x3c6, val, svga); break; case 3: - svga_out(0x3c7, val, svga); + svga_out(ibm8514_on ? 0x2eb : 0x3c7, val, svga); break; default: ramdac->regs[addr & 0xf] = val; @@ -168,23 +168,23 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) } uint8_t -ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga) +ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; - uint8_t temp = 0; + const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; + uint8_t temp = 0; switch (addr) { case 0: - temp = svga_in(0x3c8, svga); + temp = svga_in(ibm8514_on ? 0x2ec : 0x3c8, svga); break; case 1: - temp = svga_in(0x3c9, svga); + temp = svga_in(ibm8514_on ? 0x2ed : 0x3c9, svga); break; case 2: - temp = svga_in(0x3c6, svga); + temp = svga_in(ibm8514_on ? 0x2ea : 0x3c6, svga); break; case 3: - temp = svga_in(0x3c7, svga); + temp = svga_in(ibm8514_on ? 0x2eb : 0x3c7, svga); break; case 4: case 8: @@ -207,9 +207,9 @@ ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga) } void -ati68860_set_ramdac_type(void *p, int type) +ati68860_set_ramdac_type(void *priv, int type) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; if (ramdac->ramdac_type != type) { ramdac->ramdac_type = type; @@ -237,17 +237,17 @@ ati68860_ramdac_init(UNUSED(const device_t *info)) } void -ati68860_ramdac_set_render(void *p, svga_t *svga) +ati68860_ramdac_set_render(void *priv, svga_t *svga) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; svga->render = ramdac->render; } void -ati68860_ramdac_set_pallook(void *p, int i, uint32_t col) +ati68860_ramdac_set_pallook(void *priv, int i, uint32_t col) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; ramdac->pallook[i] = col; } @@ -255,11 +255,11 @@ ati68860_ramdac_set_pallook(void *p, int i, uint32_t col) void ati68860_hwcursor_draw(svga_t *svga, int displine) { - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; - int offset; - uint8_t dat; - uint32_t col0 = ramdac->pallook[0]; - uint32_t col1 = ramdac->pallook[1]; + const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; + int offset; + uint8_t dat; + uint32_t col0 = ramdac->pallook[0]; + uint32_t col1 = ramdac->pallook[1]; offset = svga->dac_hwcursor_latch.xoff; for (uint32_t x = 0; x < 64 - svga->dac_hwcursor_latch.xoff; x += 4) { diff --git a/src/video/vid_ati68875_ramdac.c b/src/video/vid_ati68875_ramdac.c new file mode 100644 index 000000000..981b0c40b --- /dev/null +++ b/src/video/vid_ati68875_ramdac.c @@ -0,0 +1,219 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Mach32-compatible ATI 68875 RAMDAC and clones. + * + * + * + * Authors: TheCollector1995. + * + * Copyright 2022-2023 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> + +typedef struct ati68875_ramdac_t { + uint8_t gen_cntl; + uint8_t in_clk_sel; + uint8_t out_clk_sel; + uint8_t mux_cntl; + uint8_t palette_page_sel; + uint8_t test_reg; +} ati68875_ramdac_t; + +static void +ati68875_set_bpp(ati68875_ramdac_t *ramdac, svga_t *svga) +{ + if (ramdac->mux_cntl == 0xff) + return; + + if (ramdac->mux_cntl & 0x20) + svga->bpp = 8; + else { + svga->bpp = 24; + } + svga_recalctimings(svga); +} + +void +ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) +{ + ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) p; + uint8_t rs = (addr & 0x03); + + rs |= (!!rs2 << 2); + rs |= (!!rs3 << 3); + + switch (rs) { + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + case 0x03: + svga_out(addr, val, svga); + break; + case 0x08: /* General Control Register (RS value = 1000) */ + ramdac->gen_cntl = val; + break; + case 0x09: /* Input Clock Selection Register (RS value = 1001) */ + ramdac->in_clk_sel = val; + break; + case 0x0a: /* Output Clock Selection Register (RS value = 1010) */ + ramdac->out_clk_sel = val; + break; + case 0x0b: /* MUX Control Register (RS value = 1011) */ + ramdac->mux_cntl = val; + ati68875_set_bpp(ramdac, svga); + break; + case 0x0c: /* Palette Page Register (RS value = 1100) */ + ramdac->palette_page_sel = val; + break; + case 0x0e: /* Test Register (RS value = 1110) */ + ramdac->test_reg = val; + break; + case 0x0f: /* Reset State (RS value = 1111) */ + ramdac->mux_cntl = 0x2d; + svga->bpp = 8; + svga_recalctimings(svga); + break; + } + + return; +} + +uint8_t +ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) +{ + ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) p; + ibm8514_t *dev = &svga->dev8514; + uint8_t rs = (addr & 0x03); + uint8_t temp = 0; + + rs |= (!!rs2 << 2); + rs |= (!!rs3 << 3); + + switch (rs) { + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + case 0x03: + temp = svga_in(addr, svga); + break; + case 0x08: /* General Control Register (RS value = 1000) */ + temp = ramdac->gen_cntl; + break; + case 0x09: /* Input Clock Selection Register (RS value = 1001) */ + temp = ramdac->in_clk_sel; + break; + case 0x0a: /* Output Clock Selection Register (RS value = 1010) */ + temp = ramdac->out_clk_sel; + break; + case 0x0b: /* MUX Control Register (RS value = 1011) */ + temp = ramdac->mux_cntl; + break; + case 0x0c: /* Palette Page Register (RS value = 1100) */ + temp = ramdac->palette_page_sel; + break; + case 0x0e: /* Test Register (RS value = 1110) */ + switch (ramdac->test_reg & 0x07) { + case 0x00: + temp = ibm8514_on ? dev->dac_r : svga->dac_r; + break; + case 0x01: + temp = ibm8514_on ? dev->dac_g : svga->dac_g; + break; + case 0x02: + temp = ibm8514_on ? dev->dac_b : svga->dac_b; + break; + case 0x03: + temp = 0x75; + break; + case 0x04: + if (ibm8514_on) { + dev->dac_r++; + temp = dev->dac_r; + } else { + svga->dac_r++; + temp = svga->dac_r; + } + break; + case 0x05: + if (ibm8514_on) { + dev->dac_g++; + temp = dev->dac_g; + } else { + svga->dac_g++; + temp = svga->dac_g; + } + break; + case 0x06: + if (ibm8514_on) { + dev->dac_b++; + temp = dev->dac_b; + } else { + svga->dac_b++; + temp = svga->dac_b; + } + break; + case 0x07: + if (ramdac->test_reg & 0x80) + temp = ibm8514_on ? dev->dac_r : svga->dac_r; + else if (ramdac->test_reg & 0x40) + temp = ibm8514_on ? dev->dac_g : svga->dac_g; + else if (ramdac->test_reg & 0x20) + temp = ibm8514_on ? dev->dac_b : svga->dac_b; + break; + } + break; + } + + return temp; +} + +static void * +ati68875_ramdac_init(const device_t *info) +{ + ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) malloc(sizeof(ati68875_ramdac_t)); + memset(ramdac, 0, sizeof(ati68875_ramdac_t)); + + ramdac->mux_cntl = 0x2d; + + return ramdac; +} + +static void +ati68875_ramdac_close(void *priv) +{ + ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + +const device_t ati68875_ramdac_device = { + .name = "ATI 68875 RAMDAC", + .internal_name = "ati68875_ramdac", + .flags = 0, + .local = 0, + .init = ati68875_ramdac_init, + .close = ati68875_ramdac_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index 2f4746e86..054d83d36 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -94,9 +94,7 @@ ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) if (!dat) break; eeprom->state = EEPROM_OPCODE; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case EEPROM_OPCODE: eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0); eeprom->count--; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index c28d4c0aa..2e05a6e03 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -94,9 +94,11 @@ typedef struct mach64_t { int type; int pci; + uint8_t pci_slot; + uint8_t irq_state; + uint8_t pci_regs[256]; uint8_t int_line; - int card; int bank_r[2]; int bank_w[2]; @@ -437,12 +439,12 @@ mach64_out(uint16_t addr, uint8_t val, void *priv) svga->crtcreg = val & 0x3f; return; case 0x3D5: + if (svga->crtcreg > 0x20) + return; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg > 0x18) - return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; @@ -452,7 +454,7 @@ mach64_out(uint16_t addr, uint8_t val, void *priv) svga->fullchange = 3; svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { - svga->fullchange = changeframecount; + svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); } } @@ -491,7 +493,7 @@ mach64_in(uint16_t addr, void *priv) case 0x3D4: return svga->crtcreg; case 0x3D5: - if (svga->crtcreg > 0x18) + if (svga->crtcreg > 0x20) return 0xff; return svga->crtc[svga->crtcreg]; @@ -647,9 +649,9 @@ mach64_update_irqs(mach64_t *mach64) } if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) - pci_set_irq(mach64->card, PCI_INTA); + pci_set_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state); else - pci_clear_irq(mach64->card, PCI_INTA); + pci_clear_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state); } static __inline void @@ -738,9 +740,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) case 0x11e: case 0x11f: WRITE8(addr, mach64->dst_height_width, val); -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x113: if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || (addr & 0x3ff) == 0x113) && !(val & 0x80)) { mach64_start_fill(mach64); @@ -963,9 +963,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) case 0x2a4: case 0x2a5: addr += 2; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x2aa: case 0x2ab: WRITE8(addr, mach64->sc_left_right, val); @@ -980,9 +978,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) case 0x2b0: case 0x2b1: addr += 2; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x2b6: case 0x2b7: WRITE8(addr, mach64->sc_top_bottom, val); @@ -1525,13 +1521,13 @@ mach64_start_line(mach64_t *mach64) #define WRITE(addr, width) \ if (width == 0) { \ svga->vram[(addr) &mach64->vram_mask] = dest_dat; \ - svga->changedvram[((addr) &mach64->vram_mask) >> 12] = changeframecount; \ + svga->changedvram[((addr) &mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } else if (width == 1) { \ *(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \ + svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } else if (width == 2) { \ *(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \ + svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } else { \ if (dest_dat & 1) { \ if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ @@ -1544,7 +1540,7 @@ mach64_start_line(mach64_t *mach64) else \ svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << (7 - ((addr) &7))); \ } \ - svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \ + svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } void @@ -3073,7 +3069,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) case 0x17: WRITE8(addr, mach64->crtc_off_pitch, val); svga_recalctimings(&mach64->svga); - svga->fullchange = changeframecount; + svga->fullchange = svga->monitor->mon_changeframecount; break; case 0x18: @@ -4401,7 +4397,7 @@ mach64_common_init(const device_t *info) mach64_io_set(mach64); if (info->flags & DEVICE_PCI) - mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64); + pci_add_card(PCI_ADD_NORMAL, mach64_pci_read, mach64_pci_write, mach64, &mach64->pci_slot); mach64->pci_regs[PCI_REG_COMMAND] = 3; mach64->pci_regs[0x30] = 0x00; @@ -4545,7 +4541,7 @@ mach64_force_redraw(void *priv) { mach64_t *mach64 = (mach64_t *) priv; - mach64->svga.fullchange = changeframecount; + mach64->svga.fullchange = mach64->svga.monitor->mon_changeframecount; } // clang-format off diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 1aa55bd6b..012703bee 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -41,25 +41,33 @@ #include <86box/vid_ati_eeprom.h> #define BIOS_MACH8_ROM_PATH "roms/video/mach8/BIOS.BIN" -#define BIOS_MACH32_ISA_ROM_PATH "roms/video/mach32/MACH32ISA.VBI" +#define BIOS_MACH32_ISA_ROM_PATH "roms/video/mach32/ATi Mach32 Graphics Pro ISA.BIN" #define BIOS_MACH32_VLB_ROM_PATH "roms/video/mach32/MACH32VLB.VBI" -#define BIOS_MACH32_PCI_ROM_PATH "roms/video/mach32/MACH32PCI.BIN" +#define BIOS_MACH32_MCA_ROM_PATH "roms/video/mach32/MACH32MCA_Olivetti.BIN" +#define BIOS_MACH32_PCI_ROM_PATH "roms/video/mach32/intelopt_00000.rom" typedef struct mach_t { ati_eeprom_t eeprom; svga_t svga; rom_t bios_rom; + rom_t bios_rom2; mem_mapping_t mmio_linear_mapping; - int mca_bus; - int pci_bus; - int vlb_bus; + int mca_bus; + int pci_bus; + int vlb_bus; + int has_bios; + uint8_t regs[256]; uint8_t pci_regs[256]; uint8_t int_line; - int card; - int index; + uint8_t pci_slot; + uint8_t irq_state; + + int index; + int ramdac_type; + int old_mode; uint32_t memory; @@ -67,14 +75,20 @@ typedef struct mach_t { uint16_t config2; uint8_t pos_regs[8]; + uint8_t pci_cntl_reg; uint8_t cursor_col_0; uint8_t cursor_col_1; uint8_t ext_cur_col_0_r; uint8_t ext_cur_col_1_r; uint8_t ext_cur_col_0_g; uint8_t ext_cur_col_1_g; + uint16_t cursor_col_0_rg; + uint16_t cursor_col_1_rg; + uint16_t cursor_col_b; uint16_t cursor_offset_lo; uint16_t cursor_offset_hi; + uint16_t cursor_offset_hi_reg; + uint16_t cursor_vh_offset; uint16_t cursor_x; uint16_t cursor_y; uint16_t misc; @@ -84,6 +98,7 @@ typedef struct mach_t { uint8_t ap_size; uint8_t bank_w; uint8_t bank_r; + uint16_t shadow_set; struct { uint8_t line_idx; @@ -165,17 +180,18 @@ typedef struct mach_t { } accel; atomic_int force_busy; - atomic_int force_busy2; } mach_t; static video_timings_t timing_gfxultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; static video_timings_t timing_mach32_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; +static video_timings_t timing_mach32_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; static video_timings_t timing_mach32_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; static void mach_accel_outb(uint16_t port, uint8_t val, void *priv); static void mach_accel_outw(uint16_t port, uint16_t val, void *priv); static uint8_t mach_accel_inb(uint16_t port, void *priv); static uint16_t mach_accel_inw(uint16_t port, void *priv); +static uint8_t mach_in(uint16_t addr, void *priv); static void mach32_updatemapping(mach_t *mach); @@ -197,64 +213,67 @@ mach_log(const char *fmt, ...) # define mach_log(fmt, ...) #endif -#define READ_PIXTRANS_BYTE_IO(cx, n, vgacore) \ - if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ - if (vgacore) { \ - if ((svga->bpp == 15) || (svga->bpp == 16)) \ - if (n == 0) \ - mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (svga->vram_mask >> 1)] & 0xff; \ - else \ - mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (svga->vram_mask >> 1)] >> 8; \ - else \ - mach->accel.pix_trans[(n)] = svga->vram[(dev->accel.dest + (cx) + (n)) & svga->vram_mask]; \ - } else \ - mach->accel.pix_trans[(n)] = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ +#define WRITE8(addr, var, val) \ + switch ((addr) & 1) { \ + case 0: \ + var = (var & 0xff00) | (val); \ + break; \ + case 1: \ + var = (var & 0x00ff) | ((val) << 8); \ + break; \ } -#define READ_PIXTRANS_WORD(cx, n, vgacore) \ +#define READ8(addr, var) \ + switch ((addr) & 1) { \ + case 0: \ + temp = (var) & 0xff; \ + break; \ + case 1: \ + temp = ((var) >> 8) & 0xff; \ + break; \ + } + +#define READ_PIXTRANS_BYTE_IO(cx, n) \ + if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ + if (dev->bpp) { \ + if (n == 0) \ + mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (dev->vram_mask >> 1)] & 0xff; \ + else \ + mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (dev->vram_mask >> 1)] >> 8; \ + } else { \ + mach->accel.pix_trans[(n)] = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ + } \ + } + +#define READ_PIXTRANS_WORD(cx, n) \ if ((cmd == 0) || (cmd == 1) || (cmd == 5) || (mach->accel.cmd_type == -1)) { \ - if (vgacore) { \ - if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (svga->vram_mask >> 1)]; \ - } else { \ - temp = svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } \ + if (dev->bpp) { \ + temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ } else { \ temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ } \ } else if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ - if ((svga->bpp == 8) || (svga->bpp == 24)) { \ - if (vgacore) { \ - temp = svga->vram[((dev->accel.dest) + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[((dev->accel.dest) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } else { \ - temp = dev->vram[((dev->accel.dest) + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[((dev->accel.dest) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } \ - } else if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - temp = vram_w[((dev->accel.dest) + (cx) + (n)) & (svga->vram_mask >> 1)]; \ + if (!dev->bpp) { \ + temp = dev->vram[((dev->accel.dest) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.dest) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } else { \ + temp = vram_w[((dev->accel.dest) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ } \ } else if ((mach->accel.cmd_type == 3) || (mach->accel.cmd_type == 4)) { \ - if ((svga->bpp == 8) || (svga->bpp == 24)) { \ - if (vgacore) { \ - temp = svga->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } else { \ - temp = dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } \ - } else if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - temp = vram_w[((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & (svga->vram_mask >> 1)]; \ + if (!dev->bpp) { \ + temp = dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } else { \ + temp = vram_w[((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ } \ } -#define READ(addr, dat, vgacore) \ - if ((svga->bpp == 8) || (svga->bpp == 24)) \ - dat = vgacore ? (svga->vram[(addr) & (svga->vram_mask)]) : (dev->vram[(addr) & (dev->vram_mask)]); \ - else if ((svga->bpp == 15) || (svga->bpp == 16)) \ - dat = vram_w[(addr) & (svga->vram_mask >> 1)]; +#define READ(addr, dat) \ + if (!dev->bpp) \ + dat = dev->vram[(addr) & (dev->vram_mask)]; \ + else \ + dat = vram_w[(addr) & (dev->vram_mask >> 1)]; #define MIX(mixmode, dest_dat, src_dat) \ { \ @@ -359,18 +378,13 @@ mach_log(const char *fmt, ...) } -#define WRITE(addr, dat, vgacore) \ - if ((svga->bpp == 8) || (svga->bpp == 24)) { \ - if (vgacore) { \ - svga->vram[((addr)) & (svga->vram_mask)] = dat; \ - svga->changedvram[(((addr)) & (svga->vram_mask)) >> 12] = changeframecount; \ - } else { \ - dev->vram[((addr)) & (dev->vram_mask)] = dat; \ - dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ - } \ - } else if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - vram_w[((addr)) & (svga->vram_mask >> 1)] = dat; \ - svga->changedvram[(((addr)) & (svga->vram_mask >> 1)) >> 11] = changeframecount; \ +#define WRITE(addr, dat) \ + if (!dev->bpp) { \ + dev->vram[((addr)) & (dev->vram_mask)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ + } else { \ + vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask >> 1)) >> 11] = changeframecount; \ } static int @@ -392,31 +406,31 @@ mach_pixel_read(mach_t *mach) } static void -mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint32_t cpu_dat, mach_t *mach, ibm8514_t *dev, UNUSED(int len)) +mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint32_t cpu_dat, mach_t *mach, ibm8514_t *dev) { - svga_t *svga = &mach->svga; - int compare_mode; - int poly_src = 0; - uint16_t rd_mask = dev->accel.rd_mask; - uint16_t wrt_mask = dev->accel.wrt_mask; - uint16_t dest_cmp_clr = dev->accel.color_cmp; - int frgd_sel; - int bkgd_sel; - int mono_src; - int compare = 0; - uint16_t src_dat = 0; - uint16_t dest_dat = 0; - uint16_t old_dest_dat; - uint16_t *vram_w = (uint16_t *) svga->vram; - uint16_t mix = 0; - int16_t clip_l = dev->accel.clip_left & 0x7ff; - int16_t clip_t = dev->accel.clip_top & 0x7ff; - int16_t clip_r = dev->accel.multifunc[4] & 0x7ff; - int16_t clip_b = dev->accel.multifunc[3] & 0x7ff; - uint32_t mono_dat0 = 0; - uint32_t mono_dat1 = 0; + const svga_t *svga = &mach->svga; + int compare_mode; + int poly_src = 0; + uint16_t rd_mask = dev->accel.rd_mask; + uint16_t wrt_mask = dev->accel.wrt_mask; + uint16_t dest_cmp_clr = dev->accel.color_cmp; + int frgd_sel; + int bkgd_sel; + int mono_src; + int compare = 0; + uint16_t src_dat = 0; + uint16_t dest_dat = 0; + uint16_t old_dest_dat; + uint16_t *vram_w = (uint16_t *) dev->vram; + uint16_t mix = 0; + int16_t clip_l = dev->accel.clip_left & 0x7ff; + int16_t clip_t = dev->accel.clip_top & 0x7ff; + int16_t clip_r = dev->accel.multifunc[4] & 0x7ff; + int16_t clip_b = dev->accel.multifunc[3] & 0x7ff; + uint32_t mono_dat0 = 0; + uint32_t mono_dat1 = 0; - if ((svga->bpp == 8) || (svga->bpp == 24)) { + if (!dev->bpp) { rd_mask &= 0xff; dest_cmp_clr &= 0xff; } @@ -430,13 +444,12 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { mach->force_busy = 1; - mach->force_busy2 = 1; dev->force_busy = 1; dev->force_busy2 = 1; } if (cpu_input) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { + if (dev->bpp) { if ((mach->accel.dp_config & 0x200) && (count == 2)) { count >>= 1; } @@ -514,7 +527,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix = 1; break; case 1: - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat >>= 8; } @@ -539,10 +552,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } break; case 3: - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); } mix = (mix & rd_mask) == rd_mask; break; @@ -553,10 +566,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { if (mach->accel.linedraw_opt & 0x02) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); } poly_src = ((poly_src & rd_mask) == rd_mask); if (poly_src) @@ -578,10 +591,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach_pixel_read(mach)) src_dat = cpu_dat; else { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); } if (mono_src == 3) { src_dat = (src_dat & rd_mask) == rd_mask; @@ -599,10 +612,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } } @@ -644,17 +657,17 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.dp_config & 0x10) { if (mach->accel.linedraw_opt & 0x04) { if (dev->accel.sx < mach->accel.width) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } } } else { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } } } @@ -665,10 +678,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; switch (mach->accel.linedraw_opt & 0xe0) { case 0x00: @@ -725,7 +738,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix = 1; break; case 1: - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat >>= 8; } @@ -750,10 +763,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } break; case 3: - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); } mix = (mix & rd_mask) == rd_mask; break; @@ -764,10 +777,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { if (mach->accel.linedraw_opt & 0x02) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); } poly_src = ((poly_src & rd_mask) == rd_mask); if (poly_src) @@ -789,10 +802,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach_pixel_read(mach)) src_dat = cpu_dat; else { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); } if (mono_src == 3) { src_dat = (src_dat & rd_mask) == rd_mask; @@ -810,10 +823,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } } @@ -855,17 +868,17 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.dp_config & 0x10) { if (mach->accel.linedraw_opt & 0x04) { if (dev->accel.sx < mach->accel.width) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } } } else { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat); } } } @@ -876,10 +889,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.linedraw_opt & 0x40) { dev->accel.dy += mach->accel.stepy; @@ -985,7 +998,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } dev->accel.sy = 0; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); else dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); @@ -1025,7 +1038,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach_log("BitBLT: Src Indeterminate X: width = %d, coordinates: %d,%d px, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); } mach->accel.sx = 0; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); else dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); @@ -1077,7 +1090,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (frgd_sel == 5) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { + if (dev->bpp) { for (int x = 0; x <= mach->accel.patt_len; x += 2) { mach->accel.color_pattern_word[x + (mach->accel.color_pattern_idx & 1)] = (mach->accel.patt_data[x & mach->accel.patt_len] & 0xff); mach->accel.color_pattern_word[x + (mach->accel.color_pattern_idx & 1)] |= (mach->accel.patt_data[(x + 1) & mach->accel.patt_len] << 8); @@ -1158,7 +1171,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } break; case 3: - READ(dev->accel.src + ((dev->accel.cx)), mix, dev->local); + READ(dev->accel.src + ((dev->accel.cx)), mix); mix = (mix & rd_mask) == rd_mask; break; @@ -1168,7 +1181,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { if (mach->accel.dp_config & 0x02) { - READ(dev->accel.src + (dev->accel.cx), poly_src, dev->local); + READ(dev->accel.src + (dev->accel.cx), poly_src); poly_src = ((poly_src & rd_mask) == rd_mask); if (poly_src) mach->accel.poly_fill = !mach->accel.poly_fill; @@ -1189,7 +1202,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach_pixel_read(mach)) src_dat = cpu_dat; else { - READ(dev->accel.src + (dev->accel.cx), src_dat, dev->local); + READ(dev->accel.src + (dev->accel.cx), src_dat); if (mono_src == 3) { src_dat = (src_dat & rd_mask) == rd_mask; } @@ -1197,7 +1210,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; case 5: if (mix) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { + if (dev->bpp) { src_dat = mach->accel.color_pattern_word[mach->accel.color_pattern_idx]; } else { src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; @@ -1213,12 +1226,12 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if ((svga->bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { if (dev->accel.sy & 1) { - READ(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat, dev->local); + READ(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); } else { - READ(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + READ(dev->accel.dest + dev->accel.dx, dest_dat); } } else { - READ(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + READ(dev->accel.dest + dev->accel.dx, dest_dat); } switch (compare_mode) { @@ -1259,20 +1272,20 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.dp_config & 0x10) { if ((svga->bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { if (dev->accel.sy & 1) { - WRITE(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat, dev->local); + WRITE(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); } else { - WRITE(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } else { - WRITE(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } } - if ((svga->bpp == 8) || (svga->bpp == 24)) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if ((mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3)) { dev->accel.cx += mach->accel.src_stepx; @@ -1284,7 +1297,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else dev->accel.cx -= mach->accel.src_width; dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1); - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); else dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); @@ -1312,7 +1325,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.color_pattern_idx = 0; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { + if (dev->bpp) { mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; } @@ -1329,7 +1342,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.dy += mach->accel.stepy; dev->accel.sy++; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); else { dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); @@ -1454,10 +1467,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { @@ -1495,10 +1508,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } else @@ -1507,10 +1520,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (!count) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.err >= 0) { dev->accel.cy += mach->accel.stepy; @@ -1576,10 +1589,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { @@ -1620,17 +1633,17 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { if (mach->accel.linedraw_opt & 0x04) { if (dev->accel.sx < mach->accel.width) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } else { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } @@ -1640,10 +1653,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.sx >= mach->accel.width) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.err >= 0) { dev->accel.cy += mach->accel.stepy; @@ -1698,10 +1711,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { case 1: @@ -1739,10 +1752,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } else @@ -1751,10 +1764,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (!count) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.err >= 0) { dev->accel.cx += mach->accel.stepx; @@ -1820,10 +1833,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { @@ -1864,17 +1877,17 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { if (mach->accel.linedraw_opt & 0x04) { if (dev->accel.sx < mach->accel.width) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } else { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } @@ -1884,10 +1897,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.sx >= mach->accel.width) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.err >= 0) { dev->accel.cx += mach->accel.stepx; @@ -1959,7 +1972,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.stepy = 0; } - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); else dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); @@ -1996,7 +2009,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } mach->accel.sx = 0; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); else dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); @@ -2063,7 +2076,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix = 1; break; case 1: - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat >>= 8; } @@ -2088,7 +2101,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } break; case 3: - READ(dev->accel.src + (dev->accel.cx), mix, dev->local); + READ(dev->accel.src + (dev->accel.cx), mix); mix = (mix & rd_mask) == rd_mask; break; @@ -2111,7 +2124,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach_pixel_read(mach)) src_dat = cpu_dat; else { - READ(dev->accel.src + (dev->accel.cx), src_dat, dev->local); + READ(dev->accel.src + (dev->accel.cx), src_dat); if (mono_src == 3) { src_dat = (src_dat & rd_mask) == rd_mask; } @@ -2134,7 +2147,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - READ(dev->accel.dest + (dev->accel.dx), dest_dat, dev->local); + READ(dev->accel.dest + (dev->accel.dx), dest_dat); switch (compare_mode) { case 1: @@ -2172,14 +2185,14 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (mach->accel.dp_config & 0x10) { - WRITE(dev->accel.dest + (dev->accel.dx), dest_dat, dev->local); + WRITE(dev->accel.dest + (dev->accel.dx), dest_dat); } } - if ((svga->bpp == 8) || (svga->bpp == 24)) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; dev->accel.cx += mach->accel.src_stepx; mach->accel.sx++; @@ -2190,7 +2203,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } else dev->accel.cx -= mach->accel.src_width; dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1); - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); else dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); @@ -2217,7 +2230,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.sx >= mach->accel.width) { dev->accel.sx = 0; dev->accel.dy += mach->accel.stepy; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); else dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); @@ -2236,7 +2249,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } static void -mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, UNUSED(uint16_t port), uint16_t val, uint16_t len) +mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, UNUSED(uint16_t port), uint16_t val, UNUSED(uint16_t len)) { int frgd_sel; int bkgd_sel; @@ -2254,25 +2267,25 @@ mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, UNUSED(uint16_t port), uin case 0x000: /*8-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { - if ((mach->accel.dp_config & 0x1000) && dev->local) + if ((mach->accel.dp_config & 0x1000) && (dev->local >= 2)) val = (val >> 8) | (val << 8); - mach_accel_start(mach->accel.cmd_type, 1, 8, val | (val << 16), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 8, val | (val << 16), 0, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev); break; case 0x200: /*16-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { if (mach->accel.dp_config & 0x1000) val = (val >> 8) | (val << 8); - mach_accel_start(mach->accel.cmd_type, 1, 16, val | (val << 16), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 16, val | (val << 16), 0, mach, dev); } else { - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev); } } else { - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev); } break; @@ -2289,6 +2302,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) const ibm8514_t *dev = &svga->dev8514; uint8_t old; uint8_t rs2; + uint8_t rs3; if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -2311,7 +2325,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) svga_recalctimings(svga); break; case 0xad: - if (dev->local) { + if (dev->local >= 2) { if ((old ^ val) & 0x0c) svga_recalctimings(svga); } @@ -2327,7 +2341,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) if (mach->regs[0xbe] & 0x08) { /* Read/write bank mode */ mach->bank_r = (((mach->regs[0xb2] & 1) << 3) | ((mach->regs[0xb2] & 0xe0) >> 5)); mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1); - if (dev->local) { + if (dev->local >= 2) { mach->bank_r |= ((mach->regs[0xae] & 0x0c) << 2); mach->bank_w |= ((mach->regs[0xae] & 3) << 4); } @@ -2335,7 +2349,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) mach_log("Separate B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); } else { /* Single bank mode */ mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1); - if (dev->local) { + if (dev->local >= 2) { mach->bank_w |= ((mach->regs[0xae] & 3) << 4); } mach->bank_r = mach->bank_w; @@ -2359,11 +2373,11 @@ mach_out(uint16_t addr, uint8_t val, void *priv) ati_eeprom_write(&mach->eeprom, val & 8, val & 2, val & 1); break; case 0xb6: - if ((old ^ val) & 0x10) + if ((old ^ val) & 0x11) svga_recalctimings(svga); break; case 0xb8: - if (dev->local) { + if (dev->local >= 2) { if ((old ^ val) & 0x40) svga_recalctimings(svga); } else { @@ -2386,11 +2400,12 @@ mach_out(uint16_t addr, uint8_t val, void *priv) case 0x2ec: case 0x2ed: rs2 = !!(mach->accel.ext_ge_config & 0x1000); - if (dev->local) { - if (mach->pci_bus) - ati68860_ramdac_out((addr & 3) | (rs2 << 2), val, svga->ramdac, svga); + rs3 = !!(mach->accel.ext_ge_config & 0x2000); + if (dev->local >= 2) { + if (mach->pci_bus && !mach->ramdac_type) + ati68860_ramdac_out((addr & 3) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); else - svga_out(addr, val, svga); + ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else svga_out(addr, val, svga); return; @@ -2399,12 +2414,13 @@ mach_out(uint16_t addr, uint8_t val, void *priv) case 0x3C7: case 0x3C8: case 0x3C9: - rs2 = !!(mach->accel.ext_ge_config & 0x1000); - if (dev->local) { - if (mach->pci_bus) - ati68860_ramdac_out((addr & 3) | (rs2 << 2), val, svga->ramdac, svga); + rs2 = !!(mach->regs[0xa0] & 0x20); + rs3 = !!(mach->regs[0xa0] & 0x40); + if (dev->local >= 2) { + if (mach->pci_bus && !mach->ramdac_type) + ati68860_ramdac_out((addr & 3) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); else - svga_out(addr, val, svga); + ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else svga_out(addr, val, svga); return; @@ -2423,9 +2439,11 @@ mach_out(uint16_t addr, uint8_t val, void *priv) svga->crtcreg = val & 0x3f; return; case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + if (svga->crtcreg & 0x20) return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80) && !(mach->regs[0xb4] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80) && !(mach->regs[0xb4] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); old = svga->crtc[svga->crtcreg]; @@ -2443,6 +2461,17 @@ mach_out(uint16_t addr, uint8_t val, void *priv) } break; + case 0x46e8: + io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mach->mmio_linear_mapping); + if (val & 8) { + io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + mem_mapping_enable(&svga->mapping); + mach32_updatemapping(mach); + } + break; + default: break; } @@ -2455,8 +2484,9 @@ mach_in(uint16_t addr, void *priv) mach_t *mach = (mach_t *) priv; svga_t *svga = &mach->svga; const ibm8514_t *dev = &svga->dev8514; - uint8_t temp; + uint8_t temp = 0xff; uint8_t rs2; + uint8_t rs3; if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -2475,7 +2505,7 @@ mach_in(uint16_t addr, void *priv) break; case 0xb0: temp = mach->regs[0xb0] | 0x80; - if (dev->local) { /*Mach32 VGA 1MB memory*/ + if (dev->local >= 2) { /*Mach32 VGA 1MB memory*/ temp |= 0x08; temp &= ~0x10; } else { /*ATI 28800 VGA 512kB memory*/ @@ -2500,40 +2530,40 @@ mach_in(uint16_t addr, void *priv) case 0x2ec: case 0x2ed: rs2 = !!(mach->accel.ext_ge_config & 0x1000); - if (dev->local) { - if (mach->pci_bus) - return ati68860_ramdac_in((addr & 3) | (rs2 << 2), svga->ramdac, svga); + rs3 = !!(mach->accel.ext_ge_config & 0x2000); + if (dev->local >= 2) { + if (mach->pci_bus && !mach->ramdac_type) + temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga); else - return svga_in(addr, svga); - } - return svga_in(addr, svga); + temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + } else + temp = svga_in(addr, svga); + break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - rs2 = !!(mach->accel.ext_ge_config & 0x1000); - if (dev->local) { - if (mach->pci_bus) - return ati68860_ramdac_in((addr & 3) | (rs2 << 2), svga->ramdac, svga); + rs2 = !!(mach->regs[0xa0] & 0x20); + rs3 = !!(mach->regs[0xa0] & 0x40); + if (dev->local >= 2) { + if (mach->pci_bus && !mach->ramdac_type) + temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga); else - return svga_in(addr, svga); - } - return svga_in(addr, svga); + temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + } else + temp = svga_in(addr, svga); + break; case 0x3D4: temp = svga->crtcreg; break; case 0x3D5: - temp = svga->crtc[svga->crtcreg]; - break; - case 0x3DA: - svga->attrff = 0; - if (svga->cgastat & 0x01) - svga->cgastat &= ~0x38; + if (svga->crtcreg & 0x20) + temp = 0xff; else - svga->cgastat ^= 0x38; - return svga->cgastat; + temp = svga->crtc[svga->crtcreg]; + break; default: temp = svga_in(addr, svga); @@ -2547,61 +2577,16 @@ mach_recalctimings(svga_t *svga) { const mach_t *mach = (mach_t *) svga->priv; ibm8514_t *dev = &svga->dev8514; + int clock_sel; - if (vga_on && !ibm8514_on) { - switch (((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0c) >> 2)) { - case 0x00: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 42954000.0; - break; - case 0x01: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 48771000.0; - break; - case 0x02: - mach_log("clock 2\n"); - break; - case 0x03: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 36000000.0; - break; - case 0x04: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; - break; - case 0x05: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 56640000.0; - break; - case 0x06: - mach_log("clock 2\n"); - break; - case 0x07: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - break; - case 0x08: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 30240000.0; - break; - case 0x09: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 32000000.0; - break; - case 0x0A: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 37500000.0; - break; - case 0x0B: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 39000000.0; - break; - case 0x0C: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; - break; - case 0x0D: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 56644000.0; - break; - case 0x0E: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0; - break; - case 0x0F: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0; - break; + clock_sel = ((svga->miscout >> 2) & 3) | ((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1); - default: - break; - } + if (dev->local >= 2) { + if (mach->regs[0xad] & 0x04) + svga->ma_latch |= 0x40000; + + if (mach->regs[0xad] & 0x08) + svga->ma_latch |= 0x80000; } if (mach->regs[0xa3] & 0x10) @@ -2610,35 +2595,6 @@ mach_recalctimings(svga_t *svga) if (mach->regs[0xb0] & 0x40) svga->ma_latch |= 0x20000; - if (dev->local) { - if (mach->regs[0xad] & 0x04) - svga->ma_latch |= 0x40000; - - if (mach->regs[0xad] & 0x08) - svga->ma_latch |= 0x80000; - - if (mach->regs[0xb8] & 0x40) - svga->clock *= 2; - } else { - switch (mach->regs[0xb8] & 0xc0) { - case 0x40: - svga->clock *= 2; - break; - case 0x80: - svga->clock *= 3; - break; - case 0xc0: - svga->clock *= 4; - break; - - default: - break; - } - } - - if (mach->regs[0xa7] & 0x80) - svga->clock *= 3; - if (mach->regs[0xb6] & 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; @@ -2650,137 +2606,209 @@ mach_recalctimings(svga_t *svga) svga->gdcreg[5] |= 0x40; } - if (vga_on && !ibm8514_on) { - if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: - case 0x60: /*256+ colours*/ - switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else { - svga->render = svga_render_8bpp_highres; - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; - } - break; + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if (((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { + if (!ibm8514_on) { + mach_log("VGA ON.\n"); + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + if (mach->regs[0xa7] & 0x80) + svga->clock *= 3; + } + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } + break; - default: - break; - } + default: + break; + } + break; + + default: + break; + } + } + } + + if (dev->local >= 2) { + if (ibm8514_on) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + dev->h_disp = (dev->hdisp + 1) << 3; + dev->h_total = (dev->htotal + 1); + dev->v_total = (dev->vtotal + 1); + dev->v_syncstart = (dev->vsyncstart + 1); + dev->dispend = ((dev->vdisp >> 1) + 1); + dev->rowcount = !!(dev->disp_cntl & 0x08); + + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->dispend == 598) + dev->dispend += 2; + + if (dev->accel.advfunc_cntl & 4) { + if (mach->shadow_set & 2) { + if (dev->h_disp == 8) { + dev->h_disp = 1024; + dev->dispend = 768; + dev->v_total = 1536; + dev->v_syncstart = 1536; + } + } + mach_log("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace); + } else { + if (mach->shadow_set & 1) { + if ((dev->h_disp == 1024) && !dev->internal_pitch) { + dev->h_disp = 640; + dev->dispend = 480; + } + } + } + + if (dev->interlace) { + dev->dispend >>= 1; + dev->v_syncstart >>= 2; + dev->v_total >>= 2; + } else { + dev->v_syncstart >>= 1; + dev->v_total >>= 1; + } + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; + if ((mach->accel.ext_ge_config & 0x800) || (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800))) { + if ((mach->accel.ext_ge_config & 0x30) == 0x20) { + if ((mach->accel.ext_ge_config & 0xc0) == 0x40) + svga->bpp = 16; + else + svga->bpp = 15; + } else if ((mach->accel.ext_ge_config & 0x30) == 0x30) { + if (mach->accel.ext_ge_config & 0x200) + svga->bpp = 32; + else + svga->bpp = 24; + } else + svga->bpp = 8; + + mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x.\n", dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0); + switch (svga->bpp) { + case 8: + svga->render = ibm8514_render_8bpp; + break; + case 15: + svga->render = ibm8514_render_15bpp; + break; + case 16: + svga->render = ibm8514_render_16bpp; + break; + case 24: + if (mach->accel.ext_ge_config & 0x400) + svga->render = ibm8514_render_BGR; + else + svga->render = ibm8514_render_24bpp; + break; + case 32: + if (mach->accel.ext_ge_config & 0x400) + svga->render = ibm8514_render_ABGR8888; + else + svga->render = ibm8514_render_RGBA8888; break; default: break; } } + switch (mach->regs[0xb8] & 0xc0) { + case 0x40: + svga->clock *= 2; + break; + case 0x80: + svga->clock *= 3; + break; + case 0xc0: + svga->clock *= 4; + break; + + default: + break; + } } - } else if (dev->local) { + } else { if (ibm8514_on) { - svga->hdisp_time = svga->hdisp = (dev->hdisp + 1) << 3; - dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640; - svga->htotal = (dev->htotal + 1); - svga->vtotal = (dev->vtotal + 1); - svga->vsyncstart = (dev->vsyncstart + 1); - svga->rowcount = !!(dev->disp_cntl & 0x08); - svga->dispend = ((dev->vdisp >> 1) + 1); - svga->interlace = dev->interlace; - svga->split = 0xffffff; - svga->vblankstart = svga->dispend; + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + dev->h_disp = (dev->hdisp + 1) << 3; + dev->h_total = (dev->htotal + 1); + dev->v_total = (dev->vtotal + 1); + dev->v_syncstart = (dev->vsyncstart + 1); + dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->dispend = ((dev->vdisp >> 1) + 1); - if (svga->dispend == 766) { - svga->dispend = 768; - svga->vblankstart = svga->dispend; - } + if (dev->dispend == 766) + dev->dispend += 2; - if (svga->dispend == 598) { - svga->dispend = 600; - svga->vblankstart = svga->dispend; - } + if (dev->dispend == 598) + dev->dispend += 2; if (dev->accel.advfunc_cntl & 4) { - if (dev->ibm_mode) { - if (svga->hdisp == 8) { - svga->hdisp = 1024; - svga->dispend = 768; - svga->vtotal = 1536; - svga->vsyncstart = 1536; + if (mach->shadow_set & 2) { + if (dev->h_disp == 8) { + dev->h_disp = 1024; + dev->dispend = 768; + dev->v_total = 1536; + dev->v_syncstart = 1536; } } - - if (svga->interlace) { - svga->dispend >>= 1; - svga->vsyncstart >>= 2; - svga->vtotal >>= 2; - } else { - svga->vsyncstart >>= 1; - svga->vtotal >>= 1; - } - - dev->pitch = dev->ext_pitch; - svga->rowoffset = dev->ext_crt_pitch; - - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { - if (dev->ibm_mode) { - if ((svga->hdisp == 1024) && !dev->internal_pitch) { - svga->hdisp = 640; - svga->dispend = 480; + if (mach->shadow_set & 1) { + if ((dev->h_disp == 1024) && !dev->internal_pitch) { + dev->h_disp = 640; + dev->dispend = 480; } } - - if (svga->interlace) { - svga->dispend >>= 1; - svga->vsyncstart >>= 2; - svga->vtotal >>= 2; - } else { - svga->vsyncstart >>= 1; - svga->vtotal >>= 1; - } - - dev->pitch = dev->ext_pitch; - svga->rowoffset = dev->ext_crt_pitch; - - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } - switch (svga->bpp) { - default: - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - break; - case 16: - svga->render = svga_render_16bpp_highres; - break; - case 24: - svga->render = svga_render_24bpp_highres; - break; + if (dev->interlace) { + dev->dispend >>= 1; + dev->v_syncstart >>= 2; + dev->v_total >>= 2; + } else { + dev->v_syncstart >>= 1; + dev->v_total >>= 1; } - mach_log("BPP=%d, VRAM Mask=%08x, NormalPitch=%d, CRTPitch=%d, VSYNCSTART=%d, VTOTAL=%d, ROWCOUNT=%d, mode=%d, highres bit=%x, has_vga?=%d, override=%d.\n", svga->bpp, svga->vram_mask, dev->pitch, dev->ext_crt_pitch, svga->vsyncstart, svga->vtotal, svga->rowcount, dev->ibm_mode, dev->accel.advfunc_cntl & 4, ibm8514_has_vga, svga->override); + + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; + mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x.\n", dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0); + svga->map8 = dev->pallook; + svga->render = ibm8514_render_8bpp; + if (mach->regs[0xb8] & 0x40) + svga->clock *= 2; } - mach_log("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", svga->hdisp, svga->vtotal, svga->htotal, svga->dispend, svga->rowoffset, svga->split, svga->vsyncstart, svga->split); } } static void -mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, uint32_t val, int len) +mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, uint16_t val, int len) { int frgd_sel; int bkgd_sel; @@ -2860,9 +2888,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x92e8: if (len != 1) dev->test = val; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; + case 0xd2e8: mach_log("92E8 = %04x\n", val); if (len == 1) @@ -2914,6 +2941,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->accel.cmd_back = 0; } ibm8514_accel_start(-1, 0, -1, 0, svga, len); + svga_recalctimings(svga); } break; case 0x9ae9: @@ -3035,23 +3063,23 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x000: /*8-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { - mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); break; case 0x200: /*16-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { if (mach->accel.dp_config & 0x1000) - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev); else - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); break; default: @@ -3120,23 +3148,23 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x000: /*8-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { - mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); break; case 0x200: /*16-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { if (mach->accel.dp_config & 0x1000) - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev); else - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); break; default: @@ -3221,7 +3249,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } mach_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], svga->bpp, dev->pitch); if ((dev->accel.multifunc_cntl >> 12) == 5) { - if (!dev->local || !dev->ext_crt_pitch) + if (!dev->ext_crt_pitch || (dev->local < 2)) dev->ext_crt_pitch = 128; svga_recalctimings(svga); } @@ -3243,7 +3271,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; } if ((dev->accel.multifunc_cntl >> 12) == 5) { - if (!dev->local || !dev->ext_crt_pitch) + if (!dev->ext_crt_pitch || (dev->local < 2)) dev->ext_crt_pitch = 128; svga_recalctimings(svga); } @@ -3309,7 +3337,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->data_available = 0; dev->data_available2 = 0; mach->accel.cmd_type = 1; - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); } break; case 0x96ef: @@ -3319,7 +3347,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->data_available = 0; dev->data_available2 = 0; mach->accel.cmd_type = 1; - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); } break; @@ -3378,7 +3406,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->data_available2 = 0; mach_log("BitBLT = %04x.\n", mach->accel.dp_config); mach->accel.cmd_type = 2; /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); } break; case 0xaeef: @@ -3387,7 +3415,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->data_available = 0; dev->data_available2 = 0; mach->accel.cmd_type = 2; /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); } break; @@ -3445,7 +3473,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->data_available2 = 0; mach->accel.cmd_type = 5; /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ mach_log("ScanToX = %04x.\n", mach->accel.dp_config); - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); } break; case 0xcaef: @@ -3454,7 +3482,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->data_available = 0; dev->data_available2 = 0; mach->accel.cmd_type = 5; /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); } break; @@ -3578,7 +3606,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach->accel.cy_end_line = mach->accel.line_array[3]; if ((mach->accel.line_idx == 3) || (mach->accel.line_idx == 5)) { mach->accel.cmd_type = (mach->accel.line_idx == 5) ? 4 : 3; - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); mach->accel.line_idx = (mach->accel.line_idx == 5) ? 4 : 2; break; } @@ -3592,672 +3620,347 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } static void -mach_accel_out(uint16_t port, uint32_t val, mach_t *mach, int len) +mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) { svga_t *svga = &mach->svga; ibm8514_t *dev = &svga->dev8514; - mach_log("Port accel out = %04x, val = %04x, len = %d.\n", port, val, len); + mach_log("Port accel out = %04x, val = %04x.\n", port, val); - if (port & 0x8000) { - mach_accel_out_fifo(mach, svga, dev, port, val, len); - } else { - switch (port) { - case 0x2e8: - if (len == 1) - dev->htotal = (dev->htotal & 0xff00) | val; - else { - dev->htotal = val; - svga_recalctimings(svga); + switch (port) { + case 0x2e8: + case 0x2e9: + WRITE8(port, dev->htotal, val); + svga_recalctimings(svga); + break; + case 0x6e8: + dev->hdisp = val; + mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); + svga_recalctimings(svga); + break; + + case 0xae8: + mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + svga_recalctimings(svga); + break; + + case 0xee8: + mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + svga_recalctimings(svga); + break; + + case 0x12e8: + case 0x12e9: + WRITE8(port, dev->vtotal, val); + dev->vtotal &= 0x1fff; + svga_recalctimings(svga); + break; + + case 0x16e8: + case 0x16e9: + WRITE8(port, dev->vdisp, val); + dev->vdisp &= 0x1fff; + svga_recalctimings(svga); + break; + + case 0x1ae8: + case 0x1ae9: + WRITE8(port, dev->vsyncstart, val); + dev->vsyncstart &= 0x1fff; + svga_recalctimings(svga); + break; + + case 0x1ee8: + dev->vsyncwidth = val; + mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); + svga_recalctimings(svga); + break; + + case 0x22e8: + dev->disp_cntl = val & 0x7e; + dev->interlace = !!(val & 0x10); + mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); + svga_recalctimings(svga); + break; + + case 0x42e8: + dev->subsys_stat &= ~val; + break; + case 0x42e9: + dev->subsys_cntl = val; + break; + + case 0x4ae8: + if (!val) + break; + if (!dev->ext_crt_pitch || (dev->local < 2)) + dev->ext_crt_pitch = 128; + + dev->accel.advfunc_cntl = val & 0x0f; + ibm8514_on = val & 0x01; + if (!ibm8514_on && mach->old_mode) { + ibm8514_on = 1; + mach->old_mode = 0; + } + vga_on = !ibm8514_on; + mach_log("ATI 8514/A: VGA ON (0x4ae8) = %i, val = %02x, 8514 = %i, gdcreg6 = %02x\n", vga_on, val, ibm8514_on, svga->gdcreg[6] & 0x0c); + svga_recalctimings(svga); + break; + + /*ATI Mach8/32 specific registers*/ + case 0x2ee: + mach_log("2EE write val = %02x.\n", val); + break; + case 0x2ef: + mach_log("2EF write val = %02x.\n", val); + break; + + case 0x6ee: + mach_log("6EE write val = %02x.\n", val); + break; + case 0x6ef: + mach_log("6EF write val = %02x.\n", val); + break; + + case 0xaee: + case 0xaef: + WRITE8(port, mach->cursor_offset_lo, val); + break; + + case 0xeee: + case 0xeef: + WRITE8(port, mach->cursor_offset_hi_reg, val); + mach->cursor_offset_hi = mach->cursor_offset_hi_reg & 0x0f; + dev->hwcursor.addr = (mach->cursor_offset_lo | (mach->cursor_offset_hi << 16)) << 2; + dev->hwcursor.ena = !!(mach->cursor_offset_hi_reg & 0x8000); + break; + + case 0x12ee: + case 0x12ef: + WRITE8(port, mach->cursor_x, val); + dev->hwcursor.x = mach->cursor_x & 0x7ff; + break; + + case 0x16ee: + case 0x16ef: + WRITE8(port, mach->cursor_y, val); + dev->hwcursor.y = mach->cursor_y & 0xfff; + break; + + case 0x1aee: + case 0x1aef: + WRITE8(port, mach->cursor_col_b, val); + mach->cursor_col_0 = mach->cursor_col_b & 0xff; + mach->cursor_col_1 = (mach->cursor_col_b >> 8) & 0xff; + break; + + case 0x1eee: + case 0x1eef: + WRITE8(port, mach->cursor_vh_offset, val); + dev->hwcursor.xoff = mach->cursor_vh_offset & 0x3f; + dev->hwcursor.yoff = (mach->cursor_vh_offset >> 8) & 0x3f; + break; + + case 0x22ee: + if (mach->pci_bus) { + mach->pci_cntl_reg = val; + mach32_updatemapping(mach); + } + break; + + case 0x26ee: + mach_log("CRT Pitch = %d, original val = %d.\n", val << 3, val); + dev->ext_crt_pitch = val; + dev->internal_pitch = val; + if (svga->bpp > 8) { + if (svga->bpp == 24) + dev->ext_crt_pitch *= 3; + else if (svga->bpp == 32) + dev->ext_crt_pitch <<= 2; + else + dev->ext_crt_pitch <<= 1; + } + if (dev->local >= 2) { + if (!ibm8514_on) { + ibm8514_on = 1; + svga->adv_flags |= FLAG_ATI; } - break; - case 0x2e9: - if (len != 1) { - dev->htotal = (dev->htotal & 0xff) | (val << 8); - mach_log("ATI 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1); - svga_recalctimings(svga); - } - break; + } + svga_recalctimings(svga); + break; - case 0x6e8: - dev->hdisp = val; - mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); - svga_recalctimings(svga); - break; + case 0x32ee: + case 0x32ef: + WRITE8(port, mach->local_cntl, val); + mach32_updatemapping(mach); + break; - case 0xae8: - mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); - svga_recalctimings(svga); - break; + case 0x36ee: + case 0x36ef: + WRITE8(port, mach->misc, val); + mach->misc &= 0xfff0; + break; - case 0xee8: - mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); - svga_recalctimings(svga); - break; + case 0x3aee: + case 0x3aef: + WRITE8(port, mach->cursor_col_0_rg, val); + mach->ext_cur_col_0_g = mach->cursor_col_0_rg & 0xff; + mach->ext_cur_col_0_r = (mach->cursor_col_0_rg >> 8) & 0xff; + break; - case 0x12e8: - if (len == 1) - dev->vtotal = (dev->vtotal & 0x1f00) | val; - else { - dev->vtotal = val & 0x1fff; - svga_recalctimings(svga); - } - break; - case 0x12e9: - if (len == 1) { - dev->vtotal = (dev->vtotal & 0xff) | ((val & 0x1f) << 8); - mach_log("ATI 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal); - svga_recalctimings(svga); - } - break; + case 0x3eee: + case 0x3eef: + WRITE8(port, mach->cursor_col_1_rg, val); + mach->ext_cur_col_1_g = mach->cursor_col_1_rg & 0xff; + mach->ext_cur_col_1_r = (mach->cursor_col_1_rg >> 8) & 0xff; + break; - case 0x16e8: - if (len == 1) - dev->vdisp = (dev->vdisp & 0x1f00) | val; - else { - dev->vdisp = val & 0x1fff; - svga_recalctimings(svga); - } - break; - case 0x16e9: - if (len == 1) { - dev->vdisp = (dev->vdisp & 0xff) | ((val & 0x1f) << 8); - mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); - svga_recalctimings(svga); - } - break; + case 0x42ee: + mach->accel.test2[0] = val; + break; + case 0x42ef: + mach->accel.test2[1] = val; + break; - case 0x1ae8: - if (len == 1) - dev->vsyncstart = (dev->vsyncstart & 0x1f00) | val; - else { - dev->vsyncstart = val & 0x1fff; - svga_recalctimings(svga); - } - break; - case 0x1ae9: - if (len == 1) { - dev->vsyncstart = (dev->vsyncstart & 0xff) | ((val & 0x1f) << 8); - mach_log("ATI 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart); - svga_recalctimings(svga); - } - break; + case 0x46ee: + mach->accel.test3[0] = val; + break; + case 0x46ef: + mach->accel.test3[1] = val; + break; - case 0x1ee8: - dev->vsyncwidth = val; - mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); - svga_recalctimings(svga); - break; + case 0x4aee: + case 0x4aef: + if (!(port & 1)) + mach->old_mode = mach->accel.clock_sel & 0x01; - case 0x22e8: - dev->disp_cntl = val & 0x7e; - dev->interlace = !!(val & 0x10); - mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); - svga_recalctimings(svga); - break; - - case 0x42e8: - if (len == 1) { - dev->subsys_stat &= ~val; - } else { - dev->subsys_stat &= ~(val & 0xff); - dev->subsys_cntl = (val >> 8); - mach_log("CNTL = %02x.\n", val >> 8); - } - break; - case 0x42e9: - if (len == 1) { - dev->subsys_cntl = val; - mach_log("CNTL = %02x.\n", val); - } - break; - - case 0x4ae8: - mach_log("ATI 8514/A: VGA ON (0x4ae8) = %i, val = %02x\n", vga_on, val); - if (!val) - break; - if (!dev->local || !dev->ext_crt_pitch) - dev->ext_crt_pitch = 128; - dev->accel.advfunc_cntl = val & 7; - ibm8514_on = (dev->accel.advfunc_cntl & 1); - vga_on = !ibm8514_on; - dev->ibm_mode = 1; + WRITE8(port, mach->accel.clock_sel, val); + ibm8514_on = mach->accel.clock_sel & 0x01; + vga_on = !ibm8514_on; + if (dev->local >= 2) { if (ibm8514_on) svga->adv_flags |= FLAG_ATI; else svga->adv_flags &= ~FLAG_ATI; - svga_recalctimings(svga); - break; + } + mach_log("ATI 8514/A: VGA ON (0x4aee) = %i, Ext = %i, val = %04x\n", vga_on, ibm8514_on, mach->accel.clock_sel); + svga_recalctimings(svga); + break; - /*ATI Mach8/32 specific registers*/ - case 0x6ee: - mach_log("6EE write val = %02x, len = %d.\n", val, len); - break; + case 0x52ee: + case 0x52ef: + WRITE8(port, mach->accel.scratch0, val); + break; - case 0x6ef: - mach_log("6EF write val = %02x, len = %d.\n", val, len); - break; + case 0x56ee: + case 0x56ef: + WRITE8(port, mach->accel.scratch1, val); + break; - case 0xaee: - if (len == 1) - mach->cursor_offset_lo = (mach->cursor_offset_lo & 0xff00) | val; - else { - mach_log("AEE val=%02x.\n", val); - mach->cursor_offset_lo = val; - svga->hwcursor.addr = mach->cursor_offset_lo << 2; - } - break; - case 0xaef: - if (len == 1) { - mach->cursor_offset_lo = (mach->cursor_offset_lo & 0x00ff) | (val << 8); - svga->hwcursor.addr = mach->cursor_offset_lo << 2; - } - break; + case 0x5aee: + case 0x5aef: + WRITE8(port, mach->shadow_set, val); + svga_recalctimings(svga); + break; - case 0xeee: - mach->cursor_offset_hi = val & 0x0f; - if (len != 1) { - svga->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16))) << 2; - svga->hwcursor.ena = !!(val & 0x8000); - } - mach_log("EEE val=%08x.\n", svga->hwcursor.addr); - break; - case 0xeef: - if (len == 1) { - svga->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16))) << 2; - svga->hwcursor.ena = !!(val & 0x80); - } - break; + case 0x5eee: + case 0x5eef: + WRITE8(port, mach->memory_aperture, val); + mach_log("Memory Aperture = %04x.\n", mach->memory_aperture); + if (!mach->pci_bus) + mach->linear_base = (mach->memory_aperture & 0xff00) << 12; - case 0x12ee: - if (len == 1) { - svga->hwcursor.x = (svga->hwcursor.x & 0x700) | val; - } else { - svga->hwcursor.x = val & 0x7ff; - mach_log("X = %03x.\n", val); - } - break; - case 0x12ef: - if (len == 1) { - svga->hwcursor.x = (svga->hwcursor.x & 0x0ff) | ((val & 0x07) << 8); - } - break; + mach32_updatemapping(mach); + break; - case 0x16ee: - if (len == 1) { - svga->hwcursor.y = (svga->hwcursor.y & 0xf00) | val; - } else { - svga->hwcursor.y = val & 0xfff; - } - break; - case 0x16ef: - if (len == 1) { - svga->hwcursor.y = (svga->hwcursor.y & 0x0ff) | ((val & 0x0f) << 8); - } - break; + case 0x62ee: + mach_log("62EE write val = %04x, len = %d.\n", val, len); + break; - case 0x1aee: - if (len != 1) { - mach->cursor_col_0 = val & 0xff; - mach->cursor_col_1 = (val >> 8) & 0xff; - } else - mach->cursor_col_0 = val; - break; - case 0x1aef: - if (len == 1) - mach->cursor_col_1 = val; - break; + case 0x66ee: + mach_log("66EE write val = %04x, len = %d.\n", val, len); + break; - case 0x1eee: - if (len != 1) { - svga->hwcursor.xoff = val & 0x3f; - svga->hwcursor.yoff = (val >> 8) & 0x3f; - } else - svga->hwcursor.xoff = val & 0x3f; - break; - case 0x1eef: - if (len == 1) - svga->hwcursor.yoff = val & 0x3f; - break; + case 0x6aee: + case 0x6aef: + WRITE8(port, mach->accel.max_waitstates, val); + break; - case 0x2aee: - mach_log("2AEE write val = %04x\n", val); - if (len == 1) - mach->accel.crt_offset_lo = (mach->accel.crt_offset_lo & 0xff00) | val; - else - mach->accel.crt_offset_lo = val; - break; - case 0x2aef: - if (len == 1) - mach->accel.crt_offset_lo = (mach->accel.crt_offset_lo & 0x00ff) | (val << 8); - break; + case 0x6eee: + case 0x6eef: + WRITE8(port, mach->accel.ge_offset_lo, val); + dev->accel.ge_offset = mach->accel.ge_offset_lo; + break; - case 0x2eee: - mach_log("2EEE write val = %04x\n", val); - if (len == 1) - mach->accel.crt_offset_hi = (mach->accel.crt_offset_hi & 0xff00) | val; - else - mach->accel.crt_offset_hi = val; - break; - case 0x2eef: - if (len == 1) - mach->accel.crt_offset_hi = (mach->accel.crt_offset_hi & 0x00ff) | (val << 8); - break; + case 0x72ee: + case 0x72ef: + WRITE8(port, mach->accel.ge_offset_hi, val); + dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); + break; - case 0x26ee: - mach_log("CRT Pitch = %d, original val = %d.\n", val << 3, val); - dev->ext_crt_pitch = val; - dev->internal_pitch = val; - if (svga->bpp > 8) { - if (svga->bpp == 24) - dev->ext_crt_pitch *= 3; - else + case 0x76ee: + mach_log("76EE write val=%d shifted, normal=%d.\n", val << 3, val); + dev->ext_pitch = val << 3; + mach->old_mode = 1; + svga_recalctimings(svga); + break; + + case 0x7aee: + case 0x7aef: + WRITE8(port, mach->accel.ext_ge_config, val); + if (dev->local >= 2) { + dev->ext_crt_pitch = dev->internal_pitch; + switch (mach->accel.ext_ge_config & 0x30) { + case 0: + case 0x10: + dev->bpp = 0; + break; + case 0x20: + dev->bpp = 1; dev->ext_crt_pitch <<= 1; - } - if (dev->local) { - if (!ibm8514_on) { - ibm8514_on ^= 1; - svga->adv_flags |= FLAG_ATI; - } - } - svga_recalctimings(svga); - break; - - case 0x32ee: - if (len == 1) { - mach->local_cntl = (mach->local_cntl & 0xff00) | val; - } else { - mach->local_cntl = val; - mach32_updatemapping(mach); - } - break; - - case 0x32ef: - if (len == 1) { - mach->local_cntl = (mach->local_cntl & 0x00ff) | (val << 8); - mach32_updatemapping(mach); - } - break; - - case 0x36ee: - if (len == 1) { - mach->misc = (mach->misc & 0xff00) | (val); - } else { - mach->misc = val; - } - break; - case 0x36ef: - if (len == 1) { - mach->misc = (mach->misc & 0x00ff) | (val << 8); - } - break; - - case 0x3aee: - if (len == 1) { - mach->ext_cur_col_0_g = val; - } else { - mach->ext_cur_col_0_g = val & 0xff; - mach->ext_cur_col_0_r = (val >> 8) & 0xff; - } - break; - case 0x3aef: - if (len == 1) { - mach->ext_cur_col_0_r = val; - } - break; - - case 0x3eee: - if (len == 1) { - mach->ext_cur_col_1_g = val; - } else { - mach->ext_cur_col_1_g = val & 0xff; - mach->ext_cur_col_1_r = (val >> 8) & 0xff; - } - break; - case 0x3eef: - if (len == 1) { - mach->ext_cur_col_1_r = val; - } - break; - - case 0x42ee: - mach->accel.test2[0] = val; - break; - case 0x42ef: - mach->accel.test2[1] = val; - break; - - case 0x46ee: - mach->accel.test3[0] = val; - break; - case 0x46ef: - mach->accel.test3[1] = val; - break; - - case 0x4aee: - if (len == 1) - mach->accel.clock_sel = (mach->accel.clock_sel & 0xff00) | val; - else { - mach->accel.clock_sel = val; - ibm8514_on = (mach->accel.clock_sel & 1); - vga_on = !ibm8514_on; - dev->ibm_mode = 0; - if (ibm8514_on) - svga->adv_flags |= FLAG_ATI; - else - svga->adv_flags &= ~FLAG_ATI; - mach_log("ATI 8514/A: VGA ON (0x4aee) = %i, val = %04x\n", vga_on, val); - svga_recalctimings(svga); - } - break; - case 0x4aef: - if (len == 1) { - mach->accel.clock_sel = (mach->accel.clock_sel & 0x00ff) | (val << 8); - ibm8514_on = (mach->accel.clock_sel & 1); - vga_on = !ibm8514_on; - dev->ibm_mode = 0; - if (ibm8514_on) - svga->adv_flags |= FLAG_ATI; - else - svga->adv_flags &= ~FLAG_ATI; - mach_log("ATI 8514/A: VGA ON (0x4aef) = %i, val = %04x\n", vga_on, mach->accel.clock_sel); - svga_recalctimings(svga); - } - break; - - case 0x52ee: - if (len == 1) - mach->accel.scratch0 = (mach->accel.scratch0 & 0xff00) | val; - else - mach->accel.scratch0 = val; - break; - case 0x52ef: - if (len == 1) - mach->accel.scratch0 = (mach->accel.scratch0 & 0x00ff) | (val << 8); - break; - - case 0x56ee: - if (len == 1) - mach->accel.scratch1 = (mach->accel.scratch1 & 0xff00) | val; - else - mach->accel.scratch1 = val; - break; - case 0x56ef: - if (len == 1) - mach->accel.scratch1 = (mach->accel.scratch1 & 0x00ff) | (val << 8); - break; - - case 0x5aee: - mach_log("Shadow set = %04x\n", val); - break; - case 0x5aef: - mach_log("Shadow + 1 set = %02x\n", val); - break; - - case 0x5eee: - mach_log("Memory Aperture = %04x, len = %d.\n", val, len); - if (len == 1) { - mach->memory_aperture = (mach->memory_aperture & 0xff00) | val; - } else { - mach->memory_aperture = val; - if (!mach->pci_bus) - mach->linear_base = (mach->memory_aperture & 0xff00) << 12; - - mach32_updatemapping(mach); - } - break; - - case 0x5eef: - if (len == 1) { - mach->memory_aperture = (mach->memory_aperture & 0x00ff) | (val << 8); - if (!mach->pci_bus) - mach->linear_base = (mach->memory_aperture & 0xff00) << 12; - - mach32_updatemapping(mach); - } - break; - - case 0x62ee: - mach_log("62EE write val = %04x, len = %d.\n", val, len); - break; - - case 0x66ee: - mach_log("66EE write val = %04x, len = %d.\n", val, len); - break; - - case 0x6aee: - mach_log("6AEE write val = %04x.\n", val & 0x400); - if (len == 1) - mach->accel.max_waitstates = (mach->accel.max_waitstates & 0xff00) | val; - else { - mach->accel.max_waitstates = val; - } - break; - case 0x6aef: - if (len == 1) - mach->accel.max_waitstates = (mach->accel.max_waitstates & 0x00ff) | (val << 8); - break; - - case 0x6eee: - mach_log("6EEE write val = %04x\n", val); - if (len == 1) - mach->accel.ge_offset_lo = (mach->accel.ge_offset_lo & 0xff00) | val; - else { - mach->accel.ge_offset_lo = val; - dev->accel.ge_offset = mach->accel.ge_offset_lo; - } - break; - case 0x6eef: - if (len == 1) { - mach->accel.ge_offset_lo = (mach->accel.ge_offset_lo & 0x00ff) | (val << 8); - dev->accel.ge_offset = mach->accel.ge_offset_lo; - } - break; - - case 0x72ee: - mach_log("72EE write val = %04x\n", val); - if (len == 1) - mach->accel.ge_offset_hi = (mach->accel.ge_offset_hi & 0xff00) | val; - else { - mach->accel.ge_offset_hi = val; - dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); - } - break; - case 0x72ef: - if (len == 1) { - mach->accel.ge_offset_hi = (mach->accel.ge_offset_hi & 0x00ff) | (val << 8); - dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); - } - break; - - case 0x76ee: - mach_log("76EE write val=%d shifted, normal=%d.\n", val << 3, val); - dev->ext_pitch = val << 3; - svga_recalctimings(svga); - break; - - case 0x7aee: - mach_log("7AEE write val = %04x, len = %d.\n", val, len); - if (len == 1) - mach->accel.ext_ge_config = (mach->accel.ext_ge_config & 0xff00) | val; - else { - mach->accel.ext_ge_config = val; - dev->ext_crt_pitch = dev->internal_pitch; - switch (mach->accel.ext_ge_config & 0x30) { - case 0: - case 0x10: - svga->bpp = 8; - break; - case 0x20: - if ((mach->accel.ext_ge_config & 0xc0) == 0x40) - svga->bpp = 16; - else - svga->bpp = 15; - - dev->ext_crt_pitch <<= 1; - break; - case 0x30: - svga->bpp = 24; + break; + case 0x30: + dev->bpp = 0; + if (mach->accel.ext_ge_config & 0x200) + dev->ext_crt_pitch <<= 2; + else dev->ext_crt_pitch *= 3; - break; + break; - default: - break; - } - if (mach->accel.ext_ge_config & 0x800) { - svga_recalctimings(svga); - } - if (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800)) - svga_recalctimings(svga); + default: + break; } - break; - case 0x7aef: - mach_log("7AEF write val = %02x.\n", val); - if (len == 1) { - mach->accel.ext_ge_config = (mach->accel.ext_ge_config & 0x00ff) | (val << 8); - dev->ext_crt_pitch = dev->internal_pitch; - switch (mach->accel.ext_ge_config & 0x30) { - case 0: - case 0x10: - svga->bpp = 8; - break; - case 0x20: - if ((mach->accel.ext_ge_config & 0xc0) == 0x40) - svga->bpp = 16; - else - svga->bpp = 15; + svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000)); + mach_log("Passthrough override = %04x.\n", val & 0x1000); + svga_recalctimings(svga); + } + mach_log("7AEE write val = %04x.\n", mach->accel.ext_ge_config); + break; - dev->ext_crt_pitch <<= 1; - break; - case 0x30: - svga->bpp = 24; - dev->ext_crt_pitch *= 3; - break; + case 0x7eee: + case 0x7eef: + WRITE8(port, mach->accel.eeprom_control, val); + ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 4, mach->accel.eeprom_control & 2, mach->accel.eeprom_control & 1); + mach_log("[%04X]: 7EEE+%d VGA ON = %d, Ext = %i, val = %04x, pagesel = %04x.\n", CS, port & 1, vga_on, ibm8514_on, mach->accel.eeprom_control & 0x10ff, (mach->accel.eeprom_control & 0xf0) << 7); + svga_recalctimings(svga); + break; - default: - break; - } - if (mach->accel.ext_ge_config & 0x800) { - svga_recalctimings(svga); - } - if (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800)) - svga_recalctimings(svga); - } - break; - - case 0x7eee: - mach->accel.eeprom_control = val; - break; - - default: - break; - } + default: + break; } } -static uint32_t -mach_accel_in(uint16_t port, mach_t *mach, int len) +static uint16_t +mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, int len) { - svga_t *svga = &mach->svga; - ibm8514_t *dev = &svga->dev8514; - const uint16_t *vram_w = (uint16_t *) svga->vram; - uint16_t temp = 0; + const uint16_t *vram_w = (uint16_t *) dev->vram; + uint16_t temp = 0; int cmd; - int vpos = dev->displine + svga->y_add; - int vblankend = svga->vblankstart + svga->crtc[0x16]; int frgd_sel; int bkgd_sel; int mono_src; switch (port) { - case 0x2e8: - if (dev->local) { - vpos = svga->displine + svga->y_add; - if (vblankend > svga->vtotal) { - vblankend -= svga->vtotal; - if (vpos >= svga->vblankstart || vpos <= vblankend) - temp |= 2; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - temp |= 2; - } - } else { - vpos = dev->displine + svga->y_add; - if (vblankend > dev->vtotal) { - vblankend -= dev->vtotal; - if (vpos >= svga->vblankstart || vpos <= vblankend) - temp |= 2; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - temp |= 2; - } - } - break; - - case 0x6e8: - temp = dev->hdisp; - break; - - case 0x22e8: - temp = dev->disp_cntl; - break; - - case 0x26e8: - if (len == 1) - temp = dev->htotal & 0xff; - else - temp = dev->htotal; - break; - case 0x26e9: - if (len == 1) - temp = dev->htotal >> 8; - break; - - case 0x2ee8: - temp = dev->subsys_cntl; - break; - - case 0x42e8: - if (dev->local) { - vpos = svga->displine + svga->y_add; - if (vblankend > svga->vtotal) { - vblankend -= svga->vtotal; - if (vpos >= svga->vblankstart || vpos <= vblankend) - dev->subsys_stat |= 1; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - dev->subsys_stat |= 1; - } - } else { - vpos = dev->displine + svga->y_add; - if (vblankend > dev->vtotal) { - vblankend -= dev->vtotal; - if (vpos >= svga->vblankstart || vpos <= vblankend) - dev->subsys_stat |= 1; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - dev->subsys_stat |= 1; - } - } - - if (len != 1) { - temp = dev->subsys_stat | 0xa0 | 0x8000; - } else { - temp = dev->subsys_stat | 0xa0; - } - break; - - case 0x4ae8: - temp = dev->accel.advfunc_cntl; - break; - - case 0x42e9: - if (len == 1) { - temp = dev->subsys_stat >> 8; - temp |= 0x80; - } - break; - case 0x82e8: case 0xc2e8: if (len != 1) { @@ -4353,14 +4056,13 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) if (mach_pixel_read(mach)) { cmd = -1; if (len == 1) { - READ_PIXTRANS_BYTE_IO(dev->accel.dx, 1, dev->local) - + READ_PIXTRANS_BYTE_IO(dev->accel.dx, 1) temp = mach->accel.pix_trans[1]; } else { if (mach->accel.cmd_type == 3) { - READ_PIXTRANS_WORD(dev->accel.cx, 0, dev->local) + READ_PIXTRANS_WORD(dev->accel.cx, 0) } else { - READ_PIXTRANS_WORD(dev->accel.dx, 0, dev->local) + READ_PIXTRANS_WORD(dev->accel.dx, 0) } mach_accel_out_pixtrans(mach, dev, port, temp, len); } @@ -4368,19 +4070,14 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) } else { if (ibm8514_cpu_dest(svga)) { cmd = (dev->accel.cmd >> 13); - if (len == 1) { - ; // READ_PIXTRANS_BYTE_IO(0) - } else { - READ_PIXTRANS_WORD(dev->accel.cx, 0, dev->local) + if (len != 1) { + READ_PIXTRANS_WORD(dev->accel.cx, 0) if (dev->accel.input && !dev->accel.odd_in && !dev->accel.sx) { temp &= ~0xff00; - if (dev->local) - temp |= (svga->vram[(dev->accel.newdest_in + dev->accel.cur_x) & svga->vram_mask] << 8); - else - temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); + temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); } if (dev->subsys_stat & 1) { - dev->force_busy = 1; + dev->force_busy = 1; dev->data_available = 1; } } @@ -4395,9 +4092,9 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) if (mach_pixel_read(mach)) { if (len == 1) { cmd = -1; - READ_PIXTRANS_BYTE_IO(dev->accel.dx, 0, dev->local) + READ_PIXTRANS_BYTE_IO(dev->accel.dx, 0) - temp = mach->accel.pix_trans[0]; + temp = mach->accel.pix_trans[0]; frgd_sel = (mach->accel.dp_config >> 13) & 7; bkgd_sel = (mach->accel.dp_config >> 7) & 3; mono_src = (mach->accel.dp_config >> 5) & 3; @@ -4406,23 +4103,23 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) case 0x000: /*8-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { - mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); break; case 0x200: /*16-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { if (mach->accel.dp_config & 0x1000) - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev); else - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); break; default: @@ -4472,189 +4169,6 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) } break; - /*ATI Mach8/32 specific registers*/ - case 0x12ee: - if (len == 1) - temp = mach->config1 & 0xff; - else - temp = mach->config1; - break; - case 0x12ef: - if (len == 1) - temp = mach->config1 >> 8; - break; - - case 0x16ee: - if (len == 1) - temp = mach->config2 & 0xff; - else - temp = mach->config2; - break; - case 0x16ef: - if (len == 1) - temp = mach->config2 >> 8; - break; - - case 0x32ee: - if (len == 1) - temp = mach->local_cntl & 0xff; - else - temp = mach->local_cntl; - break; - case 0x32ef: - if (len == 1) - temp = mach->local_cntl >> 8; - break; - - case 0x36ee: - if (len == 1) - temp = mach->misc & 0xff; - else - temp = mach->misc; - break; - case 0x36ef: - if (len == 1) - temp = mach->misc >> 8; - break; - - case 0x42ee: - temp = mach->accel.test2[0]; - break; - case 0x42ef: - temp = mach->accel.test2[1]; - break; - - case 0x46ee: - temp = mach->accel.test3[0]; - break; - case 0x46ef: - temp = mach->accel.test3[1]; - break; - - case 0x4aee: - if (len == 1) - temp = mach->accel.clock_sel & 0xff; - else - temp = mach->accel.clock_sel; - break; - case 0x4aef: - if (len == 1) - temp = mach->accel.clock_sel >> 8; - break; - - case 0x52ee: - if (len == 1) - temp = mach->accel.scratch0 & 0xff; - else - temp = mach->accel.scratch0; - break; - case 0x52ef: - if (len == 1) - temp = mach->accel.scratch0 >> 8; - break; - - case 0x56ee: - if (len == 1) - temp = mach->accel.scratch1 & 0xff; - else - temp = mach->accel.scratch1; - break; - case 0x56ef: - if (len == 1) - temp = mach->accel.scratch1 >> 8; - break; - - case 0x5eee: - if (mach->pci_bus) - mach->memory_aperture = (mach->memory_aperture & ~0xfff0) | ((mach->linear_base >> 20) << 4); - - if (len == 1) - temp = mach->memory_aperture & 0xff; - else - temp = mach->memory_aperture; - break; - case 0x5eef: - if (len == 1) - temp = mach->memory_aperture >> 8; - break; - - case 0x62ee: - temp = mach->accel.clip_overrun; - if (len != 1) { - if (mach->force_busy) - temp |= 0x2000; - mach->force_busy = 0; - if (ati_eeprom_read(&mach->eeprom)) - temp |= 0x4000; - } - mach_log("[%04X:%08X]: 62EE: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); - break; - case 0x62ef: - if (len == 1) { - if (mach->force_busy2) - temp |= 0x20; - mach->force_busy2 = 0; - if (ati_eeprom_read(&mach->eeprom)) - temp |= 0x40; - } - mach_log("[%04X:%08X]: 62EF: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); - break; - - case 0x6aee: - if (len == 1) - temp = mach->accel.max_waitstates & 0xff; - else - temp = mach->accel.max_waitstates; - break; - case 0x6aef: - if (len == 1) - temp = mach->accel.max_waitstates >> 8; - break; - - case 0x72ee: - if (len == 1) - temp = dev->accel.clip_left & 0xff; - else - temp = dev->accel.clip_left; - break; - case 0x72ef: - if (len == 1) - temp = dev->accel.clip_left >> 8; - break; - - case 0x76ee: - if (len == 1) - temp = dev->accel.clip_top & 0xff; - else - temp = dev->accel.clip_top; - break; - case 0x76ef: - if (len == 1) - temp = dev->accel.clip_top >> 8; - break; - - case 0x7aee: - if (len == 1) - temp = dev->accel.multifunc[4] & 0xff; - else - temp = dev->accel.multifunc[4]; - break; - case 0x7aef: - if (len == 1) - temp = dev->accel.multifunc[4] >> 8; - break; - - case 0x7eee: - if (len == 1) - temp = dev->accel.multifunc[3] & 0xff; - else - temp = dev->accel.multifunc[3]; - break; - case 0x7eef: - if (len == 1) - temp = dev->accel.multifunc[3] >> 8; - break; - case 0x82ee: temp = mach->accel.patt_data_idx; break; @@ -4664,6 +4178,8 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) temp = mach->accel.ext_ge_config & 0xff; else temp = mach->accel.ext_ge_config; + + mach_log("ExtGE Read = %04x, len=%d.\n", temp, len); break; case 0x8eef: if (len == 1) @@ -4671,7 +4187,18 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) break; case 0x92ee: - temp = mach->accel.eeprom_control; + if (len == 1) + temp = mach->accel.eeprom_control & 0xff; + else + temp = mach->accel.eeprom_control; + + mach_log("EEPROM cntl read=%04x, len=%d.\n", temp, len); + break; + case 0x92ef: + if (len == 1) + temp = mach->accel.eeprom_control >> 8; + + mach_log("EEPROM cntl read+1=%02x, len=%d.\n", temp, len); break; case 0x96ee: @@ -4754,40 +4281,39 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) case 0xceee: if (len == 1) - temp = svga->vc & 0xff; + temp = dev->vc & 0xff; else - temp = svga->vc & 0x7ff; + temp = dev->vc & 0x7ff; break; case 0xceef: if (len == 1) - temp = (svga->vc >> 8) & 7; + temp = (dev->vc >> 8) & 7; break; case 0xdaee: if (len != 1) { temp = mach->accel.src_x; - if (dev->local) { + if (dev->local >= 2) temp &= 0x7ff; - } } else - temp = dev->accel.destx_distp & 0xff; + temp = mach->accel.src_x & 0xff; break; case 0xdaef: if (len == 1) - temp = dev->accel.destx_distp >> 8; + temp = mach->accel.src_x >> 8; break; case 0xdeee: if (len != 1) { temp = mach->accel.src_y; - if (dev->local) + if (dev->local >= 2) temp &= 0x7ff; } else - temp = dev->accel.desty_axstp & 0xff; + temp = mach->accel.src_y & 0xff; break; case 0xdeef: if (len == 1) - temp = dev->accel.desty_axstp >> 8; + temp = mach->accel.src_y >> 8; break; case 0xfaee: @@ -4815,9 +4341,209 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) default: break; } - if (port != 0x9ae8 && port != 0x9ae9 && port != 0x62ee && port != 0x9aee) { - mach_log("Port accel in = %04x, temp = %04x, len = %d, mode = %d.\n", port, temp, len, dev->ibm_mode); + + mach_log("Port FIFO IN=%04x, temp=%04x, len=%d.\n", port, temp, len); + return temp; +} + +static uint8_t +mach_accel_in(uint16_t port, mach_t *mach) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = &svga->dev8514; + uint8_t temp = 0; + int vpos = 0; + int vblankend = svga->vblankstart + svga->crtc[0x16]; + + switch (port) { + case 0x2e8: + vpos = dev->vc & 0x7ff; + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; + if (vpos >= svga->vblankstart || vpos <= vblankend) + temp |= 2; + } else { + if (vpos >= svga->vblankstart && vpos <= vblankend) + temp |= 2; + } + break; + + case 0x6e8: + temp = dev->hdisp; + break; + + case 0x22e8: + temp = dev->disp_cntl; + break; + + case 0x26e8: + case 0x26e9: + READ8(port, dev->htotal); + break; + + case 0x2ee8: + temp = dev->subsys_cntl; + break; + case 0x2ee9: + temp = 0xff; + break; + + case 0x42e8: + case 0x42e9: + vpos = dev->vc & 0x7ff; + if (vblankend > dev->v_total) { + vblankend -= dev->v_total; + if (vpos >= svga->vblankstart || vpos <= vblankend) + dev->subsys_stat |= 1; + } else { + if (vpos >= svga->vblankstart && vpos <= vblankend) + dev->subsys_stat |= 1; + } + + if (port & 1) { + temp = 0x80; + } else { + temp = dev->subsys_stat | 0x80; + if (mach->accel.ext_ge_config & 0x08) { + temp |= ((mach->accel.ext_ge_config & 0x07) << 4); + } else + temp |= 0x20; + } + break; + + case 0x4ae8: + temp = dev->accel.advfunc_cntl; + break; + + /*ATI Mach8/32 specific registers*/ + case 0x12ee: + case 0x12ef: + READ8(port, mach->config1); + break; + + case 0x16ee: + case 0x16ef: + READ8(port, mach->config2); + break; + + case 0x22ee: + if (mach->pci_bus) { + temp = mach->pci_cntl_reg; + } + break; + + case 0x32ee: + case 0x32ef: + READ8(port, mach->local_cntl); + break; + + case 0x36ee: + case 0x36ef: + READ8(port, mach->misc); + + if (!(port & 1)) { + switch (mach->memory) { + case 512: + temp &= ~0x0c; + break; + case 1024: + temp |= 0x04; + break; + case 2048: + temp |= 0x08; + break; + case 4096: + temp |= 0x0c; + break; + + default: + break; + } + } + break; + + case 0x42ee: + temp = mach->accel.test2[0]; + break; + case 0x42ef: + temp = mach->accel.test2[1]; + break; + + case 0x46ee: + temp = mach->accel.test3[0]; + break; + case 0x46ef: + temp = mach->accel.test3[1]; + break; + + case 0x4aee: + case 0x4aef: + READ8(port, mach->accel.clock_sel); + break; + + case 0x52ee: + case 0x52ef: + READ8(port, mach->accel.scratch0); + break; + + case 0x56ee: + case 0x56ef: + READ8(port, mach->accel.scratch1); + break; + + case 0x5eee: + case 0x5eef: + if (mach->pci_bus) + mach->memory_aperture = (mach->memory_aperture & ~0xfff0) | ((mach->linear_base >> 20) << 4); + if ((port & 1) && ibm8514_on) { + ibm8514_on = 0; + vga_on = 1; + } + READ8(port, mach->memory_aperture); + break; + + case 0x62ee: + temp = mach->accel.clip_overrun; + mach_log("ClipOverrun = %02x.\n", temp); + break; + case 0x62ef: + if (mach->force_busy) + temp |= 0x20; + mach->force_busy = 0; + if (ati_eeprom_read(&mach->eeprom)) + temp |= 0x40; + mach_log("Mach busy temp=%02x.\n", temp); + break; + + case 0x6aee: + case 0x6aef: + READ8(port, mach->accel.max_waitstates); + break; + + case 0x72ee: + case 0x72ef: + READ8(port, dev->accel.clip_left); + break; + + case 0x76ee: + case 0x76ef: + READ8(port, dev->accel.clip_top); + break; + + case 0x7aee: + case 0x7aef: + READ8(port, dev->accel.multifunc[4]); + break; + + case 0x7eee: + case 0x7eef: + READ8(port, dev->accel.multifunc[3]); + break; + + default: + break; } + mach_log("Port accel in = %04x, temp = %04x.\n", port, temp); return temp; } @@ -4825,28 +4551,92 @@ static void mach_accel_outb(uint16_t port, uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach_accel_out(port, val, mach, 1); + svga_t *svga = &mach->svga; + + if (port & 0x8000) + mach_accel_out_fifo(mach, svga, &svga->dev8514, port, val, 1); + else + mach_accel_out(port, val, mach); } static void mach_accel_outw(uint16_t port, uint16_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach_accel_out(port, val, mach, 2); + svga_t *svga = &mach->svga; + + if (port & 0x8000) + mach_accel_out_fifo(mach, svga, &svga->dev8514, port, val, 2); + else { + mach_accel_out(port, val, mach); + mach_accel_out(port + 1, (val >> 8), mach); + } } +static void +mach_accel_outl(uint16_t port, uint32_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + + if (port & 0x8000) { + mach_accel_out_fifo(mach, svga, &svga->dev8514, port, val & 0xffff, 2); + mach_accel_out_fifo(mach, svga, &svga->dev8514, port + 2, val >> 16, 2); + } else { + mach_accel_out(port, val, mach); + mach_accel_out(port + 1, (val >> 8), mach); + mach_accel_out(port + 2, (val >> 16), mach); + mach_accel_out(port + 3, (val >> 24), mach); + } +} static uint8_t mach_accel_inb(uint16_t port, void *priv) { mach_t *mach = (mach_t *) priv; - return mach_accel_in(port, mach, 1); + svga_t *svga = &mach->svga; + uint8_t temp; + + if (port & 0x8000) + temp = mach_accel_in_fifo(mach, svga, &svga->dev8514, port, 1); + else + temp = mach_accel_in(port, mach); + + return temp; } static uint16_t mach_accel_inw(uint16_t port, void *priv) { mach_t *mach = (mach_t *) priv; - return mach_accel_in(port, mach, 2); + svga_t *svga = &mach->svga; + uint16_t temp; + + if (port & 0x8000) + temp = mach_accel_in_fifo(mach, svga, &svga->dev8514, port, 2); + else { + temp = mach_accel_in(port, mach); + temp |= (mach_accel_in(port + 1, mach) << 8); + } + return temp; +} + +static uint32_t +mach_accel_inl(uint16_t port, void *priv) +{ + mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + uint32_t temp; + + if (port & 0x8000) { + temp = mach_accel_in_fifo(mach, svga, &svga->dev8514, port, 2); + temp = (mach_accel_in_fifo(mach, svga, &svga->dev8514, port + 2, 2) << 16); + } else { + temp = mach_accel_in(port, mach); + temp |= (mach_accel_in(port + 1, mach) << 8); + temp |= (mach_accel_in(port + 2, mach) << 16); + temp |= (mach_accel_in(port + 3, mach) << 24); + } + return temp; } static void @@ -4855,7 +4645,8 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv) mach_t *mach = (mach_t *) priv; uint8_t port_dword = addr & 0xfc; - if ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { if (addr & 0x100) { mach_log("Port WORDB Write=%04x.\n", 0x02ee + (port_dword << 8)); mach_accel_outb(0x02ee + (addr & 1) + (port_dword << 8), val, mach); @@ -4875,7 +4666,8 @@ mach32_ap_writew(uint32_t addr, uint16_t val, void *priv) mach_t *mach = (mach_t *) priv; uint8_t port_dword = addr & 0xfc; - if ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { if (addr & 0x100) { mach_log("Port WORDW Write=%04x.\n", 0x02ee + (port_dword << 8)); mach_accel_outw(0x02ee + (port_dword << 8), val, mach); @@ -4895,7 +4687,8 @@ mach32_ap_writel(uint32_t addr, uint32_t val, void *priv) mach_t *mach = (mach_t *) priv; uint8_t port_dword = addr & 0xfc; - if ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { if (addr & 0x100) { mach_log("Port WORDL Write=%04x.\n", 0x02ee + (port_dword << 8)); mach_accel_outw(0x02ee + (port_dword << 8), val & 0xffff, mach); @@ -4918,7 +4711,8 @@ mach32_ap_readb(uint32_t addr, void *priv) uint8_t temp; uint8_t port_dword = addr & 0xfc; - if ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { if (addr & 0x100) { temp = mach_accel_inb(0x02ee + (addr & 1) + (port_dword << 8), mach); } else { @@ -4937,7 +4731,8 @@ mach32_ap_readw(uint32_t addr, void *priv) uint16_t temp; uint8_t port_dword = addr & 0xfc; - if ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { if (addr & 0x100) { temp = mach_accel_inw(0x02ee + (port_dword << 8), mach); } else { @@ -4956,7 +4751,8 @@ mach32_ap_readl(uint32_t addr, void *priv) uint32_t temp; uint8_t port_dword = addr & 0xfc; - if ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && + ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { if (addr & 0x100) { temp = mach_accel_inw(0x02ee + (port_dword << 8), mach); temp |= (mach_accel_inw(0x02ee + (port_dword << 8) + 4, mach) << 8); @@ -4984,7 +4780,6 @@ mach32_updatemapping(mach_t *mach) if (mach->regs[0xbd] & 4) { mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; - mach_log("Bit 2 of BD.\n"); } else { switch (svga->gdcreg[6] & 0x0c) { case 0x0: /*128k at A0000*/ @@ -5020,14 +4815,6 @@ mach32_updatemapping(mach_t *mach) mach->ap_size = 4; mem_mapping_set_addr(&mach->mmio_linear_mapping, mach->linear_base, mach->ap_size << 20); } - /*Force IBM/ATI mode on when the MMIO registers are loaded.*/ - if (mach->local_cntl & 0x20) { - if (!ibm8514_on) { - ibm8514_on ^= 1; - svga->adv_flags |= FLAG_ATI; - svga_recalctimings(svga); - } - } } else { mach->ap_size = 4; mem_mapping_disable(&mach->mmio_linear_mapping); @@ -5037,39 +4824,36 @@ mach32_updatemapping(mach_t *mach) static void mach32_hwcursor_draw(svga_t *svga, int displine) { - const mach_t *mach = (mach_t *) svga->priv; + const mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = &svga->dev8514; uint16_t dat; int comb; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int offset = dev->hwcursor_latch.x - dev->hwcursor_latch.xoff; uint32_t color0; uint32_t color1; if (svga->bpp == 8) { - color0 = svga->pallook[mach->cursor_col_0]; - color1 = svga->pallook[mach->cursor_col_1]; - mach_log("8BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); + color0 = dev->pallook[mach->cursor_col_0]; + color1 = dev->pallook[mach->cursor_col_1]; } else if (svga->bpp == 15) { color0 = video_15to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff]; color1 = video_15to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff]; - mach_log("15BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); } else if (svga->bpp == 16) { color0 = video_16to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff]; color1 = video_16to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff]; - mach_log("16BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); } else { color0 = ((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0); color1 = ((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1); - mach_log("24BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); } - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + if (dev->interlace && dev->hwcursor_oddeven) + dev->hwcursor_latch.addr += 16; for (int x = 0; x < 64; x += 8) { - dat = svga->vram[svga->hwcursor_latch.addr & svga->vram_mask] | (svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_mask] << 8); + dat = dev->vram[dev->hwcursor_latch.addr & dev->vram_mask] | (dev->vram[(dev->hwcursor_latch.addr + 1) & dev->vram_mask] << 8); for (int xx = 0; xx < 8; xx++) { comb = (dat >> (xx << 1)) & 0x03; - if (offset >= svga->hwcursor_latch.x) { + if (offset >= dev->hwcursor_latch.x) { switch (comb) { case 0: (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = color0; @@ -5087,250 +4871,287 @@ mach32_hwcursor_draw(svga_t *svga, int displine) } offset++; } - svga->hwcursor_latch.addr += 2; + dev->hwcursor_latch.addr += 2; } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + if (dev->interlace && !dev->hwcursor_oddeven) + dev->hwcursor_latch.addr += 16; } static void mach_io_remove(mach_t *mach) { - io_removehandler(0x01ce, 2, - mach_in, NULL, NULL, - mach_out, NULL, NULL, mach); - io_removehandler(0x03c0, 32, - mach_in, NULL, NULL, - mach_out, NULL, NULL, mach); + io_removehandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x2ea, 0x0004, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); - io_removehandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - - io_removehandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x02ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x22ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); } static void mach_io_set(mach_t *mach) { - io_sethandler(0x01ce, 2, - mach_in, NULL, NULL, - mach_out, NULL, NULL, mach); - io_sethandler(0x03c0, 32, - mach_in, NULL, NULL, - mach_out, NULL, NULL, mach); + io_sethandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_sethandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x2ea, 0x0004, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); - io_sethandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_sethandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x02ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x22ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); +} - io_sethandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); +static uint8_t +mach_mca_read(int port, void *priv) +{ + const mach_t *mach = (mach_t *) priv; + + mach_log("[%04X]: MCA read port = %x, val = %02x.\n", CS, port & 7, mach->pos_regs[port & 7]); + return mach->pos_regs[port & 7]; +} + +static void +mach_mca_write(int port, uint8_t val, void *priv) +{ + mach_t *mach = (mach_t *) priv; + + if (port < 0x102) + return; + + mach->pos_regs[port & 7] = val; + mach_log("[%04X]: MCA write port = %x, val = %02x, biosaddr = %05x.\n", CS, port & 7, mach->pos_regs[port & 7], (((mach->pos_regs[3] & 0x3e) << 0x0c) >> 1) + 0xc0000); + mem_mapping_disable(&mach->bios_rom.mapping); + mem_mapping_disable(&mach->bios_rom2.mapping); + if (mach->pos_regs[2] & 0x01) { + mem_mapping_enable(&mach->bios_rom.mapping); + mem_mapping_enable(&mach->bios_rom2.mapping); + } +} + +static uint8_t +mach_mca_feedb(void *priv) +{ + const mach_t *mach = (mach_t *) priv; + + mach_log("FeedB = %x.\n", mach->pos_regs[2] & 0x01); + return mach->pos_regs[2] & 0x01; +} + +static void +mach_mca_reset(void *priv) +{ + mach_t *mach = (mach_t *) priv; + + mem_mapping_disable(&mach->bios_rom.mapping); + mem_mapping_disable(&mach->bios_rom2.mapping); + mach_log("MCA reset.\n"); + ibm8514_on = 0; + vga_on = 1; + mach_mca_write(0x102, 0, mach); } static uint8_t @@ -5339,6 +5160,9 @@ mach32_pci_read(UNUSED(int func), int addr, void *priv) const mach_t *mach = (mach_t *) priv; uint8_t ret = 0x00; + if ((addr >= 0x30) && (addr <= 0x33) && !mach->has_bios) + return ret; + switch (addr) { case 0x00: ret = 0x02; /*ATI*/ @@ -5413,14 +5237,18 @@ static void mach32_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; + if ((addr >= 0x30) && (addr <= 0x33) && !mach->has_bios) + return; switch (addr) { case PCI_REG_COMMAND: mach->pci_regs[PCI_REG_COMMAND] = val & 0x27; - mach_io_remove(mach); if (val & PCI_COMMAND_IO) { - mach_io_set(mach); - } + io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + } else + io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + mach32_updatemapping(mach); break; @@ -5462,7 +5290,6 @@ mach8_init(const device_t *info) mach_t *mach; svga_t *svga; ibm8514_t *dev; - uint32_t memory; mach = malloc(sizeof(mach_t)); memset(mach, 0x00, sizeof(mach_t)); @@ -5472,30 +5299,42 @@ mach8_init(const device_t *info) mach->pci_bus = !!(info->flags & DEVICE_PCI); mach->vlb_bus = !!(info->flags & DEVICE_VLB); - dev->local = info->local; - dev->vram_size = (1024 << 10); - dev->vram = calloc(dev->vram_size, 1); - dev->changedvram = calloc(dev->vram_size >> 12, 1); - dev->vram_mask = dev->vram_size - 1; - dev->map8 = svga->pallook; - memory = device_get_config_int("memory"); + mach->mca_bus = !!(info->flags & DEVICE_MCA); + dev->type = info->flags; + dev->local = info->local & 0xff; + mach->has_bios = !(info->local & 0xff00); + mach->memory = device_get_config_int("memory"); + mach->ramdac_type = mach->pci_bus ? device_get_config_int("ramdac") : 1; - if (dev->local) { - if (mach->vlb_bus) + if (dev->local >= 2) { + if (mach->pci_bus) { + if (mach->has_bios) { + rom_init(&mach->bios_rom, + BIOS_MACH32_PCI_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + } + } + else if (mach->vlb_bus) rom_init(&mach->bios_rom, BIOS_MACH32_VLB_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else if (mach->pci_bus) + else if (mach->mca_bus) { rom_init(&mach->bios_rom, - BIOS_MACH32_PCI_ROM_PATH, + BIOS_MACH32_MCA_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else + rom_init(&mach->bios_rom2, + BIOS_MACH32_MCA_ROM_PATH, + 0xc8000, 0x1000, 0x0fff, + 0x8000, MEM_MAPPING_EXTERNAL); + } else { rom_init(&mach->bios_rom, BIOS_MACH32_ISA_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + } } else { rom_init(&mach->bios_rom, BIOS_MACH8_ROM_PATH, @@ -5503,75 +5342,108 @@ mach8_init(const device_t *info) 0, MEM_MAPPING_EXTERNAL); } - svga_init(info, svga, mach, dev->local ? (memory << 10) : (512 << 10), /*default: 512kB for Mach8, 2MB for Mach32*/ - mach_recalctimings, - mach_in, mach_out, - dev->local ? mach32_hwcursor_draw : NULL, - NULL); - - if (dev->local) { - switch (memory) { - case 1024: - mach->misc |= 0x04; - break; - case 2048: - mach->misc |= 0x08; - break; - case 4096: - mach->misc |= 0x0c; - break; - - default: - break; - } - svga->hwcursor.cur_ysize = 64; - mach->config1 = 0x20; - mach->config2 = 0x08; - /*Fake the RAMDAC to give the VLB/MCA variants full 24-bit support until said RAMDAC is implemented.*/ + if (dev->local >= 2) { + svga_init(info, svga, mach, mach->memory << 10, /*default: 2MB for Mach32*/ + mach_recalctimings, + mach_in, mach_out, + mach32_hwcursor_draw, + NULL); + dev->hwcursor.cur_ysize = 64; + dev->vram_size = svga->vram_max; + dev->vram = svga->vram; + dev->changedvram = svga->changedvram; + dev->vram_mask = svga->vram_mask; + mach->config1 = 0x20; + mach->config2 = 0x08; + if (mach->pci_bus && !mach->ramdac_type) + svga->ramdac = device_add(&ati68860_ramdac_device); + else + svga->ramdac = device_add(&ati68875_ramdac_device); if (mach->vlb_bus) { video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_vlb); - mach->config1 |= 0x0c; + if (!is486) + mach->config1 |= 0x0a; + else + mach->config1 |= 0x0c; mach->config1 |= 0x0400; + svga->clock_gen = device_add(&ati18811_0_device); + } else if (mach->mca_bus) { + video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_mca); + if (is286 && !is386) + mach->config1 |= 0x04; + else + mach->config1 |= 0x06; + mach->config1 |= 0x0400; + mach->config1 |= 0x1000; + svga->clock_gen = device_add(&ati18811_1_device); } else if (mach->pci_bus) { video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_pci); mach->config1 |= 0x0e; - mach->config1 |= 0x0a00; + if (mach->ramdac_type) + mach->config1 |= 0x0400; + else + mach->config1 |= 0x0a00; mach->config2 |= 0x2000; - svga->ramdac = device_add(&ati68860_ramdac_device); + svga->clock_gen = device_add(&ati18811_0_device); } else { video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); + mach->config1 |= 0x0400; + svga->clock_gen = device_add(&ati18811_0_device); } mem_mapping_add(&mach->mmio_linear_mapping, 0, 0, mach32_ap_readb, mach32_ap_readw, mach32_ap_readl, mach32_ap_writeb, mach32_ap_writew, mach32_ap_writel, NULL, MEM_MAPPING_EXTERNAL, mach); mem_mapping_disable(&mach->mmio_linear_mapping); } else { + svga_init(info, svga, mach, (512 << 10), /*default: 512kB VGA for 28800-6 + 1MB for Mach8*/ + mach_recalctimings, + mach_in, mach_out, + NULL, + NULL); + dev->vram_size = (1024 << 10); + dev->vram = calloc(dev->vram_size, 1); + dev->changedvram = calloc(dev->vram_size >> 12, 1); + dev->vram_mask = dev->vram_size - 1; video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); - mach->config1 = 0x02 | 0x20 | 0x80; - mach->config2 = 0x02; - dev->ext_pitch = 1024; + mach->config1 = 0x02 | 0x20 | 0x80; + mach->config2 = 0x02; + svga->clock_gen = device_add(&ati18810_device); } + dev->bpp = 0; + svga->getclock = ics2494_getclock; + dev->ext_pitch = 1024; + dev->ext_crt_pitch = 0x80; svga->force_old_addr = 1; - svga->miscout = 1; - svga->bpp = 8; - svga->packed_chain4 = 1; - ibm8514_enabled = 1; - ibm8514_has_vga = 1; - dev->ibm_mode = 1; - dev->rowoffset = 128; + svga->miscout = 1; + svga->bpp = 8; + svga->packed_chain4 = 1; + dev->rowoffset = 0x80; + io_sethandler(0x01ce, 2, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_sethandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_sethandler(0x46e8, 1, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); mach_io_set(mach); - if (dev->local) { + if (dev->local >= 2) { svga->decode_mask = (4 << 20) - 1; mach->cursor_col_1 = 0xff; mach->ext_cur_col_1_r = 0xff; mach->ext_cur_col_1_g = 0xff; - dev->ext_crt_pitch = 128; if (mach->vlb_bus) ati_eeprom_load(&mach->eeprom, "mach32_vlb.nvr", 1); - else if (mach->pci_bus) { - ati_eeprom_load(&mach->eeprom, "mach32_pci.nvr", 1); + else if (mach->mca_bus) { + ati_eeprom_load(&mach->eeprom, "mach32_mca.nvr", 1); mem_mapping_disable(&mach->bios_rom.mapping); - mach->card = pci_add_card(PCI_ADD_VIDEO, mach32_pci_read, mach32_pci_write, mach); + mem_mapping_disable(&mach->bios_rom2.mapping); + mach->pos_regs[0] = 0x89; + mach->pos_regs[1] = 0x80; + mca_add(mach_mca_read, mach_mca_write, mach_mca_feedb, mach_mca_reset, mach); + } else if (mach->pci_bus) { + ati_eeprom_load(&mach->eeprom, "mach32_pci.nvr", 1); + if (mach->has_bios) { + mem_mapping_disable(&mach->bios_rom.mapping); + pci_add_card(PCI_ADD_NORMAL, mach32_pci_read, mach32_pci_write, mach, &mach->pci_slot); + } else + pci_add_card(PCI_ADD_VIDEO, mach32_pci_read, mach32_pci_write, mach, &mach->pci_slot); mach->pci_regs[PCI_REG_COMMAND] = 0x83; mach->pci_regs[0x30] = 0x00; mach->pci_regs[0x32] = 0x0c; @@ -5603,6 +5475,12 @@ mach32_vlb_available(void) return rom_present(BIOS_MACH32_VLB_ROM_PATH); } +static int +mach32_mca_available(void) +{ + return rom_present(BIOS_MACH32_MCA_ROM_PATH); +} + static int mach32_pci_available(void) { @@ -5616,7 +5494,7 @@ mach_close(void *priv) svga_t *svga = &mach->svga; ibm8514_t *dev = &svga->dev8514; - if (dev) { + if (dev && (dev->local < 2)) { free(dev->vram); free(dev->changedvram); } @@ -5640,7 +5518,7 @@ mach_force_redraw(void *priv) mach_t *mach = (mach_t *) priv; svga_t *svga = &mach->svga; - svga->fullchange = changeframecount; + svga->fullchange = svga->monitor->mon_changeframecount; } // clang-format off @@ -5677,11 +5555,64 @@ static const device_config_t mach32_config[] = { } }; +// clang-format off +static const device_config_t mach32_pci_config[] = { + { + .name = "ramdac", + .description = "RAMDAC type", + .type = CONFIG_SELECTION, + .default_int = 0, + .selection = { + { + .description = "ATI 68860", + .value = 0 + }, + { + .description = "ATI 68875", + .value = 1 + }, + { + .description = "" + } + } + }, + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 2048, + .selection = { + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "2 MB", + .value = 2048 + }, + { + .description = "4 MB", + .value = 4096 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +}; + const device_t mach8_isa_device = { .name = "ATI Mach8 (ISA)", .internal_name = "mach8_isa", .flags = DEVICE_ISA, - .local = 0, + .local = 1, .init = mach8_init, .close = mach_close, .reset = NULL, @@ -5695,7 +5626,7 @@ const device_t mach32_isa_device = { .name = "ATI Mach32 (ISA)", .internal_name = "mach32_isa", .flags = DEVICE_ISA, - .local = 1, + .local = 2, .init = mach8_init, .close = mach_close, .reset = NULL, @@ -5709,7 +5640,7 @@ const device_t mach32_vlb_device = { .name = "ATI Mach32 (VLB)", .internal_name = "mach32_vlb", .flags = DEVICE_VLB, - .local = 1, + .local = 2, .init = mach8_init, .close = mach_close, .reset = NULL, @@ -5719,16 +5650,45 @@ const device_t mach32_vlb_device = { .config = mach32_config }; +const device_t mach32_mca_device = { + .name = "ATI Mach32 (MCA)", + .internal_name = "mach32_mca", + .flags = DEVICE_MCA, + .local = 2, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach32_mca_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_config +}; + const device_t mach32_pci_device = { .name = "ATI Mach32 (PCI)", .internal_name = "mach32_pci", .flags = DEVICE_PCI, - .local = 1, + .local = 2, .init = mach8_init, .close = mach_close, .reset = NULL, { .available = mach32_pci_available }, .speed_changed = mach_speed_changed, .force_redraw = mach_force_redraw, - .config = mach32_config + .config = mach32_pci_config }; + +const device_t mach32_onboard_pci_device = { + .name = "ATI Mach32 (PCI) On-Board", + .internal_name = "mach32_pci_onboard", + .flags = DEVICE_PCI, + .local = 2 | 0x100, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_pci_config +}; + diff --git a/src/video/vid_att20c49x_ramdac.c b/src/video/vid_att20c49x_ramdac.c index 3f995c56a..13b19af1e 100644 --- a/src/video/vid_att20c49x_ramdac.c +++ b/src/video/vid_att20c49x_ramdac.c @@ -28,8 +28,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> -typedef struct -{ +typedef struct att49x_ramdac_t { int type; int state; uint8_t ctrl; @@ -42,9 +41,9 @@ enum { }; static void -att49x_ramdac_control(uint8_t val, void *p, svga_t *svga) +att49x_ramdac_control(uint8_t val, void *priv, svga_t *svga) { - att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv; ramdac->ctrl = val; switch ((ramdac->ctrl >> 5) & 7) { case 0: @@ -73,9 +72,9 @@ att49x_ramdac_control(uint8_t val, void *p, svga_t *svga) } void -att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -110,9 +109,9 @@ att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) } uint8_t -att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +att49x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); diff --git a/src/video/vid_att2xc498_ramdac.c b/src/video/vid_att2xc498_ramdac.c index 9919b7111..42bf583a8 100644 --- a/src/video/vid_att2xc498_ramdac.c +++ b/src/video/vid_att2xc498_ramdac.c @@ -28,8 +28,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> -typedef struct -{ +typedef struct att498_ramdac_t { int type; int state; int loop; @@ -37,9 +36,9 @@ typedef struct } att498_ramdac_t; static void -att498_ramdac_control(uint8_t val, void *p, svga_t *svga) +att498_ramdac_control(uint8_t val, void *priv, svga_t *svga) { - att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + att498_ramdac_t *ramdac = (att498_ramdac_t *) priv; ramdac->ctrl = val; if (val == 0xff) @@ -73,9 +72,9 @@ att498_ramdac_control(uint8_t val, void *p, svga_t *svga) } void -att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + att498_ramdac_t *ramdac = (att498_ramdac_t *) priv; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -109,9 +108,9 @@ att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) } uint8_t -att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +att498_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + att498_ramdac_t *ramdac = (att498_ramdac_t *) priv; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); diff --git a/src/video/vid_bt48x_ramdac.c b/src/video/vid_bt48x_ramdac.c index bb276ece6..91ddce956 100644 --- a/src/video/vid_bt48x_ramdac.c +++ b/src/video/vid_bt48x_ramdac.c @@ -29,13 +29,13 @@ #include <86box/video.h> #include <86box/vid_svga.h> -typedef struct -{ +typedef struct bt48x_ramdac_t { PALETTE extpal; uint32_t extpallook[256]; uint8_t cursor32_data[256]; uint8_t cursor64_data[1024]; - int hwc_y, hwc_x; + int hwc_y; + int hwc_x; uint8_t cmd_r0; uint8_t cmd_r1; uint8_t cmd_r2; @@ -85,9 +85,9 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga) } void -bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) +bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga) { - bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; uint32_t o32; uint8_t *cd; uint16_t index; @@ -233,11 +233,11 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t * } uint8_t -bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) +bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) { - bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; uint8_t temp = 0xff; - uint8_t *cd; + const uint8_t *cd; uint16_t index; uint8_t rs = (addr & 0x03); uint16_t da_mask = 0x03ff; @@ -360,9 +360,9 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) } void -bt48x_recalctimings(void *p, svga_t *svga) +bt48x_recalctimings(void *priv, svga_t *svga) { - bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; + const bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; svga->interlace = ramdac->cmd_r2 & 0x08; if (ramdac->cmd_r3 & 0x08) @@ -386,7 +386,7 @@ bt48x_hwcursor_draw(svga_t *svga, int displine) uint32_t clr2; uint32_t clr3; uint32_t *p; - uint8_t *cd; + const uint8_t *cd; bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) svga->ramdac; clr1 = ramdac->extpallook[1]; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 14ff3b221..41195210b 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -12,9 +12,11 @@ * * Authors: Sarah Walker, * Miran Grca, + * W. M. Martinez, * * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. + * Copyright 2023 W. M. Martinez */ #include #include @@ -33,7 +35,6 @@ #include <86box/video.h> #include <86box/vid_cga.h> #include <86box/vid_cga_comp.h> -#include <86box/plat_unused.h> #define CGA_RGB 0 #define CGA_COMPOSITE 1 @@ -51,9 +52,9 @@ static video_timings_t timing_cga = { .type = VIDEO_ISA, .write_b = 8, .write_w void cga_recalctimings(cga_t *cga); void -cga_out(uint16_t addr, uint8_t val, void *priv) +cga_out(uint16_t addr, uint8_t val, void *p) { - cga_t *cga = (cga_t *) priv; + cga_t *cga = (cga_t *) p; uint8_t old; if ((addr >= 0x3d0) && (addr <= 0x3d7)) @@ -90,16 +91,13 @@ cga_out(uint16_t addr, uint8_t val, void *priv) if (old ^ val) cga_recalctimings(cga); return; - - default: - break; } } uint8_t -cga_in(uint16_t addr, void *priv) +cga_in(uint16_t addr, void *p) { - const cga_t *cga = (cga_t *) priv; + cga_t *cga = (cga_t *) p; uint8_t ret = 0xff; @@ -116,32 +114,29 @@ cga_in(uint16_t addr, void *priv) case 0x3DA: ret = cga->cgastat; break; - - default: - break; } return ret; } void -cga_pravetz_out(UNUSED(uint16_t addr), uint8_t val, void *priv) +cga_pravetz_out(uint16_t addr, uint8_t val, void *p) { - cga_t *cga = (cga_t *) priv; + cga_t *cga = (cga_t *) p; cga->fontbase = (((unsigned int) val) << 8); } uint8_t -cga_pravetz_in(UNUSED(uint16_t addr), void *priv) +cga_pravetz_in(uint16_t addr, void *p) { - const cga_t *cga = (cga_t *) priv; + cga_t *cga = (cga_t *) p; return (cga->fontbase >> 8); } void -cga_waitstates(UNUSED(void *priv)) +cga_waitstates(void *p) { int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; @@ -151,9 +146,9 @@ cga_waitstates(UNUSED(void *priv)) } void -cga_write(uint32_t addr, uint8_t val, void *priv) +cga_write(uint32_t addr, uint8_t val, void *p) { - cga_t *cga = (cga_t *) priv; + cga_t *cga = (cga_t *) p; cga->vram[addr & 0x3fff] = val; if (cga->snow_enabled) { @@ -165,9 +160,9 @@ cga_write(uint32_t addr, uint8_t val, void *priv) } uint8_t -cga_read(uint32_t addr, void *priv) +cga_read(uint32_t addr, void *p) { - cga_t *cga = (cga_t *) priv; + cga_t *cga = (cga_t *) p; cga_waitstates(cga); if (cga->snow_enabled) { @@ -182,8 +177,7 @@ void cga_recalctimings(cga_t *cga) { double disptime; - double _dispontime; - double _dispofftime; + double _dispontime, _dispofftime; if (cga->cgamode & 1) { disptime = (double) (cga->crtc[0] + 1); @@ -200,18 +194,14 @@ cga_recalctimings(cga_t *cga) } void -cga_poll(void *priv) +cga_poll(void *p) { - cga_t *cga = (cga_t *) priv; + cga_t *cga = (cga_t *) p; uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; int drawcursor; - int x; - int c; - int xs_temp; - int ys_temp; + int x, c, xs_temp, ys_temp; int oldvc; - uint8_t chr; - uint8_t attr; + uint8_t chr, attr; uint8_t border; uint16_t dat; int cols[4]; @@ -231,21 +221,21 @@ cga_poll(void *priv) video_wait_for_buffer(); } cga->lastline = cga->displine; - for (c = 0; c < 8; c++) { - if ((cga->cgamode & 0x12) == 0x12) { - buffer32->line[cga->displine << 1][c] = buffer32->line[(cga->displine << 1) + 1][c] = 0; - if (cga->cgamode & 1) { - buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = 0; - } else { - buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = 0; - } - } else { - buffer32->line[cga->displine << 1][c] = buffer32->line[(cga->displine << 1) + 1][c] = (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) { - buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; - } else { - buffer32->line[cga->displine << 1][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; - } + if ((cga->cgamode & 0x12) == 0x12) { + for (c = 0; c < 8; ++c) { + buffer32->line[cga->displine][c] = 0; + if (cga->cgamode & 1) + buffer32->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = 0; + else + buffer32->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = 0; + } + } else { + for (c = 0; c < 8; ++c) { + buffer32->line[cga->displine][c] = (cga->cgacol & 15) + 16; + if (cga->cgamode & 1) + buffer32->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; + else + buffer32->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; } } if (cga->cgamode & 1) { @@ -265,11 +255,11 @@ cga_poll(void *priv) cols[0] = (attr >> 4) + 16; if (drawcursor) { for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + buffer32->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } } else { for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } cga->ma++; @@ -277,8 +267,8 @@ cga_poll(void *priv) } else if (!(cga->cgamode & 2)) { for (x = 0; x < cga->crtc[1]; x++) { if (cga->cgamode & 8) { - chr = cga->vram[(cga->ma << 1) & 0x3fff]; - attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff]; + chr = cga->vram[((cga->ma << 1) & 0x3fff)]; + attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; } else chr = attr = 0; drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); @@ -292,11 +282,15 @@ cga_poll(void *priv) cga->ma++; if (drawcursor) { for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + buffer32->line[cga->displine][(x << 4) + (c << 1) + 8] + = buffer32->line[cga->displine][(x << 4) + (c << 1) + 9] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } } else { for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[cga->displine][(x << 4) + (c << 1) + 8] + = buffer32->line[cga->displine][(x << 4) + (c << 1) + 9] + = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } } @@ -323,7 +317,9 @@ cga_poll(void *priv) dat = 0; cga->ma++; for (c = 0; c < 8; c++) { - buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[cga->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + buffer32->line[cga->displine][(x << 4) + (c << 1) + 8] + = buffer32->line[cga->displine][(x << 4) + (c << 1) + 9] + = cols[dat >> 14]; dat <<= 2; } } @@ -337,7 +333,7 @@ cga_poll(void *priv) dat = 0; cga->ma++; for (c = 0; c < 16; c++) { - buffer32->line[cga->displine << 1][(x << 4) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; + buffer32->line[cga->displine][(x << 4) + c + 8] = cols[dat >> 15]; dat <<= 1; } } @@ -345,11 +341,9 @@ cga_poll(void *priv) } else { cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; if (cga->cgamode & 1) { - hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 3) + 16) << 2, cols[0]); - hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 3) + 16) << 2, cols[0]); + hline(buffer32, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]); } else { - hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 4) + 16) << 2, cols[0]); - hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 4) + 16) << 2, cols[0]); + hline(buffer32, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]); } } @@ -361,11 +355,9 @@ cga_poll(void *priv) if (cga->composite) { border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); - Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[cga->displine << 1]); - Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1) + 1]); + Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[cga->displine]); } else { - video_process_8(x, cga->displine << 1); - video_process_8(x, (cga->displine << 1) + 1); + video_process_8(x, cga->displine); } cga->sc = oldsc; @@ -440,31 +432,31 @@ cga_poll(void *priv) cga->lastline++; xs_temp = x; - ys_temp = (cga->lastline - cga->firstline) << 1; + ys_temp = cga->lastline - cga->firstline; if ((xs_temp > 0) && (ys_temp > 0)) { if (xs_temp < 64) xs_temp = 656; if (ys_temp < 32) - ys_temp = 400; + ys_temp = 200; if (!enable_overscan) xs_temp -= 16; if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { xsize = xs_temp; ysize = ys_temp; - set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); + set_screen_size(xsize, ysize + (enable_overscan ? 8 : 0)); if (video_force_resize_get()) video_force_resize_set(0); } if (enable_overscan) { - video_blit_memtoscreen(0, (cga->firstline - 4) << 1, - xsize, ((cga->lastline - cga->firstline) + 8) << 1); + video_blit_memtoscreen(0, cga->firstline - 4, + xsize, (cga->lastline - cga->firstline) + 8); } else { - video_blit_memtoscreen(8, cga->firstline << 1, - xsize, (cga->lastline - cga->firstline) << 1); + video_blit_memtoscreen(8, cga->firstline, + xsize, cga->lastline - cga->firstline); } } @@ -498,11 +490,11 @@ cga_poll(void *priv) } if (cga->cgadispon) cga->cgastat &= ~1; - if (cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))) + if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) cga->con = 1; if (cga->cgadispon && (cga->cgamode & 1)) { for (x = 0; x < (cga->crtc[1] << 1); x++) - cga->charbuffer[x] = cga->vram[((cga->ma << 1) + x) & 0x3fff]; + cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; } } } @@ -515,7 +507,7 @@ cga_init(cga_t *cga) } void * -cga_standalone_init(UNUSED(const device_t *info)) +cga_standalone_init(const device_t *info) { int display_type; cga_t *cga = malloc(sizeof(cga_t)); @@ -561,18 +553,18 @@ cga_pravetz_init(const device_t *info) } void -cga_close(void *priv) +cga_close(void *p) { - cga_t *cga = (cga_t *) priv; + cga_t *cga = (cga_t *) p; free(cga->vram); free(cga); } void -cga_speed_changed(void *priv) +cga_speed_changed(void *p) { - cga_t *cga = (cga_t *) priv; + cga_t *cga = (cga_t *) p; cga_recalctimings(cga); } diff --git a/src/video/vid_cga_comp.c b/src/video/vid_cga_comp.c index 31e4a6bf7..d580f0c06 100644 --- a/src/video/vid_cga_comp.c +++ b/src/video/vid_cga_comp.c @@ -44,22 +44,22 @@ static const double tau = 6.28318531; /* == 2*pi */ static unsigned char chroma_multiplexer[256] = { // clang-format off - 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, - 133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152, - 2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5, - 140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135, - 32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77, - 177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192, - 4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117, - 147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193, - 72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1, - 248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130, - 1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2, - 162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112, - 78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37, - 252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200, - 61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107, - 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252 + 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, + 133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152, + 2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5, + 140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135, + 32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77, + 177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192, + 4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117, + 147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193, + 72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1, + 248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130, + 1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2, + 162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112, + 78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37, + 252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200, + 61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107, + 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252 // clang-format on }; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 225810974..6afc719c1 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -39,6 +39,8 @@ #include <86box/vid_ddc.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #define BIOS_GD5401_PATH "roms/video/cirruslogic/avga1.rom" #define BIOS_GD5402_PATH "roms/video/cirruslogic/avga2.rom" @@ -158,8 +160,9 @@ typedef struct gd54xx_t { svga_t svga; - int has_bios, rev, - bit32; + int has_bios; + int rev; + int bit32; rom_t bios_rom; uint32_t vram_size; @@ -174,61 +177,97 @@ typedef struct gd54xx_t { } ramdac; struct { - uint16_t width, height; - uint16_t dst_pitch, src_pitch; - uint16_t trans_col, trans_mask; + uint16_t width; + uint16_t height; + uint16_t dst_pitch; + uint16_t src_pitch; + uint16_t trans_col; + uint16_t trans_mask; uint16_t height_internal; - uint16_t msd_buf_pos, msd_buf_cnt; + uint16_t msd_buf_pos; + uint16_t msd_buf_cnt; uint8_t status; - uint8_t mask, mode, rop, modeext; - uint8_t ms_is_dest, msd_buf[32]; + uint8_t mask; + uint8_t mode; + uint8_t rop; + uint8_t modeext; + uint8_t ms_is_dest; + uint8_t msd_buf[32]; - uint32_t fg_col, bg_col; - uint32_t dst_addr_backup, src_addr_backup; - uint32_t dst_addr, src_addr; - uint32_t sys_src32, sys_cnt; + uint32_t fg_col; + uint32_t bg_col; + uint32_t dst_addr_backup; + uint32_t src_addr_backup; + uint32_t dst_addr; + uint32_t src_addr; + uint32_t sys_src32; + uint32_t sys_cnt; /* Internal state */ - int pixel_width, pattern_x; - int x_count, y_count; - int xx_count, dir; + int pixel_width; + int pattern_x; + int x_count; + int y_count; + int xx_count; + int dir; int unlock_special; } blt; struct { int mode; - uint16_t stride, r1sz, r1adjust, r2sz, - r2adjust, r2sdz, wvs, wve, - hzoom, vzoom; - uint8_t occlusion, colorkeycomparemask, - colorkeycompare; - int region1size, region2size, - colorkeymode; + uint16_t stride; + uint16_t r1sz; + uint16_t r1adjust; + uint16_t r2sz; + uint16_t r2adjust; + uint16_t r2sdz; + uint16_t wvs; + uint16_t wve; + uint16_t hzoom; + uint16_t vzoom; + uint8_t occlusion; + uint8_t colorkeycomparemask; + uint8_t colorkeycompare; + int region1size; + int region2size; + int colorkeymode; uint32_t ck; } overlay; - int pci, vlb, mca, countminusone; - int vblank_irq, vportsync; + int pci; + int vlb; + int mca; + int countminusone; + int vblank_irq; + int vportsync; uint8_t pci_regs[256]; - uint8_t int_line, unlocked, status, extensions; + uint8_t int_line; + uint8_t unlocked; + uint8_t status; + uint8_t extensions; uint8_t crtcreg_mask; uint8_t fc; /* Feature Connector */ - int card, id; + int id; + + uint8_t pci_slot; + uint8_t irq_state; uint8_t pos_regs[8]; - uint32_t lfb_base, vgablt_base; + uint32_t lfb_base; + uint32_t vgablt_base; int mmio_vram_overlap; uint32_t extpallook[256]; PALETTE extpal; - void *i2c, *ddc; + void *i2c; + void *ddc; } gd54xx_t; static video_timings_t timing_gd54xx_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 8, .read_w = 8, .read_l = 12 }; @@ -484,9 +523,9 @@ gd54xx_update_irqs(gd54xx_t *gd54xx) return; if ((gd54xx->vblank_irq > 0) && gd54xx_vga_vsync_enabled(gd54xx)) - pci_set_irq(gd54xx->card, PCI_INTA); + pci_set_irq(gd54xx->pci_slot, PCI_INTA, &gd54xx->irq_state); else - pci_clear_irq(gd54xx->card, PCI_INTA); + pci_clear_irq(gd54xx->pci_slot, PCI_INTA, &gd54xx->irq_state); } static void @@ -512,23 +551,23 @@ gd54xx_is_5422(svga_t *svga) static void gd54xx_overlay_draw(svga_t *svga, int displine) { - gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; - int shift = (svga->crtc[0x27] >= CIRRUS_ID_CLGD5446) ? 2 : 0; - int h_acc = svga->overlay_latch.h_acc; - int r[8]; - int g[8]; - int b[8]; - int x_read = 4; - int x_write = 4; - uint32_t *p; - uint8_t *src = &svga->vram[(svga->overlay_latch.addr << shift) & svga->vram_mask]; - int bpp = svga->bpp; - int bytesperpix = (bpp + 7) / 8; - uint8_t *src2 = &svga->vram[(svga->ma - (svga->hdisp * bytesperpix)) & svga->vram_display_mask]; - int occl; - int ckval; + const gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; + int shift = (svga->crtc[0x27] >= CIRRUS_ID_CLGD5446) ? 2 : 0; + int h_acc = svga->overlay_latch.h_acc; + int r[8]; + int g[8]; + int b[8]; + int x_read = 4; + int x_write = 4; + uint32_t *p; + uint8_t *src = &svga->vram[(svga->overlay_latch.addr << shift) & svga->vram_mask]; + int bpp = svga->bpp; + int bytesperpix = (bpp + 7) / 8; + uint8_t *src2 = &svga->vram[(svga->ma - (svga->hdisp * bytesperpix)) & svga->vram_display_mask]; + int occl; + int ckval; - p = &((uint32_t *) svga->monitor->target_buffer->line[displine])[gd54xx->overlay.region1size + svga->x_add]; + p = &(svga->monitor->target_buffer->line[displine])[gd54xx->overlay.region1size + svga->x_add]; src2 += gd54xx->overlay.region1size * bytesperpix; OVERLAY_SAMPLE(); @@ -768,6 +807,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) else return; break; + + default: + break; } return; } @@ -823,6 +865,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->dac_addr = (svga->dac_addr + 1) & 255; svga->dac_pos = 0; break; + + default: + break; } return; case 0x3ce: @@ -869,6 +914,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) case 7: svga->colournocare = val; break; + + default: + break; } if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424)) @@ -905,6 +953,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) } svga->seqregs[2] &= 0x0f; } + fallthrough; case 0x09: case 0x0a: gd54xx_recalc_banking(gd54xx); @@ -1024,6 +1073,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) case 0x39: gd543x_mmio_write(0xb8021, val, gd54xx); break; + + default: + break; } } return; @@ -1139,6 +1191,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->overlay.ena = (val & 1) != 0; gd54xx_update_overlay(gd54xx); break; + + default: + break; } if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { @@ -1152,6 +1207,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } svga_out(addr, val, svga); } @@ -1222,6 +1280,9 @@ gd54xx_in(uint16_t addr, void *priv) case 2048: ret |= 0x18; break; + + default: + break; } } break; @@ -1246,6 +1307,9 @@ gd54xx_in(uint16_t addr, void *priv) case 4096: ret |= 0x98; /*64-bit (5434 and up) DRAM data bus width for 4M of memory*/ break; + + default: + break; } break; case 0x15: /*Scratch Pad 3 (Memory size for 543x)*/ @@ -1261,6 +1325,9 @@ gd54xx_in(uint16_t addr, void *priv) case 4: ret |= 0x04; break; + + default: + break; } } break; @@ -1298,6 +1365,9 @@ gd54xx_in(uint16_t addr, void *priv) case 0x1e: ret = gd54xx->vclk_d[svga->seqaddr - 0x1b]; break; + + default: + break; } break; } else @@ -1353,6 +1423,9 @@ gd54xx_in(uint16_t addr, void *priv) else ret = svga->vgapal[index].b & 0x3f; break; + + default: + break; } break; case 0x3ce: @@ -1470,6 +1543,9 @@ gd54xx_in(uint16_t addr, void *priv) gd54xx->vportsync = !gd54xx->vportsync; ret = gd54xx->vportsync ? 0x80 : 0x00; break; + + default: + break; } } else { if ((svga->gdcaddr < 2) && !gd54xx->unlocked) @@ -1510,6 +1586,9 @@ gd54xx_in(uint16_t addr, void *priv) if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) ret = 0xff; /*Standard CL-GD5430/40*/ break; + + default: + break; } break; default: @@ -1587,6 +1666,9 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) svga->banked_mask = 0x7fff; gd54xx->mmio_vram_overlap = 1; break; + + default: + break; } if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { @@ -1608,9 +1690,11 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) } } else if (gd54xx->pci) { base = gd54xx->lfb_base; - /* if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - size = 32 * 1024 * 1024; - else */ +#if 0 + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) + size = 32 * 1024 * 1024; + else +#endif if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) size = 16 * 1024 * 1024; else @@ -1646,10 +1730,10 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) static void gd54xx_recalctimings(svga_t *svga) { - gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; - uint8_t clocksel; - uint8_t rdmask; - uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; + const gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; + uint8_t clocksel; + uint8_t rdmask; + uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; svga->rowoffset = (svga->crtc[0x13]) | (((int) (uint32_t) (svga->crtc[0x1b] & 0x10)) << 4); @@ -1785,8 +1869,14 @@ gd54xx_recalctimings(svga_t *svga) else svga->render = svga_render_8bpp_highres; break; + + default: + break; } break; + + default: + break; } } else { svga->bpp = 15; @@ -1809,18 +1899,21 @@ gd54xx_recalctimings(svga_t *svga) if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) svga->clock = (cpuclock * (float) (1ULL << 32)) / ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); else { - int n = gd54xx->vclk_n[clocksel] & 0x7f; - int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; - int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; - float freq = (14318184.0 * ((float) n / ((float) d * m))); + int n = gd54xx->vclk_n[clocksel] & 0x7f; + int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; + uint8_t m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; + float freq = (14318184.0F * ((float) n / ((float) d * m))); if (gd54xx_is_5422(svga)) { switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) { case 2: - freq /= 2.0; + freq /= 2.0F; break; case 4: if (!gd54xx_is_5434(svga)) - freq /= 3.0; + freq /= 3.0F; + break; + + default: break; } } @@ -1833,16 +1926,16 @@ gd54xx_recalctimings(svga_t *svga) static void gd54xx_hwcursor_draw(svga_t *svga, int displine) { - gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; - int comb; - int b0; - int b1; - uint8_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int pitch = (svga->hwcursor.cur_xsize == 64) ? 16 : 4; - uint32_t bgcol = gd54xx->extpallook[0x00]; - uint32_t fgcol = gd54xx->extpallook[0x0f]; - uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; + const gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; + int comb; + int b0; + int b1; + uint8_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int pitch = (svga->hwcursor.cur_xsize == 64) ? 16 : 4; + uint32_t bgcol = gd54xx->extpallook[0x00]; + uint32_t fgcol = gd54xx->extpallook[0x0f]; + uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; offset <<= linedbl; @@ -1866,16 +1959,19 @@ gd54xx_hwcursor_draw(svga_t *svga, int displine) break; case 1: /* The pixel is shown in the cursor background color */ - ((uint32_t *) svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = bgcol; + (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = bgcol; break; case 2: /* The pixel is shown as the inverse of the original screen pixel (XOR cursor) */ - ((uint32_t *) svga->monitor->target_buffer->line[displine])[offset + svga->x_add] ^= 0xffffff; + (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] ^= 0xffffff; break; case 3: /* The pixel is shown in the cursor foreground color */ - ((uint32_t *) svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = fgcol; + (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = fgcol; + break; + + default: break; } } @@ -1944,6 +2040,9 @@ gd54xx_rop(gd54xx_t *gd54xx, uint8_t *res, uint8_t *dst, const uint8_t *src) case 0xda: *res = ~(*src & *dst); break; + + default: + break; } } @@ -2117,6 +2216,9 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) } } break; + + default: + break; } svga->changedvram[addr >> 12] = changeframecount; @@ -2132,7 +2234,7 @@ gd54xx_get_aperture(uint32_t addr) static int gd54xx_aperture2_enabled(gd54xx_t *gd54xx) { - svga_t *svga = &gd54xx->svga; + const svga_t *svga = &gd54xx->svga; if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) return 0; @@ -2168,8 +2270,8 @@ gd54xx_readb_linear(uint32_t addr, void *priv) return gd54xx_mem_sys_dest_read(gd54xx); switch (ap) { - case 0: default: + case 0: break; case 1: /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ @@ -2215,12 +2317,13 @@ gd54xx_readw_linear(uint32_t addr, void *priv) } switch (ap) { - case 0: default: + case 0: return svga_readw_linear(addr, svga); case 2: /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ addr ^= 0x00000002; + fallthrough; case 1: temp = svga_readb_linear(addr + 1, svga); temp |= (svga_readb_linear(addr, svga) << 8); @@ -2265,8 +2368,8 @@ gd54xx_readl_linear(uint32_t addr, void *priv) } switch (ap) { - case 0: default: + case 0: return svga_readl_linear(addr, svga); case 1: temp = svga_readb_linear(addr + 1, svga); @@ -2294,7 +2397,7 @@ gd54xx_readl_linear(uint32_t addr, void *priv) } static uint8_t -gd5436_aperture2_readb(uint32_t addr, void *priv) +gd5436_aperture2_readb(UNUSED(uint32_t addr), void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; @@ -2337,7 +2440,7 @@ gd5436_aperture2_readl(uint32_t addr, void *priv) } static void -gd5436_aperture2_writeb(uint32_t addr, uint8_t val, void *priv) +gd5436_aperture2_writeb(UNUSED(uint32_t addr), uint8_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; @@ -2450,8 +2553,8 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) if (svga->writemode < 4) { switch (ap) { - case 0: default: + case 0: svga_writew_linear(addr, val, svga); return; case 2: @@ -2462,21 +2565,24 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) if (svga->fast) cycles -= svga->monitor->mon_video_timing_write_w; + return; case 3: return; } } else { switch (ap) { - case 0: default: + case 0: svga_write_linear(addr, val & 0xff, svga); svga_write_linear(addr + 1, val >> 8, svga); return; case 2: addr ^= 0x00000002; + fallthrough; case 1: svga_write_linear(addr + 1, val & 0xff, svga); svga_write_linear(addr, val >> 8, svga); + return; case 3: return; } @@ -2516,8 +2622,8 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) if (svga->writemode < 4) { switch (ap) { - case 0: default: + case 0: svga_writel_linear(addr, val, svga); return; case 1: @@ -2531,13 +2637,14 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) svga_writeb_linear(addr + 2, val >> 8, svga); svga_writeb_linear(addr + 1, val >> 16, svga); svga_writeb_linear(addr, val >> 24, svga); + return; case 3: return; } } else { switch (ap) { - case 0: default: + case 0: svga_write_linear(addr, val & 0xff, svga); svga_write_linear(addr + 1, val >> 8, svga); svga_write_linear(addr + 2, val >> 16, svga); @@ -2554,6 +2661,7 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) svga_write_linear(addr + 2, val >> 8, svga); svga_write_linear(addr + 1, val >> 16, svga); svga_write_linear(addr, val >> 24, svga); + return; case 3: return; } @@ -2788,6 +2896,9 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *priv) gd54xx_start_blit(0, 0xffffffff, gd54xx, svga); } break; + + default: + break; } } else if (gd54xx->mmio_vram_overlap) gd54xx_write(addr, val, gd54xx); @@ -2982,6 +3093,9 @@ gd543x_mmio_read(uint32_t addr, void *priv) case 0x40: ret = gd54xx->blt.status; break; + + default: + break; } } else if (gd54xx->mmio_vram_overlap) ret = gd54xx_read(addr, gd54xx); @@ -3151,6 +3265,9 @@ gd54xx_get_pixel_width(gd54xx_t *gd54xx) case CIRRUS_BLTMODE_PIXELWIDTH32: ret = 4; break; + + default: + break; } return ret; @@ -3236,13 +3353,13 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) /* The vertical offset is in the three low-order bits of the Source Address register. */ pattern_y = gd54xx->blt.src_addr & 0x07; - /* Mode Pattern bytes Pattern line bytes + /* Mode Pattern bytes Pattern line bytes --------------------------------------------------- - Color Expansion 8 1 - 8-bpp 64 8 - 16-bpp 128 16 - 24-bpp 256 32 - 32-bpp 256 32 + Color Expansion 8 1 + 8-bpp 64 8 + 16-bpp 128 16 + 24-bpp 256 32 + 32-bpp 256 32 */ /* The boundary has to be equal to the size of the pattern. */ @@ -3419,7 +3536,7 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) dst = svga->vram[dst_addr & svga->vram_mask]; svga->changedvram[(dst_addr & svga->vram_mask) >> 12] = changeframecount; - gd54xx_rop(gd54xx, (uint8_t *) &dst, (uint8_t *) &dst, (const uint8_t *) &src); + gd54xx_rop(gd54xx, &dst, &dst, (const uint8_t *) &src); if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)) mask = !mask; @@ -3557,11 +3674,11 @@ gd54xx_start_blit(uint32_t cpu_dat, uint32_t count, gd54xx_t *gd54xx, svga_t *sv } static uint8_t -cl_pci_read(int func, int addr, void *priv) +cl_pci_read(UNUSED(int func), int addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; - uint8_t ret = 0x00; + const gd54xx_t *gd54xx = (gd54xx_t *) priv; + const svga_t *svga = &gd54xx->svga; + uint8_t ret = 0x00; if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) ret = 0x00; @@ -3650,17 +3767,20 @@ cl_pci_read(int func, int addr, void *priv) case 0x3d: ret = PCI_INTA; break; + + default: + break; } return ret; } static void -cl_pci_write(int func, int addr, uint8_t val, void *priv) +cl_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; - uint32_t byte; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + const svga_t *svga = &gd54xx->svga; + uint32_t byte; if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) return; @@ -3720,13 +3840,16 @@ cl_pci_write(int func, int addr, uint8_t val, void *priv) case 0x3c: gd54xx->int_line = val; return; + + default: + break; } } static uint8_t gd5428_mca_read(int port, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; + const gd54xx_t *gd54xx = (gd54xx_t *) priv; return gd54xx->pos_regs[port & 7]; } @@ -3744,7 +3867,7 @@ gd5428_mca_write(int port, uint8_t val, void *priv) } static uint8_t -gd5428_mca_feedb(void *priv) +gd5428_mca_feedb(UNUSED(void *priv)) { return 1; } @@ -3821,17 +3944,17 @@ gd54xx_reset(void *priv) gd54xx->unlocked = 0; } -static void - * - gd54xx_init(const device_t *info) +static void * +gd54xx_init(const device_t *info) { - gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); - svga_t *svga = &gd54xx->svga; - int id = info->local & 0xff; - int vram; - char *romfn = NULL; - char *romfn1 = NULL; - char *romfn2 = NULL; + gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); + svga_t *svga = &gd54xx->svga; + int id = info->local & 0xff; + int vram; + const char *romfn = NULL; + const char *romfn1 = NULL; + const char *romfn2 = NULL; + memset(gd54xx, 0, sizeof(gd54xx_t)); gd54xx->pci = !!(info->flags & DEVICE_PCI); @@ -3963,6 +4086,9 @@ static void case CIRRUS_ID_CLGD5480: romfn = BIOS_GD5480_PATH; break; + + default: + break; } if (info->flags & DEVICE_MCA) { @@ -4056,7 +4182,10 @@ static void io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) { - pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); + if (romfn == NULL) + pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx, &gd54xx->pci_slot); + else + pci_add_card(PCI_ADD_NORMAL, cl_pci_read, cl_pci_write, gd54xx, &gd54xx->pci_slot); mem_mapping_disable(&gd54xx->bios_rom.mapping); } diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index be176d9d0..dcc72a76b 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -135,8 +135,8 @@ colorplus_poll(void *priv) 0x18, 0x1A, 0x1C, 0x1E, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F }; - uint8_t *plane0 = colorplus->cga.vram; - uint8_t *plane1 = colorplus->cga.vram + 0x4000; + const uint8_t *plane0 = colorplus->cga.vram; + const uint8_t *plane1 = colorplus->cga.vram + 0x4000; /* If one of the extra modes is not selected, drop down to the CGA * drawing code. */ diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index babd45756..b5d38a8e0 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -17,6 +17,7 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ +#include #include #include #include @@ -26,6 +27,7 @@ #include "cpu.h" #include <86box/io.h> #include <86box/timer.h> +#include <86box/pic.h> #include <86box/pit.h> #include <86box/mem.h> #include <86box/rom.h> @@ -92,11 +94,11 @@ ega_out(uint16_t addr, uint8_t val, void *priv) case 0xb2: case 0xbe: #if 0 - if (ega->regs[0xbe] & 8) { /*Read/write bank mode*/ - svga->read_bank = ((ega->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; - } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; + if (ega->regs[0xbe] & 8) { /*Read/write bank mode*/ + svga->read_bank = ((ega->regs[0xb2] >> 5) & 7) * 0x10000; + svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; + } else /*Single bank mode*/ + svga->read_bank = svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; #endif break; case 0xb3: @@ -188,6 +190,10 @@ ega_out(uint16_t addr, uint8_t val, void *priv) break; } break; + case 0x3c6: + if (ega_type == 2) + ega->ctl_mode = val; + break; case 0x3ce: ega->gdcaddr = val; break; @@ -298,8 +304,8 @@ ega_in(uint16_t addr, void *priv) ret = ega->attrregs[ega->attraddr]; break; case 0x3c2: - ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; - break; + ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; + break; case 0x3c4: if (ega_type) ret = ega->seqaddr; @@ -308,6 +314,10 @@ ega_in(uint16_t addr, void *priv) if (ega_type) ret = ega->seqregs[ega->seqaddr & 0xf]; break; + case 0x3c6: + if (ega_type == 2) + ret = ega->ctl_mode; + break; case 0x3c8: if (ega_type) ret = 2; @@ -341,7 +351,7 @@ ega_in(uint16_t addr, void *priv) case 0x10: case 0x11: - // TODO: Return light pen address once implemented + /* TODO: Return light pen address once implemented. */ if (ega_type) ret = ega->crtc[ega->crtcreg]; break; @@ -353,8 +363,45 @@ ega_in(uint16_t addr, void *priv) break; case 0x3da: ega->attrff = 0; - ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ - ret = ega->stat; + if (ega_type == 2) { + ret = ega->stat & 0xcf; + switch ((ega->attrregs[0x12] >> 4) & 0x03) { + case 0x00: + /* 00 = Pri. Red (5), Pri. Blue (4) */ + ret |= (ega->color_mux & 0x04) ? 0x20 : 0x00; + ret |= (ega->color_mux & 0x01) ? 0x10 : 0x00; + break; + case 0x01: + case 0x03: + /* 01 = Sec. Red (5), Sec. Green (4) */ + /* 11 = Sec. Red (5), Sec. Green (4) */ + ret |= (ega->color_mux & 0x20) ? 0x20 : 0x00; + ret |= (ega->color_mux & 0x10) ? 0x10 : 0x00; + break; + case 0x02: + /* 10 = Sec. Blue (5), Pri. Green (4) */ + ret |= (ega->color_mux & 0x08) ? 0x20 : 0x00; + ret |= (ega->color_mux & 0x02) ? 0x10 : 0x00; + break; + } + } else { + ega->stat ^= 0x30; /* Fools IBM EGA video BIOS self-test. */ + ret = ega->stat; + } + break; + case 0x7c6: + ret = 0xfd; /* EGA mode supported. */ + break; + case 0xbc6: + /* 0000 = None; + 0001 = Compaq Dual-Mode (DM) Monitor; + 0010 = RGBI Color Monitor; + 0011 = COMPAQ Color Monitor (RrGgBb) or Compatible; + 0100 - 1111 = Reserved. */ + ret = 0x01; + break; + case 0xfc6: + ret = 0xfd; break; default: @@ -368,6 +415,7 @@ void ega_recalctimings(ega_t *ega) { int clksel; + int color; double _dispontime; double _dispofftime; @@ -411,7 +459,26 @@ ega_recalctimings(ega_t *ega) ega->linedbl = ega->crtc[9] & 0x80; ega->rowcount = ega->crtc[9] & 0x1f; - if (ega->eeprom) { + if (ega_type == 2) { + color = (ega->miscout & 1); + clksel = ((ega->miscout & 0xc) >> 2); + + if (color) { + if (ega->vidclock) + crtcconst = (cpuclock / 16257000.0 * (double) (1ULL << 32)); + else + crtcconst = (cpuclock / (157500000.0 / 11.0) * (double) (1ULL << 32)); + } else { + if (ega->vidclock) + crtcconst = (cpuclock / 18981000.0 * (double) (1ULL << 32)); + else + crtcconst = (cpuclock / 16872000.0 * (double) (1ULL << 32)); + } + if (!(ega->seqregs[1] & 1)) + crtcconst *= 9.0; + else + crtcconst *= 8.0; + } else if (ega->eeprom) { clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); switch (clksel) { @@ -442,6 +509,10 @@ ega_recalctimings(ega_t *ega) else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); } + if (!(ega->seqregs[1] & 1)) + ega->dot_clock = crtcconst / 9.0; + else + ega->dot_clock = crtcconst / 8.0; ega->interlace = 0; @@ -496,9 +567,110 @@ ega_recalctimings(ega_t *ega) if (ega->dispofftime < TIMER_USEC) ega->dispofftime = TIMER_USEC; + ega->dot_time = (uint64_t) (ega->dot_clock); + if (ega->dot_time < TIMER_USEC) + ega->dot_time = TIMER_USEC; + ega_recalc_remap_func(ega); } +/* This is needed for the Compaq EGA so that it can pass the 3DA + palette mux part of the self-test. */ +void +ega_dot_poll(void *priv) +{ + ega_t *ega = (ega_t *) priv; + static uint8_t chr; + static uint8_t attr; + const bool doublewidth = ((ega->seqregs[1] & 8) != 0); + const bool attrblink = ((ega->attrregs[0x10] & 8) != 0); + const bool attrlinechars = (ega->attrregs[0x10] & 4); + const bool crtcreset = ((ega->crtc[0x17] & 0x80) == 0); + const bool seq9dot = ((ega->seqregs[1] & 1) == 0); + const bool blinked = ega->blink & 0x10; + const int dwshift = doublewidth ? 1 : 0; + const int dotwidth = 1 << dwshift; + const int charwidth = dotwidth * (seq9dot ? 9 : 8); + const int cursoron = (ega->sc == (ega->crtc[10] & 31)); + const int cursoraddr = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; + uint32_t addr; + int drawcursor; + uint32_t charaddr; + static int fg; + static int bg; + static uint32_t dat; + static int disptime; + static int _dispontime; + static int _dispofftime; + static int cclock = 0; + static int active = 0; + + if (ega->seqregs[1] & 8) { + disptime = ((ega->crtc[0] + 2) << 1); + _dispontime = ((ega->crtc[1] + 1) << 1); + } else { + disptime = (ega->crtc[0] + 2); + _dispontime = (ega->crtc[1] + 1); + } + _dispofftime = disptime - _dispontime; + + timer_advance_u64(&ega->dot_timer, ega->dot_time); + + if (ega->render == ega_render_text) + ega->color_mux = (dat & (0x100 >> (ega->dot >> dwshift))) ? fg : bg; + else + ega->color_mux = 0x00; + + addr = ega->remap_func(ega, ega->cca) & ega->vrammask; + + if (!crtcreset) { + chr = ega->vram[addr]; + attr = ega->vram[addr + 1]; + } else + chr = attr = 0; + + drawcursor = ((ega->cca == cursoraddr) && cursoron && ega->cursoron); + + if (attr & 8) + charaddr = ega->charsetb + (chr * 0x80); + else + charaddr = ega->charseta + (chr * 0x80); + + dat = ega->vram[charaddr + (ega->sc << 2)]; + dat <<= 1; + if ((chr & ~0x1F) == 0xC0 && attrlinechars) + dat |= (dat >> 1) & 1; + + if (!active) + dat = 0x200; + + if (drawcursor) { + bg = ega->egapal[attr & 0x0f]; + fg = ega->egapal[attr >> 4]; + } else { + fg = ega->egapal[attr & 0x0f]; + bg = ega->egapal[attr >> 4]; + if ((attr & 0x80) && attrblink) { + bg = ega->egapal[(attr >> 4) & 7]; + if (blinked) + fg = bg; + } + } + + ega->dot = (ega->dot + 1) % charwidth; + + if (ega->dot == 0) { + ega->cca = (ega->cca + 4) & 0x3ffff; + + cclock++; + + if (active && (cclock == _dispofftime)) + active = 0; + else if (!active && (cclock == _dispontime)) + active = 1; + } +} + void ega_poll(void *priv) { @@ -581,6 +753,7 @@ ega_poll(void *priv) if (ega->linedbl && !ega->linecountff) { ega->linecountff = 1; ega->ma = ega->maback; + ega->cca = ega->maback; } if (ega->sc == (ega->crtc[9] & 31)) { ega->linecountff = 0; @@ -591,11 +764,13 @@ ega_poll(void *priv) ega->maback += (ega->rowoffset << 3); ega->maback &= ega->vrammask; ega->ma = ega->maback; + ega->cca = ega->maback; } else { ega->linecountff = 0; ega->sc++; ega->sc &= 31; ega->ma = ega->maback; + ega->cca = ega->maback; } } ega->vc++; @@ -607,6 +782,7 @@ ega_poll(void *priv) else ega->ma = ega->maback = 0; ega->ma <<= 2; + ega->cca = ega->ma; ega->maback <<= 2; ega->sc = 0; if (ega->attrregs[0x10] & 0x20) { @@ -634,6 +810,7 @@ ega_poll(void *priv) if (ega->vc == ega->vsyncstart) { ega->dispon = 0; ega->stat |= 8; + // picint(1 << 2); x = ega->hdisp; if (ega->interlace && !ega->oddeven) @@ -673,6 +850,7 @@ ega_poll(void *priv) ega->ma <<= 2; ega->maback <<= 2; ega->ca <<= 2; + ega->cca = ega->ma; } if (ega->vc == ega->vtotal) { ega->vc = 0; @@ -1221,6 +1399,8 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) ega->crtc[6] = 255; timer_add(&ega->timer, ega_poll, ega, 1); + if (ega_type == 2) + timer_add(&ega->dot_timer, ega_dot_poll, ega, 1); } static void * @@ -1229,7 +1409,7 @@ ega_standalone_init(const device_t *info) ega_t *ega = malloc(sizeof(ega_t)); int monitor_type; - memset(ega, 0, sizeof(ega_t)); + memset(ega, 0x00, sizeof(ega_t)); video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ega); @@ -1240,6 +1420,8 @@ ega_standalone_init(const device_t *info) if ((info->local == EGA_IBM) || (info->local == EGA_ISKRA) || (info->local == EGA_TSENG)) ega_type = 0; + else if (info->local == EGA_COMPAQ) + ega_type = 2; else ega_type = 1; @@ -1250,6 +1432,7 @@ ega_standalone_init(const device_t *info) 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; case EGA_COMPAQ: + ega->ctl_mode = 0x21; rom_init(&ega->bios_rom, BIOS_CPQ_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; @@ -1293,6 +1476,11 @@ ega_standalone_init(const device_t *info) ega->eeprom = malloc(sizeof(ati_eeprom_t)); memset(ega->eeprom, 0, sizeof(ati_eeprom_t)); ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800.nvr", 0); + } else if (info->local == EGA_COMPAQ) { + io_sethandler(0x0084, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + io_sethandler(0x07c6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + io_sethandler(0x0bc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + io_sethandler(0x0fc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); } return ega; @@ -1354,11 +1542,11 @@ ega_speed_changed(void *priv) } /* SW1 SW2 SW3 SW4 - OFF OFF ON OFF Monochrome (5151) 1011 0x0B - ON OFF OFF ON Color 40x25 (5153) 0110 0x06 - OFF OFF OFF ON Color 80x25 (5153) 0111 0x07 - ON ON ON OFF Enhanced Color - Normal Mode (5154) 1000 0x08 - OFF ON ON OFF Enhanced Color - Enhanced Mode (5154) 1001 0x09 + OFF OFF ON OFF Monochrome (5151) 1011 0x0B + ON OFF OFF ON Color 40x25 (5153) 0110 0x06 + OFF OFF OFF ON Color 80x25 (5153) 0111 0x07 + ON ON ON OFF Enhanced Color - Normal Mode (5154) 1000 0x08 + OFF ON ON OFF Enhanced Color - Enhanced Mode (5154) 1001 0x09 0 = Switch closed (ON); 1 = Switch open (OFF). */ diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index a97d65cdb..318efb3f4 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -433,9 +433,7 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) case 5: et4000->kasan_cfg_regs[5] = val; et4000->svga.ksc5601_english_font_type = 0x100 | val; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 6: case 7: et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index c2ce39778..10e9695b4 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -69,7 +69,7 @@ typedef struct et4000w32p_t { svga_t svga; - uint8_t banking, banking2, adjust_cursor, rev; + uint8_t banking, banking2, adjust_cursor, rev, pci_slot; uint8_t regs[256], pci_regs[256]; @@ -500,7 +500,8 @@ et4000w32p_recalctimings(svga_t *svga) switch (svga->bpp) { case 15: case 16: - svga->hdisp >>= 1; + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) + svga->hdisp >>= 1; if (et4000->type <= ET4000W32P_REVC) { if (et4000->type == ET4000W32P_REVC) { if (svga->hdisp != 1024) @@ -513,7 +514,7 @@ et4000w32p_recalctimings(svga_t *svga) svga->hdisp /= 3; if (et4000->type <= ET4000W32P_REVC) et4000->adjust_cursor = 2; - if (et4000->type == ET4000W32P_DIAMOND && (svga->hdisp == 640 / 2 || svga->hdisp == 1232)) { + if ((et4000->type == ET4000W32P_DIAMOND) && ((svga->hdisp == (640 / 2)) || (svga->hdisp == 1232))) { svga->hdisp = 640; } break; @@ -1072,8 +1073,7 @@ et4000w32p_mmu_read(uint32_t addr, void *priv) case 0x8e: if (et4000->type >= ET4000W32P_REVC) return et4000->acl.internal.pixel_depth; - else - return et4000->acl.internal.vbus; + return et4000->acl.internal.vbus; case 0x8f: return et4000->acl.internal.xy_dir; case 0x90: @@ -2800,7 +2800,7 @@ et4000w32p_init(const device_t *info) et4000w32p_io_set(et4000); if (info->flags & DEVICE_PCI) - pci_add_card(PCI_ADD_VIDEO, et4000w32p_pci_read, et4000w32p_pci_write, et4000); + pci_add_card(PCI_ADD_NORMAL, et4000w32p_pci_read, et4000w32p_pci_write, et4000, &et4000->pci_slot); /* Hardwired bits: 00000000 1xx0x0xx */ /* R/W bits: xx xxxx */ diff --git a/src/video/vid_f82c425.c b/src/video/vid_f82c425.c index a2ffeddb5..400e6e1ec 100644 --- a/src/video/vid_f82c425.c +++ b/src/video/vid_f82c425.c @@ -39,7 +39,7 @@ * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 763cfe540..71534e432 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -74,7 +74,7 @@ static video_timings_t timing_genius = { .type = VIDEO_ISA, .write_b = 8, .write * Two card-specific registers control text and graphics display: * * 03B0: Control register. - * Bit 0: Map all graphics framebuffer into memory. + * Bit 0: Map all graphics framebuffer into memory. * Bit 2: Unknown. Set by GMC /M; cleared by mode set or GMC /T. * Bit 4: Set for CGA-compatible graphics, clear for native graphics. * Bit 5: Set for black on white, clear for white on black. @@ -404,13 +404,13 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) charh = 15 - (genius->genius_charh & 3); #if 0 - if (genius->genius_charh & 0x10) { - row = ((dl >> 1) / charh); - sc = ((dl >> 1) % charh); - } else { - row = (dl / charh); - sc = (dl % charh); - } + if (genius->genius_charh & 0x10) { + row = ((dl >> 1) / charh); + sc = ((dl >> 1) % charh); + } else { + row = (dl / charh); + sc = (dl % charh); + } #else row = (dl / charh); sc = (dl % charh); @@ -449,10 +449,10 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) for (int x = 0; x < w; x++) { #if 0 - if ((genius->genius_charh & 0x10) && ((addr + 2 * x) > 0x0FFF)) - chr = 0x00; - if ((genius->genius_charh & 0x10) && ((addr + 2 * x + 1) > 0x0FFF)) - attr = 0x00; + if ((genius->genius_charh & 0x10) && ((addr + 2 * x) > 0x0FFF)) + chr = 0x00; + if ((genius->genius_charh & 0x10) && ((addr + 2 * x + 1) > 0x0FFF)) + attr = 0x00; #endif chr = framebuf[(addr + 2 * x) & 0x3FFF]; attr = framebuf[(addr + 2 * x + 1) & 0x3FFF]; diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 587410c07..0c2c0270c 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -139,6 +139,7 @@ herculesplus_out(uint16_t port, uint8_t val, void *priv) return; old = dev->crtc[dev->crtcreg]; dev->crtc[dev->crtcreg] = val; + if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { /*Fix for Generic Turbo XT BIOS, *which sets up cursor registers wrong*/ @@ -282,6 +283,7 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) { unsigned ull; unsigned val; + unsigned ifg; unsigned ibg; unsigned cfg; const uint8_t *fnt; @@ -299,14 +301,19 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) /* MDA-compatible attributes */ ibg = 0; + ifg = 7; if ((attr & 0x77) == 0x70) { /* Invert */ + ifg = 0; ibg = 7; } if (attr & 8) - if (attr & 0x80) - ibg |= 8; /* High intensity BG */ + ifg |= 8; /* High intensity FG */ + if (attr & 0x80) + ibg |= 8; /* High intensity BG */ if ((attr & 0x77) == 0) /* Blank */ - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; + ifg = ibg; + ull = ((attr & 0x07) == 1) ? 13 : 0xffff; + if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) elg = 0; else @@ -330,6 +337,11 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) /* Generate pixel colour */ cfg = 0; + if (val & 0x100) + cfg = ifg; + else + cfg = ibg; + /* cfg = colour of foreground pixels */ if ((attr & 0x77) == 0) cfg = ibg; /* 'blank' attribute */ @@ -427,6 +439,8 @@ draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) cfg = olc ^ ibg; /* Strikethrough */ else if (dev->sc == ull) cfg = ulc ^ ibg; /* Underline */ + else if (val & 0x100) + cfg |= ~ibg; else cfg |= ibg; @@ -445,8 +459,8 @@ text_line(herculesplus_t *dev, uint16_t ca) for (uint8_t x = 0; x < dev->crtc[1]; x++) { if (dev->ctrl & 8) { - chr = dev->vram[(dev->ma << 1) & 0xfff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + chr = dev->vram[(dev->ma << 1) & 0x3fff]; + attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff]; } else chr = attr = 0; @@ -521,6 +535,7 @@ herculesplus_poll(void *priv) int x; int oldvc; int oldsc; + int cw = HERCULESPLUS_CW; VIDEO_MONITOR_PROLOGUE(); if (!dev->linepos) { @@ -544,7 +559,7 @@ herculesplus_poll(void *priv) if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) x = dev->crtc[1] << 4; else - x = dev->crtc[1] * 9; + x = dev->crtc[1] * cw; video_process_8(x, dev->displine); } @@ -607,7 +622,7 @@ herculesplus_poll(void *priv) if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) x = dev->crtc[1] << 4; else - x = dev->crtc[1] * 9; + x = dev->crtc[1] * cw; dev->lastline++; if ((dev->ctrl & 8) && ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { xsize = x; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index bd09a9ede..cee95e3a6 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -321,9 +321,7 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) svga->adv_flags &= ~FLAG_RAMDAC_SHIFT; if (val & 0x04) svga->adv_flags |= FLAG_RAMDAC_SHIFT; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; /*Bank registers*/ case 0xe8: case 0xe9: diff --git a/src/video/vid_ibm_rgb528_ramdac.c b/src/video/vid_ibm_rgb528_ramdac.c index b7a27781b..1b19a3a0f 100644 --- a/src/video/vid_ibm_rgb528_ramdac.c +++ b/src/video/vid_ibm_rgb528_ramdac.c @@ -27,32 +27,41 @@ #include <86box/vid_svga.h> #include <86box/plat_unused.h> -typedef union { +typedef union ibm_rgb528_pixel8_t { uint8_t pixel; struct { - uint8_t b : 2, g : 3, r : 2; + uint8_t b : 2; + uint8_t g : 3; + uint8_t r : 2; }; } ibm_rgb528_pixel8_t; -typedef union { +typedef union ibm_rgb528_pixel16_t { uint16_t pixel; struct { - uint16_t b_ : 5, g_ : 6, r_ : 5; + uint16_t b_ : 5; + uint16_t g_ : 6; + uint16_t r_ : 5; }; struct { - uint16_t b : 5, g : 5, r : 5, c : 1; + uint16_t b : 5; + uint16_t g : 5; + uint16_t r : 5; + uint16_t c : 1; }; } ibm_rgb528_pixel16_t; -typedef union { +typedef union ibm_rgb528_pixel32_t { uint32_t pixel; struct { - uint8_t b, g, r, a; + uint8_t b; + uint8_t g; + uint8_t r; + uint8_t a; }; } ibm_rgb528_pixel32_t; -typedef struct -{ +typedef struct ibm_rgb528_ramdac_t { PALETTE extpal; uint32_t extpallook[256]; uint8_t indexed_data[2048]; @@ -60,33 +69,37 @@ typedef struct uint8_t cursor64_data[1024]; uint8_t palettes[3][256]; ibm_rgb528_pixel32_t extra_pal[4]; - int16_t hwc_y, hwc_x; - uint16_t index, smlc_part; + int16_t hwc_y; + int16_t hwc_x; + uint16_t index; + uint16_t smlc_part; uint8_t cmd_r0; uint8_t cmd_r1; uint8_t cmd_r2; uint8_t cmd_r3; uint8_t cmd_r4; - uint8_t status, indx_cntl; - uint8_t cursor_array, - cursor_hotspot_x, cursor_hotspot_y; + uint8_t status; + uint8_t indx_cntl; + uint8_t cursor_array; + uint8_t cursor_hotspot_x; + uint8_t cursor_hotspot_y; } ibm_rgb528_ramdac_t; void ibm_rgb528_render_4bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel32_t dat_out; - uint8_t dat; - uint32_t dat32 = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; - uint8_t partition = (ramdac->indexed_data[0x07] & 0x0f) << 4; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t swap_nib = ramdac->indexed_data[0x72] & 0x21; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; + uint32_t *p; + ibm_rgb528_pixel32_t dat_out; + uint8_t dat; + uint32_t dat32 = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; + uint8_t partition = (ramdac->indexed_data[0x07] & 0x0f) << 4; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t swap_nib = ramdac->indexed_data[0x72] & 0x21; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; if ((svga->displine + svga->y_add) < 0) return; @@ -155,16 +168,16 @@ ibm_rgb528_render_4bpp(svga_t *svga) void ibm_rgb528_render_8bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel32_t dat_out; - uint8_t dat; - uint32_t dat32 = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; + uint32_t *p; + ibm_rgb528_pixel32_t dat_out; + uint8_t dat; + uint32_t dat32 = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; if ((svga->displine + svga->y_add) < 0) return; @@ -224,24 +237,24 @@ ibm_rgb528_render_8bpp(svga_t *svga) void ibm_rgb528_render_15_16bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel16_t *dat_ex; - ibm_rgb528_pixel32_t dat_out; - uint16_t dat; - uint32_t dat32 = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b16_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; - uint8_t by16_pol = ramdac->indexed_data[0x0c] & 0x20; - uint8_t b555_565 = ramdac->indexed_data[0x0c] & 0x02; - uint8_t bspr_cnt = ramdac->indexed_data[0x0c] & 0x01; - uint8_t partition = (ramdac->indexed_data[0x07] & 0x0e) << 4; - uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; - uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; - uint8_t temp; + uint32_t *p; + ibm_rgb528_pixel16_t *dat_ex; + ibm_rgb528_pixel32_t dat_out; + uint16_t dat; + uint32_t dat32 = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b16_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; + uint8_t by16_pol = ramdac->indexed_data[0x0c] & 0x20; + uint8_t b555_565 = ramdac->indexed_data[0x0c] & 0x02; + uint8_t bspr_cnt = ramdac->indexed_data[0x0c] & 0x01; + uint8_t partition = (ramdac->indexed_data[0x07] & 0x0e) << 4; + uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; + uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; + uint8_t temp; if ((svga->displine + svga->y_add) < 0) return; @@ -349,18 +362,18 @@ ibm_rgb528_render_15_16bpp(svga_t *svga) void ibm_rgb528_render_24bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel32_t *dat_ex; - uint32_t dat; - uint64_t dat64[6]; - uint8_t *dat8 = (uint8_t *) dat64; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b24_dcol = ramdac->indexed_data[0x0d] & 0x01; - uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; - uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; - uint8_t temp; + uint32_t *p; + ibm_rgb528_pixel32_t *dat_ex; + uint32_t dat; + uint64_t dat64[6]; + uint8_t *dat8 = (uint8_t *) dat64; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b24_dcol = ramdac->indexed_data[0x0d] & 0x01; + uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; + uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; + uint8_t temp; if ((svga->displine + svga->y_add) < 0) return; @@ -438,19 +451,19 @@ ibm_rgb528_render_24bpp(svga_t *svga) void ibm_rgb528_render_32bpp(svga_t *svga) { - uint32_t *p; - ibm_rgb528_pixel32_t *dat_ex; - uint32_t dat = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b32_dcol = ramdac->indexed_data[0x0e] & 0x03; - uint8_t by32_pol = ramdac->indexed_data[0x0e] & 0x04; - uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; - uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; - uint8_t temp; + uint32_t *p; + ibm_rgb528_pixel32_t *dat_ex; + uint32_t dat = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b32_dcol = ramdac->indexed_data[0x0e] & 0x03; + uint8_t by32_pol = ramdac->indexed_data[0x0e] & 0x04; + uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; + uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; + uint8_t temp; if ((svga->displine + svga->y_add) < 0) return; @@ -551,9 +564,9 @@ ibm_rgb528_set_bpp(ibm_rgb528_ramdac_t *ramdac, svga_t *svga) } void -ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; uint16_t index; uint8_t rs = (addr & 0x03); uint16_t da_mask = 0x03ff; @@ -612,6 +625,9 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga case 0xc0: ramdac->smlc_part = 0x0400; break; + + default: + break; } svga->dac_hwcursor.addr = ramdac->smlc_part; svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 0x04) ? 64 : 32; @@ -712,15 +728,18 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga case 0x07: ramdac->indx_cntl = val & 0x01; break; + + default: + break; } return; } uint8_t -ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); uint8_t loc_read = (ramdac->indexed_data[0x30] & 0x10); @@ -781,15 +800,18 @@ ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) case 0x07: temp = ramdac->indx_cntl; break; + + default: + break; } return temp; } void -ibm_rgb528_recalctimings(void *p, svga_t *svga) +ibm_rgb528_recalctimings(void *priv, svga_t *svga) { - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; svga->interlace = ramdac->indexed_data[0x071] & 0x20; @@ -814,6 +836,9 @@ ibm_rgb528_recalctimings(void *p, svga_t *svga) case 32: svga->render = ibm_rgb528_render_32bpp; break; + + default: + break; } } } @@ -824,16 +849,16 @@ ibm_rgb528_recalctimings(void *p, svga_t *svga) void ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) { - uint8_t dat; - uint8_t four_pixels = 0x00; - int pitch; - int x_pos; - int y_pos; - int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff; - uint32_t *p; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t pix_ordr = ramdac->indexed_data[0x30] & 0x20; - uint8_t cursor_mode = ramdac->indexed_data[0x30] & 0x03; + uint8_t dat; + uint8_t four_pixels = 0x00; + int pitch; + int x_pos; + int y_pos; + int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff; + uint32_t *p; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t pix_ordr = ramdac->indexed_data[0x30] & 0x20; + uint8_t cursor_mode = ramdac->indexed_data[0x30] & 0x03; /* The planes come in one part, and each plane is 2bpp, so a 32x32 cursor has 8 bytes per line, and a 64x64 @@ -873,6 +898,9 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) /* Cursor Color 3 */ p[x_pos] = ramdac->extra_pal[2].pixel; break; + + default: + break; } break; case 0x02: @@ -889,6 +917,9 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) /* Complement */ p[x_pos] ^= 0xffffff; break; + + default: + break; } break; case 0x03: @@ -901,8 +932,14 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) /* Cursor Color 2 */ p[x_pos] = ramdac->extra_pal[1].pixel; break; + + default: + break; } break; + + default: + break; } if ((x & 3) == 3) diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index adfaf6ad4..4b98e33b6 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -34,9 +34,12 @@ typedef struct icd2061_t { float freq[3]; - int count, bit_count, - unlocked, state; - uint32_t data, ctrl; + int count; + int bit_count; + int unlocked; + int state; + uint32_t data; + uint32_t ctrl; } icd2061_t; #ifdef ENABLE_ICD2061_LOG @@ -138,7 +141,7 @@ icd2061_write(void *p, int val) float icd2061_getclock(int clock, void *priv) { - icd2061_t *icd2061 = (icd2061_t *) priv; + const icd2061_t *icd2061 = (icd2061_t *) priv; if (clock > 2) clock = 2; diff --git a/src/video/vid_ics2494.c b/src/video/vid_ics2494.c index 16c4139fe..309d07966 100644 --- a/src/video/vid_ics2494.c +++ b/src/video/vid_ics2494.c @@ -51,7 +51,7 @@ ics2494_log(const char *fmt, ...) float ics2494_getclock(int clock, void *priv) { - ics2494_t *ics2494 = (ics2494_t *) priv; + const ics2494_t *ics2494 = (ics2494_t *) priv; if (clock > 15) clock = 15; @@ -66,6 +66,63 @@ ics2494_init(const device_t *info) memset(ics2494, 0, sizeof(ics2494_t)); switch (info->local) { + case 10: + /* ATI 18810 for ATI 28800 */ + ics2494->freq[0x0] = 30240000.0; + ics2494->freq[0x1] = 32000000.0; + ics2494->freq[0x2] = 37500000.0; + ics2494->freq[0x3] = 39000000.0; + ics2494->freq[0x4] = 42954000.0; + ics2494->freq[0x5] = 48771000.0; + ics2494->freq[0x6] = 16657000.0; + ics2494->freq[0x7] = 36000000.0; + ics2494->freq[0x8] = 40000000.0; + ics2494->freq[0x9] = 56644000.0; + ics2494->freq[0xa] = 75000000.0; + ics2494->freq[0xb] = 65000000.0; + ics2494->freq[0xc] = 50350000.0; + ics2494->freq[0xd] = 56640000.0; + ics2494->freq[0xe] = 28322000.0; + ics2494->freq[0xf] = 44900000.0; + break; + case 110: + /* ATI 18811-0 for ATI Mach32 */ + ics2494->freq[0x0] = 30240000.0; + ics2494->freq[0x1] = 32000000.0; + ics2494->freq[0x2] = 110000000.0; + ics2494->freq[0x3] = 80000000.0; + ics2494->freq[0x4] = 42954000.0; + ics2494->freq[0x5] = 48771000.0; + ics2494->freq[0x6] = 92400000.0; + ics2494->freq[0x7] = 36000000.0; + ics2494->freq[0x8] = 39910000.0; + ics2494->freq[0x9] = 44900000.0; + ics2494->freq[0xa] = 75000000.0; + ics2494->freq[0xb] = 65000000.0; + ics2494->freq[0xc] = 50350000.0; + ics2494->freq[0xd] = 56640000.0; + ics2494->freq[0xe] = 0.0; + ics2494->freq[0xf] = 44900000.0; + break; + case 111: + /* ATI 18811-1 for ATI Mach32 MCA */ + ics2494->freq[0x0] = 135000000.0; + ics2494->freq[0x1] = 32000000.0; + ics2494->freq[0x2] = 110000000.0; + ics2494->freq[0x3] = 80000000.0; + ics2494->freq[0x4] = 100000000.0; + ics2494->freq[0x5] = 126000000.0; + ics2494->freq[0x6] = 92400000.0; + ics2494->freq[0x7] = 36000000.0; + ics2494->freq[0x8] = 39910000.0; + ics2494->freq[0x9] = 44900000.0; + ics2494->freq[0xa] = 75000000.0; + ics2494->freq[0xb] = 65000000.0; + ics2494->freq[0xc] = 50350000.0; + ics2494->freq[0xd] = 56640000.0; + ics2494->freq[0xe] = 0.0; + ics2494->freq[0xf] = 44900000.0; + break; case 305: /* ICS2494A(N)-205 for S3 86C924 */ ics2494->freq[0x0] = 25175000.0; @@ -85,6 +142,9 @@ ics2494_init(const device_t *info) ics2494->freq[0xe] = 75000000.0; ics2494->freq[0xf] = 94500000.0; break; + + default: + break; } return ics2494; @@ -112,3 +172,45 @@ const device_t ics2494an_305_device = { .force_redraw = NULL, .config = NULL }; + +const device_t ati18810_device = { + .name = "ATI 18810 Clock Generator", + .internal_name = "ati18810", + .flags = 0, + .local = 10, + .init = ics2494_init, + .close = ics2494_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ati18811_0_device = { + .name = "ATI 18811-0 Clock Generator", + .internal_name = "ati18811_0", + .flags = 0, + .local = 110, + .init = ics2494_init, + .close = ics2494_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ati18811_1_device = { + .name = "ATI 18811-1 Clock Generator", + .internal_name = "ati18811_1", + .flags = 0, + .local = 111, + .init = ics2494_init, + .close = ics2494_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_ics2595.c b/src/video/vid_ics2595.c index 6420ee7e4..ecb414f2b 100644 --- a/src/video/vid_ics2595.c +++ b/src/video/vid_ics2595.c @@ -26,9 +26,11 @@ #include <86box/plat_unused.h> typedef struct ics2595_t { - int oldfs3, oldfs2; + int oldfs3; + int oldfs2; int dat; - int pos, state; + int pos; + int state; double clocks[16]; double output_clock; @@ -43,9 +45,9 @@ enum { static int ics2595_div[4] = { 8, 4, 2, 1 }; void -ics2595_write(void *p, int strobe, int dat) +ics2595_write(void *priv, int strobe, int dat) { - ics2595_t *ics2595 = (ics2595_t *) p; + ics2595_t *ics2595 = (ics2595_t *) priv; int d; int n; int l; @@ -88,6 +90,7 @@ static void * ics2595_init(UNUSED(const device_t *info)) { ics2595_t *ics2595 = (ics2595_t *) malloc(sizeof(ics2595_t)); + memset(ics2595, 0, sizeof(ics2595_t)); return ics2595; @@ -105,15 +108,15 @@ ics2595_close(void *priv) double ics2595_getclock(void *priv) { - ics2595_t *ics2595 = (ics2595_t *) priv; + const ics2595_t *ics2595 = (ics2595_t *) priv; return ics2595->output_clock; } void -ics2595_setclock(void *p, double clock) +ics2595_setclock(void *priv, double clock) { - ics2595_t *ics2595 = (ics2595_t *) p; + ics2595_t *ics2595 = (ics2595_t *) priv; ics2595->output_clock = clock; } diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index 7a3b416fc..3ff511394 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -749,8 +749,8 @@ text_line(incolor_t *dev, uint16_t ca) for (uint8_t x = 0; x < dev->crtc[1]; x++) { if (dev->ctrl & 8) { - chr = dev->vram[(dev->ma << 1) & 0xfff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + chr = dev->vram[(dev->ma << 1) & 0x3fff]; + attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff]; } else chr = attr = 0; @@ -850,6 +850,7 @@ incolor_poll(void *priv) int x; int oldvc; int oldsc; + int cw = INCOLOR_CW; if (!dev->linepos) { timer_advance_u64(&dev->timer, dev->dispofftime); @@ -931,7 +932,7 @@ incolor_poll(void *priv) if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH)) x = dev->crtc[1] << 4; else - x = dev->crtc[1] * 9; + x = dev->crtc[1] * cw; dev->lastline++; if ((dev->ctrl & 8) && ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { xsize = x; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 67f8d5751..bea27c164 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -424,11 +424,12 @@ typedef struct mystique_t { xcolkeyl, xcolkeyh, xcrcbitsel; + uint8_t pci_slot, irq_state, pad, pad0; + uint8_t pci_regs[256], crtcext_regs[6], xreg_regs[256], dmamap[16]; - int card, vram_size, crtcext_idx, xreg_idx, - xzoomctrl, + int vram_size, crtcext_idx, xreg_idx, xzoomctrl, pixel_count, trap_count; atomic_int busy, blitter_submit_refcount, @@ -664,9 +665,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x3c8: mystique->xreg_idx = val; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 0x3c6: case 0x3c7: case 0x3c9: @@ -1031,9 +1030,9 @@ mystique_update_irqs(mystique_t *mystique) irq = 1; if (irq) - pci_set_irq(mystique->card, PCI_INTA); + pci_set_irq(mystique->pci_slot, PCI_INTA, &mystique->irq_state); else - pci_clear_irq(mystique->card, PCI_INTA); + pci_clear_irq(mystique->pci_slot, PCI_INTA, &mystique->irq_state); } #define READ8(addr, var) \ @@ -5460,7 +5459,7 @@ static void * mystique_init(const device_t *info) { mystique_t *mystique = malloc(sizeof(mystique_t)); - char *romfn; + char *romfn = NULL; memset(mystique, 0, sizeof(mystique_t)); @@ -5524,7 +5523,10 @@ mystique_init(const device_t *info) NULL, 0, mystique); mem_mapping_disable(&mystique->iload_mapping); - mystique->card = pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique); + if (romfn == NULL) + pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); + else + pci_add_card(PCI_ADD_NORMAL, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); mystique->pci_regs[0x06] = 0x80; mystique->pci_regs[0x07] = 0 << 1; mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 932e13913..cdc518c0c 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -84,8 +84,9 @@ oti_out(uint16_t addr, uint8_t val, void *priv) if (!oti->chip_id) { oti->enable_register = val & 1; return; - } else - break; + } + svga_out(addr, val, svga); + return; case 0x3c6: case 0x3c7: diff --git a/src/video/vid_ogc.c b/src/video/vid_ogc.c index edc4c841e..a0a49525d 100644 --- a/src/video/vid_ogc.c +++ b/src/video/vid_ogc.c @@ -84,8 +84,8 @@ ogc_out(uint16_t addr, uint8_t val, void *priv) { ogc_t *ogc = (ogc_t *) priv; - // if (addr >= 0x3c0 && addr <= 0x3cf){ - // addr = addr + 16; + // if (addr >= 0x3c0 && addr <= 0x3cf) { + // addr = addr + 16; // } switch (addr) { @@ -110,8 +110,8 @@ ogc_in(uint16_t addr, void *priv) { ogc_t *ogc = (ogc_t *) priv; - // if (addr >= 0x3c0 && addr <= 0x3cf){ - // addr = addr + 16; + // if (addr >= 0x3c0 && addr <= 0x3cf) { + // addr = addr + 16; // } uint8_t ret = 0xff; diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 0033e96d1..ce848b964 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -747,7 +747,7 @@ pgc_plot(pgc_t *dev, uint16_t x, uint16_t y) * Draw a line (using raster coordinates). * * Bresenham's Algorithm from: - * + * * * The line pattern mask to use is passed in. Return value is the * line pattern mask, rotated by the number of points drawn. @@ -1384,11 +1384,11 @@ hndl_window(pgc_t *dev) * core commands (listed below) and subclass commands (listed in the clone). * * Each row has five parameters: - * ASCII-mode command - * Hex-mode command - * Function that executes this command - * Function that parses this command when building a command list - * Parameter for the parse function + * ASCII-mode command + * Hex-mode command + * Function that executes this command + * Function that parses this command when building a command list + * Parameter for the parse function * * TODO: This list omits numerous commands present in a genuine PGC * (ARC, AREA, AREABC, BUFFER, CIRCLE etc etc). diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index bcdd64d40..8fcacee38 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -209,7 +209,9 @@ typedef struct s3_t { uint32_t linear_base, linear_size; uint8_t pci_regs[256]; - int card; + + uint8_t pci_slot; + uint8_t irq_state; uint32_t vram_mask; uint8_t data_available; @@ -465,9 +467,9 @@ s3_update_irqs(s3_t *s3) return; if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) { - pci_set_irq(s3->card, PCI_INTA); + pci_set_irq(s3->pci_slot, PCI_INTA, &s3->irq_state); } else { - pci_clear_irq(s3->card, PCI_INTA); + pci_clear_irq(s3->pci_slot, PCI_INTA, &s3->irq_state); } } @@ -8349,8 +8351,12 @@ s3_init(const device_t *info) return NULL; } - if (s3->pci) - s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); + if (s3->pci) { + if (bios_fn == NULL) + pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3, &s3->pci_slot); + else + pci_add_card(PCI_ADD_NORMAL, s3_pci_read, s3_pci_write, s3, &s3->pci_slot); + } s3->i2c = i2c_gpio_init("ddc_s3"); s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c)); diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 6c382cf7f..5dc29e5da 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -172,7 +172,9 @@ typedef struct virge_t { uint32_t linear_base, linear_size; uint8_t pci_regs[256]; - int card; + + uint8_t pci_slot; + uint8_t irq_state; int pci; int chip; @@ -278,7 +280,6 @@ typedef struct virge_t { uint32_t cmd_dma_base; uint32_t dma_ptr; uint64_t blitter_time; - volatile int fifo_slot; int fifo_slots_num; pc_timer_t tri_timer; @@ -419,9 +420,9 @@ static void s3_virge_update_irqs(virge_t *virge) { if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & (virge->subsys_cntl & INT_MASK))) - pci_set_irq(virge->card, PCI_INTA); + pci_set_irq(virge->pci_slot, PCI_INTA, &virge->irq_state); else - pci_clear_irq(virge->card, PCI_INTA); + pci_clear_irq(virge->pci_slot, PCI_INTA, &virge->irq_state); } static void @@ -998,9 +999,9 @@ s3_virge_vblank_start(svga_t *svga) static void s3_virge_mmio_fifo_write(uint32_t addr, uint8_t val, virge_t *virge) { - if ((addr & 0xffff) < 0x8000) { + if ((addr & 0xffff) < 0x8000) s3_virge_bitblt(virge, 8, val); - } else { + else { switch (addr & 0xffff) { case 0x859c: virge->cmd_dma = val; @@ -1032,9 +1033,6 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) else s3_virge_bitblt(virge, 32, val); } else { - if (virge->fifo_slot >= virge->fifo_slots_num) - return; - virge->fifo_slot++; switch (addr & 0xfffc) { case 0x8590: virge->cmd_dma_base = val; @@ -1482,24 +1480,24 @@ s3_virge_mmio_read(uint32_t addr, void *priv) s3_virge_log("[%04X:%08X]: MMIO ReadB addr = %04x\n", CS, cpu_state.pc, addr & 0xffff); switch (addr & 0xffff) { + case 0x8504: + virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP); + ret = virge->subsys_stat; + s3_virge_update_irqs(virge); + return ret; case 0x8505: - ret = 0xc0; - if (!virge->s3d_busy && !virge->fifo_slot) + ret = 0xd0; + if (!virge->s3d_busy) ret |= 0x20; - if (virge->fifo_slot) - virge->fifo_slot--; - ret |= (virge->fifo_slots_num - virge->fifo_slot); return ret; case 0x850c: ret = virge->advfunc_cntl & 0x3f; - if (virge->fifo_slot) - virge->fifo_slot--; - ret |= (virge->fifo_slots_num - virge->fifo_slot) << 6; + ret |= virge->fifo_slots_num << 6; ret &= 0xff; break; case 0x850d: - ret = (virge->fifo_slots_num - virge->fifo_slot) >> 2; + ret = virge->fifo_slots_num >> 2; break; case 0x83b0: @@ -1576,23 +1574,17 @@ s3_virge_mmio_read_w(uint32_t addr, void *priv) switch (addr & 0xfffe) { case 0x8504: - ret = 0xc000; - if (!virge->s3d_busy && !virge->fifo_slot) + ret = 0xd000; + if (!virge->s3d_busy) ret |= 0x2000; - if (!virge->fifo_slot) - virge->subsys_stat |= INT_FIFO_EMP; + virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP); ret |= virge->subsys_stat; - if (virge->fifo_slot) - virge->fifo_slot--; - ret |= (virge->fifo_slots_num - virge->fifo_slot) << 8; s3_virge_update_irqs(virge); return ret; case 0x850c: ret = virge->advfunc_cntl & 0x3f; - if (virge->fifo_slot) - virge->fifo_slot--; - ret |= (virge->fifo_slots_num - virge->fifo_slot) << 6; + ret |= virge->fifo_slots_num << 6; break; case 0x859c: @@ -1682,26 +1674,17 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) break; case 0x8504: - ret = 0x0000c000; - if (!virge->s3d_busy && !virge->fifo_slot) { + ret = 0x0000d000; + if (!virge->s3d_busy) ret |= 0x00002000; - if (!virge->s3d_busy) - virge->subsys_stat |= INT_3DF_EMP; - if (!virge->fifo_slot) - virge->subsys_stat |= INT_FIFO_EMP; - } + virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP); ret |= virge->subsys_stat; - if (virge->fifo_slot) - virge->fifo_slot--; - ret |= (virge->fifo_slots_num - virge->fifo_slot) << 8; s3_virge_update_irqs(virge); break; case 0x850c: ret = virge->advfunc_cntl & 0x3f; - if (virge->fifo_slot) - virge->fifo_slot--; - ret |= (virge->fifo_slots_num - virge->fifo_slot) << 6; + ret |= virge->fifo_slots_num << 6; break; case 0x8590: @@ -3533,9 +3516,7 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) bg = svga->pallook[virge->hwc_bg_col & 0xff]; break; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 15: if (virge->chip != S3_VIRGEGX2) { @@ -3543,9 +3524,7 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) bg = video_15to32[virge->hwc_bg_col & 0xffff]; break; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 16: if (virge->chip != S3_VIRGEGX2) { @@ -3553,9 +3532,7 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) bg = video_16to32[virge->hwc_bg_col & 0xffff]; break; } -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; case 24: case 32: @@ -4360,9 +4337,7 @@ s3_virge_init(const device_t *info) case S3_VIRGE_GX: virge->virge_rev = 0x01; -#ifdef FALLTHROUGH_ANNOTATION - [[fallthrough]]; -#endif + fallthrough; default: virge->fifo_slots_num = 8; @@ -4421,7 +4396,10 @@ s3_virge_init(const device_t *info) virge->svga.crtc[0x37] = 1 | (7 << 5); virge->svga.crtc[0x53] = 8; - virge->card = pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); + if (bios_fn == NULL) + pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge, &virge->pci_slot); + else + pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_NORMAL, s3_virge_pci_read, s3_virge_pci_write, virge, &virge->pci_slot); virge->i2c = i2c_gpio_init("ddc_s3_virge"); virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/vid_sc1148x_ramdac.c index ee75d192d..24ca4aeec 100644 --- a/src/video/vid_sc1148x_ramdac.c +++ b/src/video/vid_sc1148x_ramdac.c @@ -28,8 +28,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> -typedef struct -{ +typedef struct sc1148x_ramdac_t { int type; int state; int rs2; @@ -37,9 +36,9 @@ typedef struct } sc1148x_ramdac_t; void -sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; + sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) priv; uint8_t rs = (addr & 0x03) | ((!!rs2) << 2); int oldbpp = 0; @@ -72,6 +71,9 @@ sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) } else if (val == 0x00) svga->bpp = 8; break; + + default: + break; } if (oldbpp != svga->bpp) svga_recalctimings(svga); @@ -90,9 +92,9 @@ sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) } uint8_t -sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +sc1148x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; + sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) priv; uint8_t ret = 0xff; uint8_t rs = (addr & 0x03) | ((!!rs2) << 2); diff --git a/src/video/vid_sc1502x_ramdac.c b/src/video/vid_sc1502x_ramdac.c index 3a3b3a863..babc2fc4b 100644 --- a/src/video/vid_sc1502x_ramdac.c +++ b/src/video/vid_sc1502x_ramdac.c @@ -29,17 +29,17 @@ #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/plat_unused.h> -typedef struct -{ +typedef struct sc1502x_ramdac_t { int state; uint8_t ctrl; } sc1502x_ramdac_t; void -sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) { - sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; int oldbpp = 0; switch (addr) { @@ -63,6 +63,9 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) case 0x20: svga->bpp = 24; break; + + default: + break; } break; case 4: @@ -81,13 +84,17 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) case 0x20: svga->bpp = 24; break; + + default: + break; } - break; } else { svga->bpp = 16; - break; } break; + + default: + break; } if (oldbpp != svga->bpp) svga_recalctimings(svga); @@ -100,6 +107,9 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) case 0x3C9: ramdac->state = 0; break; + + default: + break; } svga_out(addr, val, svga); @@ -125,13 +135,16 @@ sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga) case 0x3C9: ramdac->state = 0; break; + + default: + break; } return temp; } static void * -sc1502x_ramdac_init(const device_t *info) +sc1502x_ramdac_init(UNUSED(const device_t *info)) { sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) malloc(sizeof(sc1502x_ramdac_t)); memset(ramdac, 0, sizeof(sc1502x_ramdac_t)); diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index d68af2bfa..83796506e 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -44,10 +44,13 @@ enum { typedef struct sdac_ramdac_t { uint16_t regs[256]; - int magic_count, - windex, rindex, - reg_ff, rs2; - uint8_t type, command; + int magic_count; + int windex; + int rindex; + int reg_ff; + int rs2; + uint8_t type; + uint8_t command; } sdac_ramdac_t; static void @@ -59,8 +62,8 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) case ICS_5300: case ICS_5301: switch (val >> 5) { - case 0x00: default: + case 0x00: svga->bpp = 8; break; case 0x01: @@ -82,9 +85,9 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) case ICS_5341: case ICS_5342: switch (val >> 4) { + default: case 0x00: case 0x01: /* This is actually 8bpp with two pixels read at a time. */ - default: svga->bpp = 8; break; case 0x02: @@ -108,6 +111,9 @@ sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) break; } break; + + default: + break; } svga_recalctimings(svga); @@ -144,9 +150,9 @@ sdac_reg_read(sdac_ramdac_t *ramdac, int reg) } void -sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -184,13 +190,16 @@ sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) ramdac->rindex = val; ramdac->reg_ff = 0; break; + + default: + break; } } uint8_t -sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); @@ -237,6 +246,9 @@ sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) case 0x07: temp = ramdac->rindex; break; + + default: + break; } return temp; @@ -245,11 +257,11 @@ sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) float sdac_getclock(int clock, void *priv) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; - float t; - int m; - int n1; - int n2; + const sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; + float t; + int m; + int n1; + int n2; if (ramdac->regs[0xe] & (1 << 5)) clock = ramdac->regs[0xe] & 7; diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 97383bc65..a91716657 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -109,8 +109,8 @@ * 0x2DC: On write: Resets the NMI. * 0x2DD: Memory paging. The memory from 0xC1800 to 0xC1FFF can be either: * - * > ROM: A 128 character 8x16 font for use in graphics modes - * > RAM: Use by the video BIOS to hold its settings. + * > ROM: A 128 character 8x16 font for use in graphics modes + * > RAM: Use by the video BIOS to hold its settings. * * Reading port 2DD switches to ROM. Bit 7 of the value read gives the * previous paging state: bit 7 set if ROM was paged, clear if RAM was diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 0e83c034a..9e23a9871 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -110,11 +110,52 @@ svga_set_override(svga_t *svga, int val) void svga_out(uint16_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) priv; - uint8_t o; - uint8_t index; + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = &svga->dev8514; + xga_t *xga = &svga->xga; + uint8_t o; + uint8_t index; switch (addr) { + case 0x2ea: + dev->dac_mask = val; + break; + case 0x2eb: + case 0x2ec: + dev->dac_pos = 0; + dev->dac_status = addr & 0x03; + dev->dac_addr = (val + (addr & 0x01)) & 0xff; + break; + case 0x2ed: + svga->fullchange = svga->monitor->mon_changeframecount; + switch (dev->dac_pos) { + case 0: + dev->dac_r = val; + dev->dac_pos++; + break; + case 1: + dev->dac_g = val; + dev->dac_pos++; + break; + case 2: + index = dev->dac_addr & 0xff; + dev->dac_b = val; + svga->vgapal[index].r = dev->dac_r; + svga->vgapal[index].g = dev->dac_g; + svga->vgapal[index].b = dev->dac_b; + if (svga->ramdac_type == RAMDAC_8BIT) + dev->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); + else + dev->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]); + dev->dac_pos = 0; + dev->dac_addr = (dev->dac_addr + 1) & 0xff; + break; + + default: + break; + } + break; + case 0x3c0: case 0x3c1: if (!svga->attrff) { @@ -167,10 +208,12 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga_recalctimings(svga); break; case 0x3c3: - if (xga_enabled) { - svga->xga.on = (val & 0x01) ? 0 : 1; - vga_on = !svga->xga.on; - } + if (xga_enabled) + xga->on = (val & 0x01) ? 0 : 1; + if (ibm8514_enabled) + ibm8514_on = (val & 0x01) ? 0 : 1; + + vga_on = val & 0x01; break; case 0x3c4: svga->seqaddr = val; @@ -210,19 +253,15 @@ svga_out(uint16_t addr, uint8_t val, void *priv) break; } break; - case 0x2ea: case 0x3c6: svga->dac_mask = val; break; - case 0x2eb: - case 0x2ec: case 0x3c7: case 0x3c8: svga->dac_pos = 0; svga->dac_status = addr & 0x03; svga->dac_addr = (val + (addr & 0x01)) & 255; break; - case 0x2ed: case 0x3c9: if (svga->adv_flags & FLAG_RAMDAC_SHIFT) val <<= 2; @@ -238,9 +277,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv) break; case 2: index = svga->dac_addr & 255; + svga->dac_b = val; svga->vgapal[index].r = svga->dac_r; svga->vgapal[index].g = svga->dac_g; - svga->vgapal[index].b = val; + svga->vgapal[index].b = svga->dac_b; if (svga->ramdac_type == RAMDAC_8BIT) svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); else @@ -316,11 +356,52 @@ svga_out(uint16_t addr, uint8_t val, void *priv) uint8_t svga_in(uint16_t addr, void *priv) { - svga_t *svga = (svga_t *) priv; - uint8_t index; - uint8_t ret = 0xff; + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = &svga->dev8514; + uint8_t index; + uint8_t ret = 0xff; switch (addr) { + case 0x2ea: + ret = dev->dac_mask; + break; + case 0x2eb: + ret = dev->dac_status; + break; + case 0x2ec: + ret = dev->dac_addr; + break; + case 0x2ed: + index = (dev->dac_addr - 1) & 0xff; + switch (dev->dac_pos) { + case 0: + dev->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + ret = svga->vgapal[index].r; + else + ret = svga->vgapal[index].r & 0x3f; + break; + case 1: + dev->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + ret = svga->vgapal[index].g; + else + ret = svga->vgapal[index].g & 0x3f; + break; + case 2: + dev->dac_pos = 0; + dev->dac_addr = (dev->dac_addr + 1) & 0xff; + if (svga->ramdac_type == RAMDAC_8BIT) + ret = svga->vgapal[index].b; + else + ret = svga->vgapal[index].b & 0x3f; + break; + + default: + break; + } + break; + case 0x3c0: ret = svga->attraddr | svga->attr_palette_enable; break; @@ -333,25 +414,24 @@ svga_in(uint16_t addr, void *priv) else ret = 0x10; break; + case 0x3c3: + ret = vga_on; + break; case 0x3c4: ret = svga->seqaddr; break; case 0x3c5: ret = svga->seqregs[svga->seqaddr & 0x0f]; break; - case 0x2ea: case 0x3c6: ret = svga->dac_mask; break; - case 0x2eb: case 0x3c7: ret = svga->dac_status; break; - case 0x2ec: case 0x3c8: ret = svga->dac_addr; break; - case 0x2ed: case 0x3c9: index = (svga->dac_addr - 1) & 255; switch (svga->dac_pos) { @@ -432,16 +512,27 @@ svga_in(uint16_t addr, void *priv) void svga_set_ramdac_type(svga_t *svga, int type) { + ibm8514_t *dev = &svga->dev8514; + if (svga->ramdac_type != type) { svga->ramdac_type = type; for (int c = 0; c < 256; c++) { - if (svga->ramdac_type == RAMDAC_8BIT) - svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); - else - svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, - (svga->vgapal[c].g & 0x3f) * 4, - (svga->vgapal[c].b & 0x3f) * 4); + if (ibm8514_on) { + if (svga->ramdac_type == RAMDAC_8BIT) + dev->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); + else + dev->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, + (svga->vgapal[c].g & 0x3f) * 4, + (svga->vgapal[c].b & 0x3f) * 4); + } else { + if (svga->ramdac_type == RAMDAC_8BIT) + svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); + else + svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, + (svga->vgapal[c].g & 0x3f) * 4, + (svga->vgapal[c].b & 0x3f) * 4); + } } } } @@ -449,10 +540,11 @@ svga_set_ramdac_type(svga_t *svga, int type) void svga_recalctimings(svga_t *svga) { - double crtcconst; - double _dispontime; - double _dispofftime; - double disptime; + const ibm8514_t *dev = &svga->dev8514; + double crtcconst; + double _dispontime; + double _dispofftime; + double disptime; svga->vtotal = svga->crtc[6]; svga->dispend = svga->crtc[0x12]; @@ -495,7 +587,7 @@ svga_recalctimings(svga_t *svga) svga->htotal = svga->crtc[0]; /* +5 has been verified by Sergi to be correct - +6 must have been an off by one error. */ - svga->htotal += 5; /*+6 is required for Tyrian*/ + svga->htotal += 5; /*+5 is required for Tyrian*/ svga->rowoffset = svga->crtc[0x13]; @@ -612,23 +704,18 @@ svga_recalctimings(svga_t *svga) } else svga->monitor->mon_overscan_x = 16; - if (vga_on) { - if (svga->recalctimings_ex) { - svga->recalctimings_ex(svga); - } - } else { - if (ibm8514_enabled) { - if (svga->dev8514.local) { - if (svga->recalctimings_ex) { - svga->recalctimings_ex(svga); - } - } else - ibm8514_recalctimings(svga); - } - if (xga_enabled) - xga_recalctimings(svga); + if (svga->recalctimings_ex) { + svga->recalctimings_ex(svga); } + if (ibm8514_enabled) { + if (!dev->local) + ibm8514_recalctimings(svga); + } + + if (xga_enabled) + xga_recalctimings(svga); + if (svga->hdisp >= 2048) svga->monitor->mon_overscan_x = 0; @@ -640,9 +727,9 @@ svga_recalctimings(svga_t *svga) crtcconst = svga->clock * svga->char_width; - if (ibm8514_on && !svga->dev8514.local) { - disptime = svga->dev8514.h_total; - _dispontime = svga->dev8514.h_disp; + if (ibm8514_on) { + disptime = dev->h_total; + _dispontime = dev->h_disp; } else { disptime = svga->htotal; _dispontime = svga->hdisp_time; @@ -727,21 +814,19 @@ svga_poll(void *priv) { svga_t *svga = (svga_t *) priv; ibm8514_t *dev = &svga->dev8514; + xga_t *xga = &svga->xga; uint32_t x; uint32_t blink_delay; int wx; int wy; int ret; int old_ma; - int linecountff = 0; - if (!vga_on && ibm8514_enabled && ibm8514_on) { - if (!dev->local) { - ibm8514_poll(dev, svga); - return; - } - } else if (!vga_on && xga_enabled && svga->xga.on) { - xga_poll(&svga->xga, svga); + if (ibm8514_enabled && ibm8514_on) { + ibm8514_poll(dev, svga); + return; + } else if (xga_enabled && xga->on) { + xga_poll(xga, svga); return; } @@ -835,13 +920,7 @@ svga_poll(void *priv) if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount)) svga->con = 0; if (svga->dispon) { - /*Real IBM 8514/A or compatibility mode doesn't have linedbl, so skip those.*/ - if (dev->local && ibm8514_on) { - svga->linedbl = 0; - svga->linecountff = 0; - linecountff = 1; - } - if (svga->linedbl && !svga->linecountff && !linecountff) { + if (svga->linedbl && !svga->linecountff) { svga->linecountff = 1; svga->ma = svga->maback; } else if (svga->sc == svga->rowcount) { @@ -949,17 +1028,11 @@ svga_poll(void *priv) svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2; svga->vslines = 0; - if ((dev->local && vga_on) || !dev->local) { - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); - else - svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); - } else if (dev->local && ibm8514_on) { - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); - else - svga->ma = svga->maback = svga->ma_latch; - } + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + else + svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); + svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; svga->ma = (svga->ma << 2); svga->maback = (svga->maback << 2); @@ -974,24 +1047,22 @@ svga_poll(void *priv) svga->dispon = 1; svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; - if (!ibm8514_on) { - svga->scrollcache = (svga->attrregs[0x13] & 0x0f); - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 1) - svga->scrollcache &= 0x07; - else { - svga->scrollcache++; - if (svga->scrollcache > 8) - svga->scrollcache = 0; - } - } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) + svga->scrollcache = (svga->attrregs[0x13] & 0x0f); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 1) svga->scrollcache &= 0x07; - else - svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + else { + svga->scrollcache++; + if (svga->scrollcache > 8) + svga->scrollcache = 0; + } + } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) + svga->scrollcache &= 0x07; + else + svga->scrollcache = (svga->scrollcache & 0x06) >> 1; - if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) - svga->scrollcache <<= 1; - } + if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) + svga->scrollcache <<= 1; svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache; @@ -1151,12 +1222,12 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write) static __inline void svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) { - svga_t *svga = (svga_t *) priv; - + svga_t *svga = (svga_t *) priv; + xga_t *xga = &svga->xga; int writemask2 = svga->writemask; int reset_wm = 0; latch_t vall; - uint8_t wm = svga->writemask; + uint8_t wm = svga->writemask; uint8_t count; uint8_t i; @@ -1167,23 +1238,23 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) if (!linear) { if (xga_enabled) { - if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) { + if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { if (val == 0xa5) { /*Memory size test of XGA*/ - svga->xga.test = val; - svga->xga.a5_test = 1; + xga->test = val; + xga->a5_test = 1; return; } else if (val == 0x5a) { - svga->xga.test = val; + xga->test = val; return; } else if ((val == 0x12) || (val == 0x34)) { - addr += svga->xga.write_bank; - svga->xga.vram[addr & svga->xga.vram_mask] = val; - svga->xga.linear_endian_reverse = 1; + addr += xga->write_bank; + xga->vram[addr & xga->vram_mask] = val; + xga->linear_endian_reverse = 1; return; } } else { - svga->xga.on = 0; - vga_on = !svga->xga.on; + xga->on = 0; + vga_on = 1; } } addr = svga_decode_addr(svga, addr, 1); @@ -1368,6 +1439,7 @@ static __inline uint8_t svga_read_common(uint32_t addr, uint8_t linear, void *priv) { svga_t *svga = (svga_t *) priv; + xga_t *xga = &svga->xga; uint32_t latch_addr = 0; int readplane = svga->readplane; uint8_t count; @@ -1381,22 +1453,22 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv) if (!linear) { if (xga_enabled) { - if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) { - if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/ - svga->xga.on = 1; - vga_on = !svga->xga.on; - return svga->xga.test; - } else if (svga->xga.test == 0x5a) { - svga->xga.on = 1; - vga_on = !svga->xga.on; - return svga->xga.test; + if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { + if (xga->test == 0xa5) { /*Memory size test of XGA*/ + xga->on = 1; + vga_on = 0; + return xga->test; + } else if (xga->test == 0x5a) { + xga->on = 1; + vga_on = 0; + return xga->test; } else if ((addr == 0xa0000) || (addr == 0xa0010)) { - addr += svga->xga.read_bank; - return svga->xga.vram[addr & svga->xga.vram_mask]; + addr += xga->read_bank; + return xga->vram[addr & xga->vram_mask]; } } else { - svga->xga.on = 0; - vga_on = !svga->xga.on; + xga->on = 0; + vga_on = 1; } } addr = svga_decode_addr(svga, addr, 0); @@ -1617,7 +1689,7 @@ svga_writeb_linear(uint32_t addr, uint8_t val, void *priv) return; addr &= svga->vram_mask; svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - *&svga->vram[addr] = val; + svga->vram[addr] = val; } void @@ -1752,7 +1824,7 @@ svga_readb_linear(uint32_t addr, void *priv) if (addr >= svga->vram_max) return 0xff; - return *&svga->vram[addr & svga->vram_mask]; + return svga->vram[addr & svga->vram_mask]; } uint16_t diff --git a/src/video/vid_table.c b/src/video/vid_table.c index eb999eb3f..7d25f8625 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -38,7 +38,7 @@ #include <86box/vid_mda.h> #include <86box/vid_xga_device.h> -typedef struct { +typedef struct video_card_t { const device_t *device; int flags; } VIDEO_CARD; @@ -81,7 +81,7 @@ video_cards[] = { { &vid_internal_device }, { &atiega_device }, { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, - { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, + { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_isa_device }, { &ati28800k_device }, { &ati18800_vga88_device }, @@ -154,11 +154,12 @@ video_cards[] = { { &vga_device }, { &v7_vga_1024i_device }, { &wy700_device }, + { &mach32_mca_device, VIDEO_FLAG_TYPE_8514 }, { &gd5426_mca_device }, { &gd5428_mca_device }, { &et4000_mca_device }, { &radius_svga_multiview_mca_device }, - { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, + { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_pci_device }, { &mach64vt2_device }, { &et4000w32p_videomagic_revb_pci_device }, @@ -216,7 +217,7 @@ video_cards[] = { { &voodoo_3_1000_device }, { &voodoo_3_2000_device }, { &voodoo_3_3000_device }, - { &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 }, + { &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_vlb_device }, { &et4000w32i_vlb_device }, { &et4000w32p_videomagic_revb_vlb_device }, @@ -343,8 +344,18 @@ video_reset(int card) monitor_index_global = 0; loadfont("roms/video/mda/mda.rom", 0); + if ((card != VID_NONE) + && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) + && (gfxcard[1] != 0) + && device_is_valid(video_card_getdevice(gfxcard[1]), machine)) { + video_monitor_init(1); + monitor_index_global = 1; + device_add(video_cards[gfxcard[1]].device); + monitor_index_global = 0; + } + /* Do not initialize internal cards here. */ - if (!(card == VID_NONE) && !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { + if ((card != VID_NONE) && (card != VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].device->name); video_prepare(); @@ -353,21 +364,41 @@ video_reset(int card) device_add(video_cards[card].device); } - if (!(card == VID_NONE) - && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) - && gfxcard[1] != 0 - && device_is_valid(video_card_getdevice(gfxcard[1]), machine)) { - video_monitor_init(1); - monitor_index_global = 1; - device_add(video_cards[gfxcard[1]].device); - monitor_index_global = 0; + was_reset = 1; +} + +void +video_post_reset(void) +{ + if (gfxcard[0] == VID_INTERNAL) + ibm8514_has_vga = (video_get_type_monitor(0) == VIDEO_FLAG_TYPE_8514); + else if (gfxcard[0] != VID_NONE) + ibm8514_has_vga = (video_card_get_flags(gfxcard[0]) == VIDEO_FLAG_TYPE_8514); + else + ibm8514_has_vga = 0; + + if (ibm8514_has_vga) + ibm8514_enabled = 1; + + if (ibm8514_enabled) { + if (!ibm8514_has_vga) + ibm8514_device_add(); } + if (xga_enabled) + xga_device_add(); + + /* Reset the graphics card (or do nothing if it was already done + by the machine's init function). */ + video_reset(gfxcard[0]); +} + +void +video_voodoo_init(void) +{ /* Enable the Voodoo if configured. */ if (voodoo_enabled) device_add(&voodoo_device); - - was_reset = 1; } int diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index f659f90fe..de900b27a 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Trident TGUI9400CXi and TGUI9440 emulation. + * Trident TGUI9400CXi and TGUI9440/96x0 emulation. * * TGUI9400CXi has extended write modes, controlled by extended * GDC registers : @@ -103,14 +103,17 @@ typedef struct tgui_t { svga_t svga; int pci; - int type, card; + uint8_t pci_slot; + uint8_t irq_state; + + int type; uint8_t int_line; uint8_t pci_regs[256]; struct { - int16_t src_x, src_y; + int32_t src_x, src_y; int16_t src_x_clip, src_y_clip; int16_t dst_x, dst_y; int16_t dst_y_clip, dst_x_clip; @@ -126,7 +129,8 @@ typedef struct tgui_t { int offset; uint16_t ger22; - int16_t err, top, left, bottom, right; + int32_t err; + int16_t top, left, bottom, right; int x, y, dx, dy; uint32_t src, dst, src_old, dst_old; int pat_x, pat_y; @@ -219,11 +223,10 @@ tgui_update_irqs(tgui_t *tgui) if (!tgui->pci) return; - if (!(tgui->oldctrl1 & 0x40)) { - pci_set_irq(tgui->card, PCI_INTA); - } else { - pci_clear_irq(tgui->card, PCI_INTA); - } + if (!(tgui->oldctrl1 & 0x40)) + pci_set_irq(tgui->pci_slot, PCI_INTA, &tgui->irq_state); + else + pci_clear_irq(tgui->pci_slot, PCI_INTA, &tgui->irq_state); } static void @@ -496,7 +499,7 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) svga->fullchange = 3; svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { - svga->fullchange = changeframecount; + svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); } } @@ -625,7 +628,6 @@ void tgui_recalctimings(svga_t *svga) { tgui_t *tgui = (tgui_t *) svga->priv; - uint8_t ger22lower = tgui->accel.ger22 & 0xff; uint8_t ger22upper = (tgui->accel.ger22 >> 8); if (!svga->rowoffset) @@ -634,13 +636,8 @@ tgui_recalctimings(svga_t *svga) if (svga->crtc[0x29] & 0x10) svga->rowoffset |= 0x100; - if ((tgui->type >= TGUI_9440) && (svga->bpp >= 24)) { - if ((tgui->accel.bpp == 0) && (ger22lower != 14) && (svga->bpp == 24)) - svga->hdisp = (svga->crtc[1] + 1) * 8; - if ((tgui->accel.bpp == 3) && (ger22lower == 14) && (svga->bpp == 32) && (tgui->type == TGUI_9440)) - svga->rowoffset <<= 1; - // pclog("Accelbpp = %d, ger22lower = %02x, ger22upper = %02x, bpp = %d, rowoffset = %d.\n", tgui->accel.bpp, ger22lower, ger22upper, svga->bpp, svga->rowoffset); - } + if ((tgui->type >= TGUI_9440) && (svga->bpp >= 24)) + svga->hdisp = (svga->crtc[1] + 1) * 8; if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000; @@ -746,14 +743,14 @@ tgui_recalctimings(svga_t *svga) else if ((svga->dispend == 600) && (svga->hdisp == 800) && svga->interlace) svga->hdisp = 1600; + if (ger22upper & 0x80) { + svga->htotal <<= 1; + svga->hdisp <<= 1; + svga->hdisp_time <<= 1; + } switch (svga->hdisp) { case 640: - if (ger22upper & 0x01) - svga->rowoffset = 0x50; - break; - case 1600: - if (svga->rowoffset != 0x100) - svga->rowoffset = 0x100; + svga->rowoffset = 80; break; } } @@ -776,9 +773,8 @@ tgui_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; if (tgui->type >= TGUI_9660) { - if (svga->hdisp == 1024) { + if (svga->hdisp == 1024) svga->rowoffset <<= 1; - } } break; } @@ -1075,15 +1071,20 @@ tgui_ext_linear_read(uint32_t addr, void *priv) if (addr >= svga->vram_max) return 0xff; - addr &= ~0xf; + addr &= svga->vram_mask; + addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; addr = dword_remap(svga, addr); - for (uint8_t c = 0; c < 16; c++) { - tgui->copy_latch[c] = svga->vram[addr + c]; - addr += ((c & 3) == 3) ? 13 : 1; + if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { + for (int c = 0; c < 16; c++) { + tgui->copy_latch[c] = svga->vram[addr]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + return svga->vram[addr]; } - return svga->vram[addr & svga->vram_mask]; + return svga_read_linear(addr, svga); } static uint8_t @@ -1102,6 +1103,7 @@ tgui_ext_linear_write(uint32_t addr, uint8_t val, void *priv) svga_t *svga = (svga_t *) priv; tgui_t *tgui = (tgui_t *) svga->priv; int c; + int bpp = (tgui->ext_gdc_regs[0] & EXT_CTRL_16BIT); uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; uint8_t mask = tgui->ext_gdc_regs[7]; @@ -1112,62 +1114,53 @@ tgui_ext_linear_write(uint32_t addr, uint8_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7; + addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; addr = dword_remap(svga, addr); - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - switch (tgui->ext_gdc_regs[0] & 0xf) { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 7; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr += (c == 4) ? 13 : 1; + if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { + for (c = 0; c < 16; c++) { + svga->vram[addr] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + addr &= svga->vram_mask; + } + } else if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT)) { + if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_TRANSPARENT) { + if (bpp) { + for (c = 7; c >= 0; c--) { + if ((val & mask) & (1 << c)) + svga->vram[addr] = fg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else { + for (c = 7; c >= 0; c--) { + if ((val & mask) & (1 << c)) + svga->vram[addr] = tgui->ext_gdc_regs[4]; + addr += (c == 4) ? 13 : 1; + addr &= svga->vram_mask; + } } - break; - - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 7; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c == 4) ? 13 : 1; + } else { + if (bpp) { + for (c = 7; c >= 0; c--) { + if (mask & (1 << c)) + svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else { + for (c = 7; c >= 0; c--) { + if (mask & (1 << c)) + svga->vram[addr] = (val & (1 << c)) ? tgui->ext_gdc_regs[4] : tgui->ext_gdc_regs[1]; + addr += (c == 4) ? 13 : 1; + addr &= svga->vram_mask; + } } - break; - - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 7; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *) &svga->vram[addr] = fg[0]; - addr += (c == 4) ? 13 : 1; - } - break; - - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 7; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *) &svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c == 4) ? 13 : 1; - } - break; - - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - for (c = 0; c < 16; c++) { - *(uint8_t *) &svga->vram[addr] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; - } - break; - } + } + } else + svga_write_linear(addr, val, svga); } static void @@ -1176,6 +1169,7 @@ tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *priv) svga_t *svga = (svga_t *) priv; tgui_t *tgui = (tgui_t *) svga->priv; int c; + int bpp = (tgui->ext_gdc_regs[0] & EXT_CTRL_16BIT); uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; @@ -1186,70 +1180,81 @@ tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - addr &= ~0xf; + addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; addr = dword_remap(svga, addr); - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; val = (val >> 8) | (val << 8); - switch (tgui->ext_gdc_regs[0] & 0xf) { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 15; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr += (c & 3) ? 1 : 13; - } - break; + if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { + for (c = 0; c < 16; c++) { + svga->vram[addr] = tgui->copy_latch[c]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT)) { + if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_TRANSPARENT) { + if (bpp) { + for (c = 15; c >= 0; c--) { + if ((val & mask) & (1 << c)) + svga->vram[addr] = fg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else { + for (c = 15; c >= 0; c--) { + if ((val & mask) & (1 << c)) + svga->vram[addr] = tgui->ext_gdc_regs[4]; - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 15; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } } - break; + } else { + if (bpp) { + for (c = 15; c >= 0; c--) { + if (mask & (1 << c)) + svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } + } else { + for (c = 15; c >= 0; c--) { + if (mask & (1 << c)) + svga->vram[addr] = (val & (1 << c)) ? tgui->ext_gdc_regs[4] : tgui->ext_gdc_regs[1]; - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 15; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *) &svga->vram[addr] = fg[0]; - addr += (c & 3) ? 1 : 13; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } } - break; - - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 15; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *) &svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; - } - break; - - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - for (c = 0; c < 16; c++) { - *(uint8_t *) &svga->vram[addr + c] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; - } - break; - } + } + } else + svga_writew_linear(addr, val, svga); } static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *priv) { - tgui_ext_linear_writew(addr, val, priv); + svga_t *svga = (svga_t *) priv; + tgui_t *tgui = (tgui_t *) svga->priv; + cycles -= video_timing_write_l; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; + + addr = dword_remap(svga, addr); + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + + if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT | EXT_CTRL_LATCH_COPY)) { + tgui_ext_linear_writew(addr, val & 0xffff, priv); + tgui_ext_linear_writew(addr + 2, val >> 16, priv); + } else { + svga_writel_linear(addr, val, svga); + } } static void @@ -1257,7 +1262,7 @@ tgui_ext_write(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->write_bank; tgui_ext_linear_write(addr, val, svga); } @@ -1266,7 +1271,7 @@ tgui_ext_writew(uint32_t addr, uint16_t val, void *priv) { svga_t *svga = (svga_t *) priv; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->write_bank; tgui_ext_linear_writew(addr, val, svga); } @@ -1275,7 +1280,7 @@ tgui_ext_writel(uint32_t addr, uint32_t val, void *priv) { svga_t *svga = (svga_t *) priv; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->write_bank; tgui_ext_linear_writel(addr, val, svga); } @@ -1325,13 +1330,13 @@ enum { #define WRITE(addr, dat) \ if (tgui->accel.bpp == 0) { \ svga->vram[(addr) &tgui->vram_mask] = dat; \ - svga->changedvram[((addr) & (tgui->vram_mask)) >> 12] = changeframecount; \ + svga->changedvram[((addr) & (tgui->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; \ } else if (tgui->accel.bpp == 1) { \ vram_w[(addr) & (tgui->vram_mask >> 1)] = dat; \ - svga->changedvram[((addr) & (tgui->vram_mask >> 1)) >> 11] = changeframecount; \ + svga->changedvram[((addr) & (tgui->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ } else { \ vram_l[(addr) & (tgui->vram_mask >> 2)] = dat; \ - svga->changedvram[((addr) & (tgui->vram_mask >> 2)) >> 10] = changeframecount; \ + svga->changedvram[((addr) & (tgui->vram_mask >> 2)) >> 10] = svga->monitor->mon_changeframecount; \ } static void @@ -1361,7 +1366,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) trans_col &= 0xffff; } - if (count != -1 && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) { + if ((count != -1) && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) { count -= (tgui->accel.flags >> 24) & 7; cpu_dat <<= (tgui->accel.flags >> 24) & 7; } @@ -1409,38 +1414,6 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } - switch (svga->hdisp) { - case 640: - case 1024: - case 1280: - tgui->accel.pitch = svga->hdisp; - break; - case 800: /*Disassembly of the TGUI9440/96x0 drivers shows that 800x600 is treated as 832 in the acceleration pitch (0x340 as horizontal display)*/ - tgui->accel.pitch = svga->hdisp + 32; - break; - case 1600: - tgui->accel.pitch = 2048; - break; - } - - switch (ger22lower) { - case 4: /*8-bit mode for modes up to 1024x768.*/ - case 9: /*15-bit and 16-bit modes.*/ - if (!(ger22upper & 0x01)) { - if (ger22upper == 0x00) - tgui->accel.pitch = 1024; - } - break; - case 8: /*8-bit mode for modes greater than 1024x768 and 24-bit mode for 640x480 (latter is TGUI9440AGi only).*/ - if (!(ger22upper & 0x01)) { - if (ger22upper == 0x00) { - if (svga->bpp == 24) - tgui->accel.pitch = 2048; - } - } - break; - } - // pclog("TGUI accel command = %x, ger22 = %04x, hdisp = %d, dispend = %d, vtotal = %d, rowoffset = %d, svgabpp = %d, interlace = %d, accelbpp = %d, pitch = %d.\n", tgui->accel.command, tgui->accel.ger22, svga->hdisp, svga->dispend, svga->vtotal, svga->rowoffset, svga->bpp, svga->interlace, tgui->accel.bpp, tgui->accel.pitch); switch (tgui->accel.command) { @@ -1998,49 +1971,40 @@ static void tgui_accel_out(uint16_t addr, uint8_t val, void *priv) { tgui_t *tgui = (tgui_t *) priv; + svga_t *svga = &tgui->svga; switch (addr) { case 0x2122: tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; - switch (val & 0xff) { - case 4: + tgui->accel.pitch = 0x200 << ((val >> 2) & 3); + switch (svga->bpp) { case 8: + case 24: tgui->accel.bpp = 0; break; - - case 9: - switch (tgui->svga.bpp) { - case 32: - tgui->accel.bpp = 3; - break; - default: - tgui->accel.bpp = 1; - break; - } + case 15: + case 16: + tgui->accel.bpp = 1; break; - - case 13: - case 14: - switch (tgui->svga.bpp) { - case 15: - case 16: - tgui->accel.bpp = 1; - break; - - case 24: - tgui->accel.bpp = 0; - break; - - case 32: - tgui->accel.bpp = 3; - break; - } + case 32: + tgui->accel.bpp = 3; break; } break; case 0x2123: tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8); + if ((val & 0x80) || (((val & 0xc0) == 0x40))) + tgui->accel.pitch = svga->rowoffset << 3; + else if (tgui->accel.pitch <= 1024) + tgui->accel.pitch = svga->rowoffset << 3; + + if (tgui->accel.bpp == 1) + tgui->accel.pitch >>= 1; + else if (tgui->accel.bpp == 3) + tgui->accel.pitch >>= 2; + + svga_recalctimings(svga); break; case 0x2124: /*Command*/ @@ -2652,45 +2616,35 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *priv) switch (addr & 0xff) { case 0x22: tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; - switch (val & 0xff) { - case 4: + tgui->accel.pitch = 0x200 << ((val >> 2) & 3); + switch (svga->bpp) { case 8: + case 24: tgui->accel.bpp = 0; break; - - case 9: - switch (tgui->svga.bpp) { - case 32: - tgui->accel.bpp = 3; - break; - default: - tgui->accel.bpp = 1; - break; - } + case 15: + case 16: + tgui->accel.bpp = 1; break; - - case 13: - case 14: - switch (tgui->svga.bpp) { - case 15: - case 16: - tgui->accel.bpp = 1; - break; - - case 24: - tgui->accel.bpp = 0; - break; - - case 32: - tgui->accel.bpp = 3; - break; - } + case 32: + tgui->accel.bpp = 3; break; } break; case 0x23: tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8); + if ((val & 0x80) || (((val & 0xc0) == 0x40))) + tgui->accel.pitch = svga->rowoffset << 3; + else if (tgui->accel.pitch <= 1024) + tgui->accel.pitch = svga->rowoffset << 3; + + if (tgui->accel.bpp == 1) + tgui->accel.pitch >>= 1; + else if (tgui->accel.bpp == 3) + tgui->accel.pitch >>= 2; + + svga_recalctimings(svga); break; case 0x24: /*Command*/ @@ -3512,13 +3466,16 @@ tgui_init(const device_t *info) mem_mapping_disable(&tgui->accel_mapping); mem_mapping_disable(&tgui->mmio_mapping); + if (tgui->vram_size == (2 << 20)) + svga->crtc[0x21] |= 0x10; + tgui_set_io(tgui); if (tgui->pci && (tgui->type >= TGUI_9440)) { if (tgui->has_bios) - tgui->card = pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); + pci_add_card(PCI_ADD_NORMAL, tgui_pci_read, tgui_pci_write, tgui, &tgui->pci_slot); else - tgui->card = pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui); + pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui, &tgui->pci_slot); } tgui->pci_regs[PCI_REG_COMMAND] = 7; @@ -3585,7 +3542,7 @@ tgui_force_redraw(void *priv) { tgui_t *tgui = (tgui_t *) priv; - tgui->svga.fullchange = changeframecount; + tgui->svga.fullchange = tgui->svga.monitor->mon_changeframecount; } // clang-format off diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c index 32c37ca8b..fa083b76b 100644 --- a/src/video/vid_ti_cf62011.c +++ b/src/video/vid_ti_cf62011.c @@ -91,7 +91,7 @@ vid_out(uint16_t addr, uint8_t val, void *priv) #if 0 if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) && - !(svga->miscout & 1)) addr ^= 0x60; + !(svga->miscout & 1)) addr ^= 0x60; #endif switch (addr) { @@ -151,7 +151,7 @@ vid_in(uint16_t addr, void *priv) #if 0 if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) && - !(svga->miscout & 1)) addr ^= 0x60; + !(svga->miscout & 1)) addr ^= 0x60; #endif switch (addr) { diff --git a/src/video/vid_tkd8001_ramdac.c b/src/video/vid_tkd8001_ramdac.c index 66c2ca922..86a1e4dd0 100644 --- a/src/video/vid_tkd8001_ramdac.c +++ b/src/video/vid_tkd8001_ramdac.c @@ -27,6 +27,7 @@ #include <86box/mem.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/plat_unused.h> typedef struct tkd8001_ramdac_t { int state; @@ -34,9 +35,9 @@ typedef struct tkd8001_ramdac_t { } tkd8001_ramdac_t; void -tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) { - tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p; + tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) priv; switch (addr) { case 0x3C6: @@ -59,6 +60,9 @@ tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) case 7: svga->bpp = 16; break; + + default: + break; } return; } @@ -68,6 +72,9 @@ tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) case 0x3C9: ramdac->state = 0; break; + + default: + break; } svga_out(addr, val, svga); @@ -89,12 +96,15 @@ tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga) case 0x3C9: ramdac->state = 0; break; + + default: + break; } return svga_in(addr, svga); } static void * -tkd8001_ramdac_init(const device_t *info) +tkd8001_ramdac_init(UNUSED(const device_t *info)) { tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) malloc(sizeof(tkd8001_ramdac_t)); memset(ramdac, 0, sizeof(tkd8001_ramdac_t)); diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index da75543ca..15215c45d 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -27,15 +27,17 @@ #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/plat_fallthrough.h> -typedef struct -{ +typedef struct tvp3026_ramdac_t { PALETTE extpal; uint32_t extpallook[256]; uint8_t cursor64_data[1024]; - int hwc_y, hwc_x; + int hwc_y; + int hwc_x; uint8_t ind_idx; - uint8_t dcc, dc_init; + uint8_t dcc; + uint8_t dc_init; uint8_t ccr; uint8_t true_color; uint8_t latch_cntl; @@ -48,9 +50,10 @@ typedef struct uint8_t mode; uint8_t pll_addr; uint8_t clock_sel; - struct - { - uint8_t m, n, p; + struct { + uint8_t m; + uint8_t n; + uint8_t p; } pix, mem, loop; } tvp3026_ramdac_t; @@ -83,15 +86,18 @@ tvp3026_set_bpp(tvp3026_ramdac_t *ramdac, svga_t *svga) case 0x0f: svga->bpp = 24; break; + + default: + break; } } svga_recalctimings(svga); } void -tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) +tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; uint32_t o32; uint8_t *cd; uint16_t index; @@ -103,6 +109,7 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t switch (rs) { case 0x00: /* Palette Write Index Register (RS value = 0000) */ ramdac->ind_idx = val; + fallthrough; case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ case 0x03: case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ @@ -147,6 +154,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t svga->dac_addr = (svga->dac_addr + 1) & 0xff; svga->dac_pos = 0; break; + + default: + break; } break; case 0x09: /* Direct Cursor Control (RS value = 1001) */ @@ -215,6 +225,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t case 2: ramdac->pix.p = val; break; + + default: + break; } ramdac->pll_addr = ((ramdac->pll_addr + 1) & 3) | (ramdac->pll_addr & 0xfc); break; @@ -229,6 +242,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t case 2: ramdac->mem.p = val; break; + + default: + break; } ramdac->pll_addr = ((ramdac->pll_addr + 4) & 0x0c) | (ramdac->pll_addr & 0xf3); break; @@ -243,12 +259,18 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t case 2: ramdac->loop.p = val; break; + + default: + break; } ramdac->pll_addr = ((ramdac->pll_addr + 0x10) & 0x30) | (ramdac->pll_addr & 0xcf); break; case 0x39: /* MCLK/Loop Clock Control */ ramdac->mclk = val; break; + + default: + break; } break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ @@ -273,17 +295,20 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; break; + + default: + break; } return; } uint8_t -tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) +tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; uint8_t temp = 0xff; - uint8_t *cd; + const uint8_t *cd; uint16_t index; uint8_t rs = (addr & 0x03); uint16_t da_mask = 0x03ff; @@ -327,6 +352,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) else temp = ramdac->extpal[index].b & 0x3f; break; + + default: + break; } break; case 0x09: /* Direct Cursor Control (RS value = 1001) */ @@ -378,6 +406,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 3: temp = 0x40; /*PLL locked to frequency*/ break; + + default: + break; } break; case 0x2e: /* Memory Clock PLL Data */ @@ -394,6 +425,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 3: temp = 0x40; /*PLL locked to frequency*/ break; + + default: + break; } break; case 0x2f: /* Loop Clock PLL Data */ @@ -407,6 +441,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 2: temp = ramdac->loop.p; break; + + default: + break; } break; case 0x39: /* MCLK/Loop Clock Control */ @@ -415,6 +452,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 0x3f: /* ID */ temp = 0x26; break; + + default: + break; } break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ @@ -436,15 +476,18 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 0x0f: /* Cursor Y High Register (RS value = 1111) */ temp = (ramdac->hwc_y >> 8) & 0xff; break; + + default: + break; } return temp; } void -tvp3026_recalctimings(void *p, svga_t *svga) +tvp3026_recalctimings(void *priv, svga_t *svga) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; svga->interlace = (ramdac->ccr & 0x40); } @@ -466,7 +509,7 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) uint32_t clr2; uint32_t clr3; uint32_t *p; - uint8_t *cd; + const uint8_t *cd; tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) svga->ramdac; clr1 = ramdac->extpallook[1]; @@ -513,6 +556,9 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] = clr3; break; + + default: + break; } break; case 2: /* XGA */ @@ -526,6 +572,9 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] ^= 0xffffff; break; + + default: + break; } break; case 3: /* X-Windows */ @@ -536,8 +585,14 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] = clr2; break; + + default: + break; } break; + + default: + break; } } offset++; @@ -552,12 +607,12 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) float tvp3026_getclock(int clock, void *priv) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; - int n; - int m; - int pl; - float f_vco; - float f_pll; + const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; + int n; + int m; + int pl; + float f_vco; + float f_pll; if (clock == 0) return 25175000.0; @@ -569,7 +624,7 @@ tvp3026_getclock(int clock, void *priv) n = ramdac->pix.n & 0x3f; m = ramdac->pix.m & 0x3f; pl = ramdac->pix.p & 0x03; - f_vco = 8.0 * 14318184 * (float) (65 - m) / (float) (65 - n); + f_vco = 8.0f * 14318184 * (float) (65 - m) / (float) (65 - n); f_pll = f_vco / (float) (1 << pl); return f_pll; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 610e15e6c..a34f26503 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -160,8 +160,8 @@ voodoo_readw(uint32_t addr, void *priv) if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ { if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; + const voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; if (y & 1) voodoo = set->voodoos[1]; @@ -194,13 +194,12 @@ voodoo_readl(uint32_t addr, void *priv) cycles -= voodoo->read_time; - if (addr & 0x800000) /*Texture*/ - { + if (addr & 0x800000) { /*Texture*/ } else if (addr & 0x400000) /*Framebuffer*/ { if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; + const voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; if (y & 1) voodoo = set->voodoos[1]; @@ -429,7 +428,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) { voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val); } else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) { - // voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); +#if 0 + voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); +#endif *(uint32_t *) &voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; voodoo->cmdfifo_depth_wr++; if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) @@ -492,7 +493,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) if (voodoo->initEnable & 0x01) { voodoo->fbiInit4 = val; voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); - // voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); +#if 0 + voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); +#endif } break; case SST_backPorch: @@ -538,7 +541,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5); voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); - // voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); +#if 0 + voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); +#endif } break; case SST_fbiInit2: @@ -590,6 +595,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) case 0x0b: voodoo->dac_readdata = 0x79; break; + + default: + break; } } else voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7]; @@ -599,7 +607,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val; else voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8); - // voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); +#if 0 + voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); +#endif voodoo->dac_reg_ff = !voodoo->dac_reg_ff; if (!voodoo->dac_reg_ff) voodoo->dac_data[4]++; @@ -642,7 +652,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) case SST_cmdFifoBaseAddr: voodoo->cmdfifo_base = (val & 0x3ff) << 12; voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; - // voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); +#if 0 + voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); +#endif break; case SST_cmdFifoRdPtr: @@ -672,14 +684,14 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) static uint16_t voodoo_snoop_readw(uint32_t addr, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) priv; + const voodoo_set_t *set = (voodoo_set_t *) priv; return voodoo_readw(addr, set->voodoos[0]); } static uint32_t voodoo_snoop_readl(uint32_t addr, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) priv; + const voodoo_set_t *set = (voodoo_set_t *) priv; return voodoo_readl(addr, set->voodoos[0]); } @@ -687,7 +699,7 @@ voodoo_snoop_readl(uint32_t addr, void *priv) static void voodoo_snoop_writew(uint32_t addr, uint16_t val, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) priv; + const voodoo_set_t *set = (voodoo_set_t *) priv; voodoo_writew(addr, val, set->voodoos[0]); voodoo_writew(addr, val, set->voodoos[1]); @@ -695,7 +707,7 @@ voodoo_snoop_writew(uint32_t addr, uint16_t val, void *priv) static void voodoo_snoop_writel(uint32_t addr, uint32_t val, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) priv; + const voodoo_set_t *set = (voodoo_set_t *) priv; voodoo_writel(addr, val, set->voodoos[0]); voodoo_writel(addr, val, set->voodoos[1]); @@ -749,7 +761,7 @@ voodoo_recalcmapping(voodoo_set_t *set) uint8_t voodoo_pci_read(int func, int addr, void *priv) { - voodoo_t *voodoo = (voodoo_t *) priv; + const voodoo_t *voodoo = (voodoo_t *) priv; if (func) return 0; @@ -803,6 +815,9 @@ voodoo_pci_read(int func, int addr, void *priv) return (voodoo->initEnable >> 16) & 0xff; case 0x43: return (voodoo->initEnable >> 24) & 0xff; + + default: + break; } return 0; } @@ -844,13 +859,16 @@ voodoo_pci_write(int func, int addr, uint8_t val, void *priv) voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24); voodoo_recalcmapping(voodoo->set); break; + + default: + break; } } static void voodoo_speed_changed(void *priv) { - voodoo_set_t *voodoo_set = (voodoo_set_t *) priv; + const voodoo_set_t *voodoo_set = (voodoo_set_t *) priv; voodoo_pixelclock_update(voodoo_set->voodoos[0]); voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1); @@ -870,7 +888,7 @@ voodoo_speed_changed(void *priv) static void voodoo_force_blit(void *priv) { - voodoo_set_t *voodoo_set = (voodoo_set_t *) priv; + const voodoo_set_t *voodoo_set = (voodoo_set_t *) priv; thread_wait_mutex(voodoo_set->voodoos[0]->force_blit_mutex); if (voodoo_set->voodoos[0]->can_blit) { @@ -916,6 +934,9 @@ voodoo_card_init(void) case VOODOO_2: voodoo->dual_tmus = 1; break; + + default: + break; } if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/ @@ -923,7 +944,7 @@ voodoo_card_init(void) else voodoo_generate_filter_v1(voodoo); - pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo); + pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo, &voodoo->pci_slot); mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo); @@ -1163,7 +1184,7 @@ voodoo_2d3d_card_init(int type) } void * -voodoo_init(const device_t *info) +voodoo_init(UNUSED(const device_t *info)) { voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); uint32_t tmuConfig = 1; @@ -1205,6 +1226,9 @@ voodoo_init(const device_t *info) case VOODOO_2: tmuConfig = 1 | (3 << 6); break; + + default: + break; } voodoo_set->voodoos[0]->tmuConfig = tmuConfig; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 0b3a3a043..a73f2d3e8 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -142,8 +142,11 @@ typedef struct banshee_t { int desktop_y; uint32_t desktop_stride_tiled; - int type, card, agp, has_bios; - int vblank_irq; + int type, agp; + int has_bios, vblank_irq; + + uint8_t pci_slot; + uint8_t irq_state; void *i2c, *i2c_ddc, *ddc; } banshee_t; @@ -306,9 +309,9 @@ static void banshee_update_irqs(banshee_t *banshee) { if (banshee->vblank_irq > 0 && banshee_vga_vsync_enabled(banshee)) { - pci_set_irq(banshee->card, PCI_INTA); + pci_set_irq(banshee->pci_slot, PCI_INTA, &banshee->irq_state); } else { - pci_clear_irq(banshee->card, PCI_INTA); + pci_clear_irq(banshee->pci_slot, PCI_INTA, &banshee->irq_state); } } @@ -370,6 +373,9 @@ banshee_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } svga_out(addr, val, svga); } @@ -430,8 +436,7 @@ banshee_updatemapping(banshee_t *banshee) } banshee_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ - { + switch (svga->gdcreg[6] & 0xc) { /*Banked framebuffer*/ case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; @@ -448,6 +453,9 @@ banshee_updatemapping(banshee_t *banshee) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } banshee_log("Linear framebuffer %08X ", banshee->memBaseAddr1); @@ -461,7 +469,7 @@ static void banshee_render_16bpp_tiled(svga_t *svga) { banshee_t *banshee = (banshee_t *) svga->priv; - uint32_t *p = &((uint32_t *) svga->monitor->target_buffer->line[svga->displine + svga->y_add])[svga->x_add]; + uint32_t *p = &(svga->monitor->target_buffer->line[svga->displine + svga->y_add])[svga->x_add]; uint32_t addr; int drawn = 0; @@ -477,7 +485,7 @@ banshee_render_16bpp_tiled(svga_t *svga) if (svga->hwcursor_on || svga->overlay_on) svga->changedvram[addr >> 12] = 2; if (svga->changedvram[addr >> 12] || svga->fullchange) { - uint16_t *vram_p = (uint16_t *) &svga->vram[addr & svga->vram_display_mask]; + const uint16_t *vram_p = (uint16_t *) &svga->vram[addr & svga->vram_display_mask]; for (uint8_t xx = 0; xx < 64; xx++) *p++ = video_16to32[*vram_p++]; @@ -500,8 +508,8 @@ banshee_render_16bpp_tiled(svga_t *svga) static void banshee_recalctimings(svga_t *svga) { - banshee_t *banshee = (banshee_t *) svga->priv; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *) svga->priv; + const voodoo_t *voodoo = banshee->voodoo; /*7 R/W Horizontal Retrace End bit 5. - 6 R/W Horizontal Retrace Start bit 8 0x4 @@ -905,10 +913,11 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv) svga->fullchange = changeframecount; svga_recalctimings(svga); break; -#if 0 default: +#if 0 fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val); #endif + break; } } @@ -996,15 +1005,14 @@ banshee_ext_in(uint16_t addr, void *priv) static uint32_t banshee_status(banshee_t *banshee) { - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - int fifo_entries = FIFO_ENTRIES; - int swap_count = voodoo->swap_count; - int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; - uint32_t ret; + voodoo_t *voodoo = banshee->voodoo; + const svga_t *svga = &banshee->svga; + int fifo_entries = FIFO_ENTRIES; + int swap_count = voodoo->swap_count; + int written = voodoo->cmd_written + voodoo->cmd_written_fifo; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; + uint32_t ret = 0; - ret = 0; if (fifo_entries < 0x20) ret |= 0x1f - fifo_entries; else @@ -1037,10 +1045,10 @@ banshee_status(banshee_t *banshee) static uint32_t banshee_ext_inl(uint16_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - uint32_t ret = 0xffffffff; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + const svga_t *svga = &banshee->svga; + uint32_t ret = 0xffffffff; cycles -= voodoo->read_time; @@ -1212,8 +1220,8 @@ banshee_reg_readw(uint32_t addr, void *priv) static uint32_t banshee_cmd_read(banshee_t *banshee, uint32_t addr) { - voodoo_t *voodoo = banshee->voodoo; - uint32_t ret = 0xffffffff; + const voodoo_t *voodoo = banshee->voodoo; + uint32_t ret = 0xffffffff; switch (addr & 0x1fc) { case Agp_agpHostAddressLow: @@ -1419,6 +1427,9 @@ banshee_reg_readl(uint32_t addr, void *priv) break; } break; + + default: + break; } #if 0 @@ -1467,6 +1478,9 @@ banshee_reg_writew(uint32_t addr, uint16_t val, void *priv) case 0x1f00000: voodoo_queue_command(voodoo, (addr & 0xffffff) | FIFO_WRITEW_FB, val); break; + + default: + break; } } @@ -1679,15 +1693,18 @@ banshee_reg_writel(uint32_t addr, uint32_t val, void *priv) case 0x1f00000: voodoo_queue_command(voodoo, (addr & 0xfffffc) | FIFO_WRITEL_FB, val); break; + + default: + break; } } static uint8_t banshee_read_linear(uint32_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + const svga_t *svga = &banshee->svga; cycles -= voodoo->read_time; @@ -1723,9 +1740,9 @@ banshee_read_linear(uint32_t addr, void *priv) static uint16_t banshee_read_linear_w(uint32_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; if (addr & 1) return banshee_read_linear(addr, priv) | (banshee_read_linear(addr + 1, priv) << 8); @@ -1763,9 +1780,9 @@ banshee_read_linear_w(uint32_t addr, void *priv) static uint32_t banshee_read_linear_l(uint32_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; if (addr & 3) return banshee_read_linear_w(addr, priv) | (banshee_read_linear_w(addr + 2, priv) << 16); @@ -1804,9 +1821,9 @@ banshee_read_linear_l(uint32_t addr, void *priv) static void banshee_write_linear(uint32_t addr, uint8_t val, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; cycles -= voodoo->write_time; @@ -1839,9 +1856,9 @@ banshee_write_linear(uint32_t addr, uint8_t val, void *priv) static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) priv; + const voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; if (addr & 1) { banshee_write_linear(addr, val, priv); @@ -1981,14 +1998,14 @@ banshee_write_linear_l(uint32_t addr, uint32_t val, void *priv) void banshee_hwcursor_draw(svga_t *svga, int displine) { - banshee_t *banshee = (banshee_t *) svga->priv; - int x; - int x_off; - int xx; - uint32_t col0 = banshee->hwCurC0; - uint32_t col1 = banshee->hwCurC1; - uint8_t plane0[8]; - uint8_t plane1[8]; + const banshee_t *banshee = (banshee_t *) svga->priv; + int x; + int x_off; + int xx; + uint32_t col0 = banshee->hwCurC0; + uint32_t col1 = banshee->hwCurC1; + uint8_t plane0[8]; + uint8_t plane1[8]; for (uint8_t c = 0; c < 8; c++) plane0[c] = svga->vram[svga->hwcursor_latch.addr + c]; @@ -2004,7 +2021,7 @@ banshee_hwcursor_draw(svga_t *svga, int displine) if (x_off > -8) { for (xx = 0; xx < 8; xx++) { if (plane0[x >> 3] & (1 << 7)) - ((uint32_t *) svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; plane0[x >> 3] <<= 1; plane1[x >> 3] <<= 1; @@ -2019,9 +2036,9 @@ banshee_hwcursor_draw(svga_t *svga, int displine) if (x_off > -8) { for (xx = 0; xx < 8; xx++) { if (!(plane0[x >> 3] & (1 << 7))) - ((uint32_t *) svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; else if (plane1[x >> 3] & (1 << 7)) - ((uint32_t *) svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; + (svga->monitor->target_buffer->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; plane0[x >> 3] <<= 1; plane1[x >> 3] <<= 1; @@ -2186,8 +2203,6 @@ banshee_hwcursor_draw(svga_t *svga, int displine) void voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) { - int g; - int h; float difference; float diffg; float thiscol; @@ -2201,10 +2216,8 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) fcg *= hack; /* box prefilter */ - for (g = 0; g < 256; g++) // pixel 1 - our target pixel we want to bleed into - { - for (h = 0; h < 256; h++) // pixel 2 - our main pixel - { + for (uint16_t g = 0; g < 256; g++) { // pixel 1 - our target pixel we want to bleed into + for (uint16_t h = 0; h < 256; h++) { // pixel 2 - our main pixel float avg; float avgdiff; @@ -2286,10 +2299,8 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) fcg *= 6; #endif - for (g = 0; g < 256; g++) // pixel 1 - { - for (h = 0; h < 256; h++) // pixel 2 - { + for (uint16_t g = 0; g < 256; g++) { // pixel 1 + for (uint16_t h = 0; h < 256; h++) { // pixel 2 difference = (float) (h - g); diffg = difference; @@ -2329,18 +2340,18 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) static void banshee_overlay_draw(svga_t *svga, int displine) { - banshee_t *banshee = (banshee_t *) svga->priv; - voodoo_t *voodoo = banshee->voodoo; - uint32_t *p; - int x; - int y = voodoo->overlay.src_y >> 20; - uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : y * svga->overlay_latch.pitch); - uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : (y + 1) * svga->overlay_latch.pitch); - uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; - uint32_t src_x = 0; - unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; - int skip_filtering; - uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0]; + banshee_t *banshee = (banshee_t *) svga->priv; + voodoo_t *voodoo = banshee->voodoo; + uint32_t *p; + int x; + int y = voodoo->overlay.src_y >> 20; + uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : y * svga->overlay_latch.pitch); + uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : (y + 1) * svga->overlay_latch.pitch); + uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; + uint32_t src_x = 0; + unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; + int skip_filtering; + const uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0]; if (svga->render == svga_render_null && !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && !svga->fullchange && ((voodoo->overlay.src_y >> 20) < 2048 && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) && !(banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) { voodoo->overlay.src_y += (1 << 20); @@ -2354,7 +2365,7 @@ banshee_overlay_draw(svga_t *svga, int displine) if (src_addr >= 0x800000) fatal("overlay out of range!\n"); #endif - p = &((uint32_t *) svga->monitor->target_buffer->line[displine])[svga->overlay_latch.x + svga->x_add]; + p = &(svga->monitor->target_buffer->line[displine])[svga->overlay_latch.x + svga->x_add]; if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_4X4) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_2X2)); @@ -2608,7 +2619,7 @@ banshee_vsync_callback(svga_t *svga) static uint8_t banshee_pci_read(int func, int addr, void *priv) { - banshee_t *banshee = (banshee_t *) priv; + const banshee_t *banshee = (banshee_t *) priv; #if 0 svga_t *svga = &banshee->svga; #endif @@ -2803,6 +2814,9 @@ banshee_pci_read(int func, int addr, void *priv) case 0x67: ret = banshee->pci_regs[0x67]; break; + + default: + break; } #if 0 banshee_log("%02X\n", ret); @@ -2932,6 +2946,9 @@ banshee_pci_write(int func, int addr, uint8_t val, void *priv) case 0x66: banshee->pci_regs[0x66] = val & 0xc0; return; + + default: + break; } } @@ -3146,7 +3163,10 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->dramInit1 = 1 << 30; /*SDRAM*/ banshee->svga.decode_mask = 0x1ffffff; - banshee->card = pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee); + if (banshee->has_bios) + pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_NORMAL, banshee_pci_read, banshee_pci_write, banshee, &banshee->pci_slot); + else + pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee, &banshee->pci_slot); banshee->voodoo = voodoo_2d3d_card_init(voodoo_type); banshee->voodoo->p = banshee; @@ -3238,6 +3258,9 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->pci_regs[0x2e] = 0x54; banshee->pci_regs[0x2f] = 0x00; break; + + default: + break; } video_inform(VIDEO_FLAG_TYPE_SPECIAL, banshee->agp ? &timing_banshee_agp : &timing_banshee); diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index f5009e0b8..33ee602b5 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -250,6 +250,9 @@ PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, voodoo->changedvram[addr >> 12] = changeframecount; break; } + + default: + break; } } @@ -293,6 +296,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, voodoo->changedvram[addr >> 12] = changeframecount; break; } + + default: + break; } } @@ -364,6 +370,9 @@ update_src_stride(voodoo_t *voodoo) bansheeblt_log("Dword packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); #endif break; + + default: + break; } } @@ -385,12 +394,12 @@ end_command(voodoo_t *voodoo) static void banshee_do_rectfill(voodoo_t *voodoo) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - int dst_y = voodoo->banshee_blt.dstY; - uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; #if 0 bansheeblt_log("banshee_do_rectfill: size=%i,%i dst=%i,%i\n", voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY); @@ -519,13 +528,13 @@ DECODE_YUYV422_16BPP(uint16_t *buf, uint8_t *src) static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - int dst_y = voodoo->banshee_blt.dstY; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; - int src_colorkey; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int src_colorkey; switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { case SRC_FORMAT_COL_8_BPP: @@ -601,6 +610,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr voodoo->changedvram[dst_addr >> 12] = changeframecount; break; } + + default: + break; } } if (use_x_dir) { @@ -619,7 +631,9 @@ do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int sr } else { /*Conversion required*/ if (dst_y >= clip->y_min && dst_y < clip->y_max) { - // int src_x = voodoo->banshee_blt.srcX; +#if 0 + int src_x = voodoo->banshee_blt.srcX; +#endif int dst_x = voodoo->banshee_blt.dstX; int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; uint8_t pattern_mask = pattern_mono[pat_y & 7]; @@ -777,7 +791,7 @@ banshee_do_screen_to_screen_blt(voodoo_t *voodoo) } static void -banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data) +banshee_do_host_to_screen_blt(voodoo_t *voodoo, UNUSED(int count), uint32_t data) { #if 0 if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) @@ -849,15 +863,15 @@ banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data) static void do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, int *src_y) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; #if 0 int src_y = voodoo->banshee_blt.srcY; #endif - int dst_y = voodoo->banshee_blt.dstY; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint32_t *colorPattern = voodoo->banshee_blt.colorPattern; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + const uint32_t *colorPattern = voodoo->banshee_blt.colorPattern; #if 0 int error_y = voodoo->banshee_blt.dstSizeY / 2; @@ -891,7 +905,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); - // bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); +#if 0 + bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); +#endif voodoo->changedvram[dst_addr >> 12] = changeframecount; break; } @@ -937,6 +953,9 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in voodoo->changedvram[dst_addr >> 12] = changeframecount; break; } + + default: + break; } } @@ -1063,16 +1082,16 @@ step_line(voodoo_t *voodoo) static void banshee_do_line(voodoo_t *voodoo, int draw_last_pixel) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - uint8_t rop = voodoo->banshee_blt.command >> 24; - int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); - int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); - int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1; - int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1; - int x = voodoo->banshee_blt.srcX; - int y = voodoo->banshee_blt.srcY; - int error; - uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? voodoo->banshee_blt.lineStipple : ~0; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + uint8_t rop = voodoo->banshee_blt.command >> 24; + int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); + int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); + int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1; + int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1; + int x = voodoo->banshee_blt.srcX; + int y = voodoo->banshee_blt.srcY; + int error; + uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? voodoo->banshee_blt.lineStipple : ~0; if (dx > dy) /*X major*/ { @@ -1143,12 +1162,12 @@ banshee_polyfill_start(voodoo_t *voodoo) static void banshee_polyfill_continue(voodoo_t *voodoo, uint32_t data) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; - int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]); - int y_end; + const clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]); + int y_end; #if 0 bansheeblt_log("Polyfill : data %08x\n", data); diff --git a/src/video/vid_voodoo_blitter.c b/src/video/vid_voodoo_blitter.c index ff45fc837..6ea2edcc3 100644 --- a/src/video/vid_voodoo_blitter.c +++ b/src/video/vid_voodoo_blitter.c @@ -163,8 +163,6 @@ voodoo_v2_blit_start(voodoo_t *voodoo) int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8); uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8); uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - int x; - int y; #if 0 voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", @@ -175,13 +173,13 @@ voodoo_v2_blit_start(voodoo_t *voodoo) switch (voodoo->bltCommand & BLIT_COMMAND_MASK) { case BLIT_COMMAND_SCREEN_TO_SCREEN: - for (y = 0; y <= size_y; y++) { - uint16_t *src = (uint16_t *) &voodoo->fb_mem[src_base_addr + src_y * src_stride]; - uint16_t *dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; - int src_x = voodoo->bltSrcX; - int dst_x = voodoo->bltDstX; + for (int y = 0; y <= size_y; y++) { + const uint16_t *src = (uint16_t *) &voodoo->fb_mem[src_base_addr + src_y * src_stride]; + uint16_t *dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; + int src_x = voodoo->bltSrcX; + int dst_x = voodoo->bltDstX; - for (x = 0; x <= size_x; x++) { + for (int x = 0; x <= size_x; x++) { uint16_t src_dat = src[src_x]; uint16_t dst_dat = dst[dst_x]; int rop = 0; @@ -233,7 +231,7 @@ skip_pixel_blit: break; case BLIT_COMMAND_RECT_FILL: - for (y = 0; y <= size_y; y++) { + for (int y = 0; y <= size_y; y++) { uint16_t *dst; int dst_x = voodoo->bltDstX; @@ -244,7 +242,7 @@ skip_pixel_blit: } else dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; - for (x = 0; x <= size_x; x++) { + for (int x = 0; x <= size_x; x++) { if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) goto skip_pixel_fill; @@ -267,7 +265,7 @@ skip_line_fill: dat64 = voodoo->bltColorFg | ((uint64_t) voodoo->bltColorFg << 16) | ((uint64_t) voodoo->bltColorFg << 32) | ((uint64_t) voodoo->bltColorFg << 48); - for (y = 0; y <= size_y; y++) { + for (int y = 0; y <= size_y; y++) { uint64_t *dst; /*This may be wrong*/ @@ -284,7 +282,7 @@ skip_line_fill: dst = (uint64_t *) &voodoo->fb_mem[(dst_y * 512 * 8 + dst_x * 8) & voodoo->fb_mask]; - for (x = 0; x <= size_x; x++) + for (int x = 0; x <= size_x; x++) dst[x] = dat64; dst_y++; @@ -347,6 +345,9 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) case BLIT_SRC_RGB_BGRA: src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11); break; + + default: + break; } data >>= 16; src_bits -= 16; @@ -375,6 +376,9 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) g = (data >> 16) & 0xff; b = (data >> 24) & 0xff; break; + + default: + break; } switch (voodoo->bltCommand & BLIT_SRC_FORMAT) { case BLIT_SRC_24BPP: @@ -392,9 +396,15 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3]; src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); break; + + default: + break; } src_bits = 0; break; + + default: + break; } if (SLI_ENABLED) { diff --git a/src/video/vid_voodoo_display.c b/src/video/vid_voodoo_display.c index 84f376a8f..e6cf13674 100644 --- a/src/video/vid_voodoo_display.c +++ b/src/video/vid_voodoo_display.c @@ -509,8 +509,8 @@ voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, void voodoo_callback(void *priv) { - voodoo_t *voodoo = (voodoo_t *) priv; - monitor_t *monitor = &monitors[voodoo->monitor_index]; + voodoo_t *voodoo = (voodoo_t *) priv; + const monitor_t *monitor = &monitors[voodoo->monitor_index]; if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { if (voodoo->line < voodoo->v_disp) { diff --git a/src/video/vid_voodoo_fb.c b/src/video/vid_voodoo_fb.c index 5e06836b1..94394e115 100644 --- a/src/video/vid_voodoo_fb.c +++ b/src/video/vid_voodoo_fb.c @@ -76,7 +76,7 @@ voodoo_fb_readw(uint32_t addr, void *priv) } if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; + const voodoo_set_t *set = voodoo->set; if (y & 1) voodoo = set->voodoos[1]; @@ -117,7 +117,7 @@ voodoo_fb_readl(uint32_t addr, void *priv) } if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; + const voodoo_set_t *set = voodoo->set; if (y & 1) voodoo = set->voodoos[1]; @@ -170,16 +170,16 @@ do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) void voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) priv; - voodoo_params_t *params = &voodoo->params; - int x; - int y; - uint32_t write_addr; - uint32_t write_addr_aux; - rgba8_t colour_data; - uint16_t depth_data; - uint8_t alpha_data; - int write_mask = 0; + voodoo_t *voodoo = (voodoo_t *) priv; + const voodoo_params_t *params = &voodoo->params; + int x; + int y; + uint32_t write_addr; + uint32_t write_addr_aux; + rgba8_t colour_data; + uint16_t depth_data; + uint8_t alpha_data; + int write_mask = 0; colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; @@ -310,17 +310,17 @@ skip_pixel: void voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) priv; - voodoo_params_t *params = &voodoo->params; - int x; - int y; - uint32_t write_addr; - uint32_t write_addr_aux; - rgba8_t colour_data[2]; - uint16_t depth_data[2]; - uint8_t alpha_data[2]; - int write_mask = 0; - int count = 1; + voodoo_t *voodoo = (voodoo_t *) priv; + const voodoo_params_t *params = &voodoo->params; + int x; + int y; + uint32_t write_addr; + uint32_t write_addr_aux; + rgba8_t colour_data[2]; + uint16_t depth_data[2]; + uint8_t alpha_data[2]; + int write_mask = 0; + int count = 1; depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index 4a66161f5..d2fa2e1a2 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -1121,6 +1121,7 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv) } break; } + fallthrough; case SST_nccTable0_I2: if (!(val & (1 << 31))) { if (chip & CHIP_TREX0) { @@ -1359,5 +1360,8 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv) case SST_leftOverlayBuf: voodoo->leftOverlayBuf = val; break; + + default: + break; } } diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index 052a0b51e..42426744a 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -475,6 +475,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta case TC_MSELECT_LOD_FRAC: factor_r = factor_g = factor_b = state->lod_frac[1]; break; + + default: + break; } if (!c_reverse) { r = (-state->tex_r[1] * (factor_r + 1)) >> 8; @@ -520,6 +523,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta case TCA_MSELECT_LOD_FRAC: factor_a = state->lod_frac[1]; break; + + default: + break; } if (!a_reverse) a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8; @@ -575,6 +581,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta case TC_MSELECT_LOD_FRAC: factor_r = factor_g = factor_b = state->lod_frac[0]; break; + + default: + break; } if (!c_reverse) { r = (r * (factor_r + 1)) >> 8; @@ -622,6 +631,9 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta case TCA_MSELECT_LOD_FRAC: factor_a = state->lod_frac[0]; break; + + default: + break; } if (a_reverse) a = (a * ((factor_a ^ 0xff) + 1)) >> 8; @@ -1073,6 +1085,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * cother_g = src_g; cother_b = src_b; break; + + default: + break; } switch (cca_localselect) { @@ -1460,15 +1475,15 @@ voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) vertexCy_adjusted = (state.vertexCy + 7) >> 4; if (state.vertexBy - state.vertexAy) - state.dxAB = (int) ((((int64_t) state.vertexBx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (int) (state.vertexBy - state.vertexAy); + state.dxAB = (int) ((((int64_t) state.vertexBx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (state.vertexBy - state.vertexAy); else state.dxAB = 0; if (state.vertexCy - state.vertexAy) - state.dxAC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (int) (state.vertexCy - state.vertexAy); + state.dxAC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (state.vertexCy - state.vertexAy); else state.dxAC = 0; if (state.vertexCy - state.vertexBy) - state.dxBC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexBx << 12)) << 4) / (int) (state.vertexCy - state.vertexBy); + state.dxBC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexBx << 12)) << 4) / (state.vertexCy - state.vertexBy); else state.dxBC = 0; diff --git a/src/video/vid_voodoo_texture.c b/src/video/vid_voodoo_texture.c index 8b8f1366d..3939db3cd 100644 --- a/src/video/vid_voodoo_texture.c +++ b/src/video/vid_voodoo_texture.c @@ -192,7 +192,9 @@ voodoo_recalc_tex3(voodoo_t *voodoo, int tmu) if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD)) tex_lod++; /*Skip LOD 0*/ - // voodoo_texture_log("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); +#if 0 + voodoo_texture_log("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); +#endif for (lod = 0; lod <= LOD_MAX + 1; lod++) { if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) { switch (tex_lod) { @@ -302,18 +304,22 @@ voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) lod_min = (params->tLOD[tmu] >> 2) & 15; lod_max = (params->tLOD[tmu] >> 8) & 15; - // voodoo_texture_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); +#if 0 + voodoo_texture_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); +#endif lod_min = MIN(lod_min, 8); lod_max = MIN(lod_max, 8); for (int lod = lod_min; lod <= lod_max; lod++) { - uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; - uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; - int x; - int y; - int shift = 8 - params->tex_lod[tmu][lod]; - rgba_u *pal; + uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; + uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; + int x; + int y; + int shift = 8 - params->tex_lod[tmu][lod]; + const rgba_u *pal; - // voodoo_texture_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); +#if 0 + voodoo_texture_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); +#endif switch (params->tformat[tmu]) { case TEX_RGB332: @@ -566,7 +572,9 @@ flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) if (addr_end_masked < addr_start_masked) addr_end_masked = voodoo->texture_mask + 1; if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) { - // voodoo_texture_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); +#if 0 + voodoo_texture_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); +#endif if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1])) wait_for_idle = 1; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 350fc1c50..d7a69afdf 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -1,18 +1,18 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * IBM XGA emulation. + * IBM XGA emulation. * * * - * Authors: TheCollector1995. + * Authors: TheCollector1995. * - * Copyright 2022 TheCollector1995. + * Copyright 2022 TheCollector1995. */ #include #include @@ -3078,8 +3078,8 @@ xga_init(const device_t *info) svga_t *svga = svga_get_pri(); xga_t *xga = &svga->xga; FILE *f; - uint32_t temp; uint8_t *rom = NULL; + size_t res; xga->ext_mem_addr = device_get_config_hex16("ext_mem_addr"); xga->instance_isa = device_get_config_int("instance"); @@ -3100,13 +3100,11 @@ xga_init(const device_t *info) f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); (void) fseek(f, 0L, SEEK_END); - temp = ftell(f); (void) fseek(f, 0L, SEEK_SET); rom = malloc(xga->bios_rom.sz); memset(rom, 0xff, xga->bios_rom.sz); - (void) fread(rom, xga->bios_rom.sz, 1, f); - temp -= xga->bios_rom.sz; + res = fread(rom, xga->bios_rom.sz, 1, f); (void) fclose(f); xga->bios_rom.rom = rom; diff --git a/src/video/video.c b/src/video/video.c index 7ecb0e5f9..76982abdf 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -106,7 +106,7 @@ void *__cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy void *(*video_copy)(void *__restrict, const void *__restrict, size_t); #endif -PALETTE cgapal = { +PALETTE cgapal = { {0,0,0}, {0,42,0}, {42,0,0}, {42,21,0}, {0,0,0}, {0,42,42}, {42,0,42}, {42,42,42}, {0,0,0}, {21,63,21}, {63,21,21}, {63,63,21}, @@ -127,109 +127,108 @@ PALETTE cgapal = { {0,0,0}, {0,63,63}, {63,0,0}, {63,63,63}, {0,0,0}, {0,63,63}, {63,0,0}, {63,63,63}, }; -PALETTE cgapal_mono[6] = { - { /* 0 - green, 4-color-optimized contrast. */ - {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05}, - {0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a}, - {0x03,0x39,0x0d},{0x03,0x3c,0x0e},{0x00,0x07,0x01}, - {0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08}, - {0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17}, +PALETTE cgapal_mono[6] = { + { /* 0 - green, 4-color-optimized contrast. */ + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05}, + {0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a}, + {0x03,0x39,0x0d},{0x03,0x3c,0x0e},{0x00,0x07,0x01}, + {0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08}, + {0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17}, }, - { /* 1 - green, 16-color-optimized contrast. */ - {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05}, - {0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08}, - {0x02,0x2e,0x0b},{0x02,0x31,0x0b},{0x01,0x22,0x08}, - {0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c}, - {0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17}, + { /* 1 - green, 16-color-optimized contrast. */ + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05}, + {0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08}, + {0x02,0x2e,0x0b},{0x02,0x31,0x0b},{0x01,0x22,0x08}, + {0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c}, + {0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17}, }, - { /* 2 - amber, 4-color-optimized contrast. */ - {0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00}, - {0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00}, - {0x3f,0x26,0x01},{0x3f,0x2b,0x06},{0x0b,0x02,0x00}, - {0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00}, - {0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d}, + { /* 2 - amber, 4-color-optimized contrast. */ + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00}, + {0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00}, + {0x3f,0x26,0x01},{0x3f,0x2b,0x06},{0x0b,0x02,0x00}, + {0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00}, + {0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d}, }, - { /* 3 - amber, 16-color-optimized contrast. */ - {0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00}, - {0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00}, - {0x38,0x1c,0x00},{0x3b,0x1e,0x00},{0x2c,0x13,0x00}, - {0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00}, - {0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, + { /* 3 - amber, 16-color-optimized contrast. */ + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00}, + {0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00}, + {0x38,0x1c,0x00},{0x3b,0x1e,0x00},{0x2c,0x13,0x00}, + {0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00}, + {0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, }, - { /* 4 - grey, 4-color-optimized contrast. */ - {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18}, - {0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28}, - {0x33,0x34,0x32},{0x37,0x38,0x35},{0x09,0x0a,0x0b}, - {0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22}, - {0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b}, + { /* 4 - grey, 4-color-optimized contrast. */ + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18}, + {0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28}, + {0x33,0x34,0x32},{0x37,0x38,0x35},{0x09,0x0a,0x0b}, + {0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22}, + {0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b}, }, - { /* 5 - grey, 16-color-optimized contrast. */ - {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15}, - {0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22}, - {0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},{0x1f,0x21,0x21}, - {0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d}, - {0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b}, + { /* 5 - grey, 16-color-optimized contrast. */ + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15}, + {0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22}, + {0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},{0x1f,0x21,0x21}, + {0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d}, + {0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b}, } }; -const uint32_t shade[5][256] = -{ - {0}, // RGB Color (unused) - {0}, // RGB Grayscale (unused) - { // Amber monitor - 0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300, - 0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00, - 0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200, - 0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00, - 0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800, - 0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400, - 0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200, - 0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100, - 0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101, - 0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201, - 0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303, - 0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606, - 0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b, - 0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14, - 0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122, - 0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739 - }, - { // Green monitor - 0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00, - 0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401, - 0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803, - 0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906, - 0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09, - 0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d, - 0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912, - 0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718, - 0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e, - 0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325, - 0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d, - 0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36, - 0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f, - 0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749, - 0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354, - 0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60 - }, - { // White monitor - 0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12, - 0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23, - 0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33, - 0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43, - 0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52, - 0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61, - 0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70, - 0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e, - 0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c, - 0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a, - 0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8, - 0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6, - 0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3, - 0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1, - 0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf, - 0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec - } +const uint32_t shade[5][256] = { + {0}, // RGB Color (unused) + {0}, // RGB Grayscale (unused) + { // Amber monitor + 0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300, + 0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00, + 0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200, + 0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00, + 0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800, + 0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400, + 0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200, + 0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100, + 0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101, + 0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201, + 0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303, + 0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606, + 0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b, + 0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14, + 0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122, + 0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739 + }, + { // Green monitor + 0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00, + 0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401, + 0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803, + 0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906, + 0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09, + 0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d, + 0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912, + 0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718, + 0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e, + 0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325, + 0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d, + 0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36, + 0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f, + 0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749, + 0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354, + 0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60 + }, + { // White monitor + 0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12, + 0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23, + 0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33, + 0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43, + 0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52, + 0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61, + 0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70, + 0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e, + 0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c, + 0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a, + 0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8, + 0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6, + 0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3, + 0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1, + 0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf, + 0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec + } }; typedef struct blit_data_struct { @@ -308,13 +307,13 @@ static png_infop info_ptr[MONITORS_NUM]; static void video_take_screenshot_monitor(const char *fn, uint32_t *buf, int start_x, int start_y, int row_len, int monitor_index) { - png_bytep *b_rgb = NULL; - FILE *fp = NULL; - uint32_t temp = 0x00000000; - blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; + png_bytep *b_rgb = NULL; + FILE *fp = NULL; + uint32_t temp = 0x00000000; + const blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; /* create file */ - fp = plat_fopen((char *) fn, (char *) "wb"); + fp = plat_fopen(fn, (const char *) "wb"); if (!fp) { video_log("[video_take_screenshot] File %s could not be opened for writing", fn); return; @@ -423,8 +422,8 @@ void * video_transform_copy(void *__restrict _Dst, const void *__restrict _Src, size_t _Size) #endif { - uint32_t *dest_ex = (uint32_t *) _Dst; - uint32_t *src_ex = (uint32_t *) _Src; + uint32_t *dest_ex = (uint32_t *) _Dst; + const uint32_t *src_ex = (const uint32_t *) _Src; _Size /= sizeof(uint32_t); @@ -496,8 +495,8 @@ pixel_to_color(uint8_t *pixels32, uint8_t pos) uint32_t temp; temp = *(pixels32 + pos) & 0x03; switch (temp) { - case 0: default: + case 0: return 0x00; case 1: return 0x07; @@ -774,23 +773,27 @@ hline(bitmap_t *b, int x1, int y, int x2, uint32_t col) } void -blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int x2, int y2, int xs, int ys) +blit(UNUSED(bitmap_t *src), UNUSED(bitmap_t *dst), UNUSED(int x1), UNUSED(int y1), UNUSED(int x2), UNUSED(int y2), UNUSED(int xs), UNUSED(int ys)) { + // } void -stretch_blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2) +stretch_blit(UNUSED(bitmap_t *src), UNUSED(bitmap_t *dst), UNUSED(int x1), UNUSED(int y1), UNUSED(int xs1), UNUSED(int ys1), UNUSED(int x2), UNUSED(int y2), UNUSED(int xs2), UNUSED(int ys2)) { + // } void -rectfill(bitmap_t *b, int x1, int y1, int x2, int y2, uint32_t col) +rectfill(UNUSED(bitmap_t *b), UNUSED(int x1), UNUSED(int y1), UNUSED(int x2), UNUSED(int y2), UNUSED(uint32_t col)) { + // } void -set_palette(PALETTE p) +set_palette(UNUSED(PALETTE p)) { + // } void @@ -1115,8 +1118,10 @@ uint32_t video_color_transform(uint32_t color) { uint8_t *clr8 = (uint8_t *) &color; - /* if (!video_grayscale && !invert_display) - return color; */ +#if 0 + if (!video_grayscale && !invert_display) + return color; +#endif if (video_grayscale) { if (video_graytype) { if (video_graytype == 1) @@ -1129,7 +1134,7 @@ video_color_transform(uint32_t color) case 2: case 3: case 4: - color = (uint32_t) shade[video_grayscale][color]; + color = shade[video_grayscale][color]; break; default: clr8[3] = 0; diff --git a/src/vnc.c b/src/vnc.c index 30caff9e2..f8ef1ef38 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -46,15 +46,6 @@ static int ptr_x; static int ptr_y; static int ptr_but; -typedef struct { - int buttons; - int dx; - int dy; - int dwheel; -} MOUSESTATE; - -static MOUSESTATE ms; - #ifdef ENABLE_VNC_LOG int vnc_do_log = ENABLE_VNC_LOG; @@ -82,26 +73,31 @@ vnc_kbdevent(rfbBool down, rfbKeySym k, rfbClientPtr cl) vnc_kbinput(down ? 1 : 0, (int) k); } -void -vnc_mouse_poll(void) +static void +vnc_ptrevent(int but, int x, int y, rfbClientPtr cl) { - static int b = 0; - if (ms.dx != 0 || ms.dy != 0) { - mouse_x += ms.dx; - mouse_y += ms.dy; + int dx; + int dy; + int b; - ms.dx = 0; - ms.dy = 0; + b = 0x00; + if (but & 0x01) + b |= 0x01; + if (but & 0x02) + b |= 0x04; + if (but & 0x04) + b |= 0x02; + mouse_set_buttons_ex(b); + ptr_but = but; -#if 0 - pclog("dx=%d, dy=%d, dwheel=%d\n", mouse_x, mouse_y, mouse_z); -#endif - } + dx = (x - ptr_x) / 0.96; /* TODO: Figure out the correct scale factor for X and Y. */ + dy = (y - ptr_y) / 0.96; - if (b != ms.buttons) { - mouse_buttons = ms.buttons; - b = ms.buttons; - } + /* VNC uses absolute positions within the window, no deltas. */ + mouse_scale_x(dx, dy); + + ptr_x = x; + ptr_y = y; mouse_x_abs = (double)ptr_x / (double)allowedX; mouse_y_abs = (double)ptr_y / (double)allowedY; @@ -110,25 +106,6 @@ vnc_mouse_poll(void) if (mouse_y_abs > 1.0) mouse_y_abs = 1.0; if (mouse_x_abs < 0.0) mouse_x_abs = 0.0; if (mouse_y_abs < 0.0) mouse_y_abs = 0.0; -} - -static void -vnc_ptrevent(int but, int x, int y, rfbClientPtr cl) -{ - ms.buttons = 0; - if (but & 0x01) - ms.buttons |= 0x01; - if (but & 0x02) - ms.buttons |= 0x04; - if (but & 0x04) - ms.buttons |= 0x02; - ptr_but = but; - - /* VNC uses absolute positions within the window, no deltas. */ - ms.dx += (x - ptr_x) / 0.96; /* TODO: Figure out the correct scale factor for X and Y. */ - ms.dy += (y - ptr_y) / 0.96; - ptr_x = x; - ptr_y = y; rfbDefaultPtrAddEvent(but, x, y, cl); } @@ -165,9 +142,8 @@ vnc_newclient(rfbClientPtr cl) /* Reset the mouse. */ ptr_x = allowedX / 2; ptr_y = allowedY / 2; - mouse_x = mouse_y = mouse_z = 0; - mouse_buttons = 0x00; - memset(&ms, 0, sizeof(MOUSESTATE)); + mouse_clear_coords(); + mouse_clear_buttons(); /* We now have clients, un-pause the emulator if needed. */ vnc_log("VNC: unpausing..\n"); diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index a947dfb62..e29c1364e 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -568,7 +568,8 @@ MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma. usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \ $(VNCOBJ) -MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o row.o smram.o spd.o sst_flash.o +MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o mmu_2386.o rom.o row.o \ + smram.o spd.o sst_flash.o CPU808XOBJ := queue.o @@ -581,6 +582,7 @@ CPUOBJ := $(DYNARECOBJ) \ softfloat-muladd.o softfloat-round-pack.o softfloat-specialize.o softfloatx80.o CHIPSETOBJ := 82c100.o acc2168.o \ + compaq_386.o \ contaq_82c59x.o \ cs4031.o cs8230.o \ ali1429.o ali1435.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \ @@ -737,6 +739,7 @@ VIDOBJ := agpgart.o video.o \ vid_ati_eeprom.o \ vid_ati18800.o vid_ati28800.o \ vid_ati_mach8.o \ + vid_ati68875_ramdac.o \ vid_ati_mach64.o vid_ati68860_ramdac.o \ vid_bt48x_ramdac.o \ vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ diff --git a/src/win/win.c b/src/win/win.c index f166d559d..3e3535a32 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -1250,6 +1250,12 @@ plat_language_code_r(uint32_t lcid, char *outbuf, int len) c16stombs(outbuf, buffer, len); } +void +plat_get_cpu_string(char *outbuf, uint8_t len) { + char cpu_string[] = "Unknown"; + strncpy(outbuf, cpu_string, len); +} + void take_screenshot(void) { @@ -1280,3 +1286,11 @@ endblit(void) { ReleaseMutex(ghMutex); } + +double +plat_get_dpi(void) +{ + UINT dpi = win_get_dpi(hwndRender); + + return ((double) dpi) / 96.0; +} diff --git a/src/win/win_mouse.c b/src/win/win_mouse.c index 3e31f12de..e30749145 100644 --- a/src/win/win_mouse.c +++ b/src/win/win_mouse.c @@ -21,26 +21,16 @@ */ #include #include +#include #include #include #include <86box/86box.h> #include <86box/mouse.h> +#include <86box/pic.h> #include <86box/plat.h> #include <86box/win.h> int mouse_capture; -double mouse_sensitivity = 1.0; /* Unused. */ -double mouse_x_error = 0.0; /* Unused. */ -double mouse_y_error = 0.0; /* Unused. */ - -typedef struct { - int buttons; - int dx; - int dy; - int dwheel; -} MOUSESTATE; - -MOUSESTATE mousestate; void win_mouse_init(void) @@ -57,61 +47,68 @@ win_mouse_init(void) ridev.usUsage = 0x02; if (!RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) fatal("plat_mouse_init: RegisterRawInputDevices failed\n"); - - memset(&mousestate, 0, sizeof(MOUSESTATE)); } void win_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) - mousestate.buttons |= 1; + b |= 1; else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) - mousestate.buttons &= ~1; + b &= ~1; if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) - mousestate.buttons |= 4; + b |= 4; else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) - mousestate.buttons &= ~4; + b &= ~4; if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) - mousestate.buttons |= 2; + b |= 2; else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) - mousestate.buttons &= ~2; + b &= ~2; if (state.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) - mousestate.buttons |= 8; + b |= 8; else if (state.usButtonFlags & RI_MOUSE_BUTTON_4_UP) - mousestate.buttons &= ~8; + b &= ~8; if (state.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) - mousestate.buttons |= 16; + b |= 16; else if (state.usButtonFlags & RI_MOUSE_BUTTON_5_UP) - mousestate.buttons &= ~16; + b &= ~16; + + mouse_set_buttons_ex(b); if (state.usButtonFlags & RI_MOUSE_WHEEL) { - mousestate.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. */ - mousestate.dx += (state.lLastX - x) / 25; - mousestate.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 */ - mousestate.dx += state.lLastX; - mousestate.dy += state.lLastY; + delta_x = state.lLastX; + delta_y = state.lLastY; } + + mouse_scale(delta_x, delta_y); } void @@ -124,27 +121,3 @@ win_mouse_close(void) ridev.usUsage = 0x02; RegisterRawInputDevices(&ridev, 1, sizeof(ridev)); } - -void -mouse_poll(void) -{ - static int b = 0; - if (mouse_capture || video_fullscreen) { - if (mousestate.dx != 0 || mousestate.dy != 0 || mousestate.dwheel != 0) { - mouse_x += mousestate.dx; - mouse_y += mousestate.dy; - mouse_z = mousestate.dwheel; - - mousestate.dx = 0; - mousestate.dy = 0; - mousestate.dwheel = 0; - - // pclog("dx=%d, dy=%d, dwheel=%d\n", mouse_x, mouse_y, mouse_z); - } - - if (b != mousestate.buttons) { - mouse_buttons = mousestate.buttons; - b = mousestate.buttons; - } - } -} diff --git a/src/win/win_opengl_glslp.c b/src/win/win_opengl_glslp.c index 47cc755dc..33ed9feab 100644 --- a/src/win/win_opengl_glslp.c +++ b/src/win/win_opengl_glslp.c @@ -50,8 +50,8 @@ in vec2 VertexCoord;\n\ in vec2 TexCoord;\n\ out vec2 tex;\n\ void main(){\n\ - gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ - tex = TexCoord;\n\ + gl_Position = vec4(VertexCoord, 0.0, 1.0);\n\ + tex = TexCoord;\n\ }\n"; /** @@ -62,7 +62,7 @@ in vec2 tex;\n\ uniform sampler2D texsampler;\n\ out vec4 color;\n\ void main() {\n\ - color = texture(texsampler, tex);\n\ + color = texture(texsampler, tex);\n\ }\n"; /** @@ -179,7 +179,7 @@ load_custom_shaders(const char *path) /* Check if the shader program defines version directive */ char *version_start = strstr(shader, "#version"); - /* If the shader program contains a version directive, + /* If the shader program contains a version directive, it must be captured and placed as the first statement. */ if (version_start != NULL) { /* Version directive found, search the line end */ @@ -197,7 +197,7 @@ load_custom_shaders(const char *path) fragment_sources[0] = version; } - /* Comment out the original version directive + /* Comment out the original version directive as only one is allowed. */ memset(version_start, '/', 2); }