diff --git a/src/Makefile.local b/src/Makefile.local index 9774208a7..8b528ff28 100644 --- a/src/Makefile.local +++ b/src/Makefile.local @@ -10,8 +10,6 @@ # settings, so we can avoid changing the main one for all of # our local setups. # -# Version: @(#)Makefile.local 1.0.22 2019/10/20 -# # Author: Fred N. van Kempen, # @@ -35,15 +33,21 @@ STUFF := # -DENABLE_VRAM_DUMP enables Video Ram dumping. # -DENABLE_LOG_BREAKPOINT enables extra logging. # Root logging: +# -DENABLE_ACPI_LOG=N sets logging level at N. # -DENABLE_APM_LOG=N sets logging level at N. # -DENABLE_BUGGER_LOG=N sets logging level at N. # -DENABLE_CONFIG_LOG=N sets logging level at N. +# -DENABLE_DDMA_LOG=N sets logging level at N. # -DENABLE_DEVICE_LOG=N sets logging level at N. +# -DENABLE_DMA_LOG=N sets logging level at N. # -DENABLE_IO_LOG=N sets logging level at N. -# -DENABLE_PIIX_LOG=N sets logging level at N. +# -DENABLE_IOAPIC_LOG=N sets logging level at N. # -DENABLE_ISAMEM_LOG=N sets logging level at N. # -DENABLE_ISARTC_LOG=N sets logging level at N. # -DENABLE_KEYBOARD_AT_LOG=N sets logging level at N. +# -DENABLE_KEYBOARD_XT_LOG=N sets logging level at N. +# -DENABLE_LM75_LOG=N sets logging level at N. +# -DENABLE_LM78_LOG=N sets logging level at N. # -DENABLE_MEM_LOG=N sets logging level at N. # -DENABLE_MOUSE_LOG=N sets logging level at N. # -DENABLE_MOUSE_BUS_LOG=N sets logging level at N. @@ -53,30 +57,41 @@ STUFF := # -DENABLE_PC_LOG=N sets logging level at N. # -DENABLE_PCI_LOG=N sets logging level at N. # -DENABLE_PIC_LOG=N sets logging level at N. +# -DENABLE_PIT_LOG=N sets logging level at N. +# -DENABLE_POSTCARD_LOG=N sets logging level at N. # -DENABLE_ROM_LOG=N sets logging level at N. # -DENABLE_SERIAL_LOG=N sets logging level at N. +# -DENABLE_SMBUS_LOG=N sets logging level at N. +# -DENABLE_SMBUS_PIIX4_LOG=N sets logging level at N. +# -DENABLE_SPD_LOG=N sets logging level at N. +# -DENABLE_USB_LOG=N sets logging level at N. # -DENABLE_VNC_LOG=N sets logging level at N. # -DENABLE_VNC_KEYMAP_LOG=N sets logging level at N. # cdrom/ logging: # -DENABLE_CDROM_LOG=N sets logging level at N. -# -DENABLE_CDROM_DOSBOX_LOG=N sets logging level at N. # -DENABLE_CDROM_IMAGE_LOG=N sets logging level at N. +# -DENABLE_CDROM_IMAGE_BACKEND_LOG=N sets logging level at N. +# chipset/ logging: +# -DENABLE_I420EX_LOG=N sets logging level at N. +# -DENABLE_NEAT_LOG=N sets logging level at N. +# -DENABLE_PIIX_LOG=N sets logging level at N. +# -DENABLE_SIO_LOG=N sets logging level at N. +# codegen/, codegen_new/, cpu/ logging: +# -DENABLE_X86SEG_LOG=N sets logging level at N. # cpu/ logging: # -DENABLE_386_LOG=N sets logging level at N. +# -DENABLE_386_COMMON_LOG=N sets logging level at N. # -DENABLE_386_DYNAREC_LOG=N sets logging level at N. # -DENABLE_808X_LOG=N sets logging level at N. +# -DENABLE_CPU_LOG=N sets logging level at N. # -DENABLE_FPU_LOG=N sets logging level at N. -# -DENABLE_X86SEG_LOG=N sets logging level at N. -# cpu_new/ logging: -# -DENABLE_386_COMMON_LOG=N sets logging level at N. -# chipset/ logging: -# -DENABLE_NEAT_LOG=N sets logging level at N. # disk/ logging: # -DENABLE_ESDI_AT_LOG=N sets logging level at N. # -DENABLE_ESDI_MCA_LOG=N sets logging level at N. # -DENABLE_HDC_LOG=N sets logging level at N. # -DENABLE_HDD_IMAGE_LOG=N sets logging level at N. # -DENABLE_IDE_LOG=N sets logging level at N. +# -DENABLE_MO_LOG=N sets logging level at N. # -DENABLE_SFF_LOG=N sets logging level at N. # -DENABLE_ST506_AT_LOG=N sets logging level at N. # -DENABLE_ST506_XT_LOG=N sets logging level at N. @@ -109,15 +124,19 @@ STUFF := # -DENABLE_NETWORK_LOG=N sets logging level at N. # -DENABLE_NIC_LOG=N sets logging level at N. # -DENABLE_PCAP_LOG=N sets logging level at N. +# -DENABLE_PCNET_LOG=N sets logging level at N. # -DENABLE_SLIRP_LOG=N sets logging level at N. # -DENABLE_WD_LOG=N sets logging level at N. +# printer/ logging: +# -DENABLE_ESCP_LOG=N sets logging level at N. # scsi/ logging: # -DENABLE_AHA154X_LOG=N sets logging level at N. # -DENABLE_BUSLOGIC_LOG=N sets logging level at N. -# -DENABLE_SCSI_CDROM_LOG=N sets logging level at N. -# -DENABLE_SCSI_DISK_LOG=N sets logging level at N. # -DENABLE_NCR5380_LOG=N sets logging level at N. # -DENABLE_NCR53C8XX_LOG=N sets logging level at N. +# -DENABLE_SCSI_CDROM_LOG=N sets logging level at N. +# -DENABLE_SCSI_DISK_LOG=N sets logging level at N. +# -DENABLE_SPOCK_LOG=N sets logging level at N. # -DENABLE_X54X_LOG=N sets logging level at N. # sound/ logging: # -DENABLE_ADLIB_LOG=N sets logging level at N. @@ -139,15 +158,13 @@ STUFF := # -DENABLE_PGC_LOG=N sets logging level at N. # -DENABLE_S3_VIRGE_LOG=N sets logging level at N. # -DENABLE_VID_TABLE_LOG=N sets logging level at N. +# -DENABLE_VIDEO_LOG=N sets logging level at N. # -DENABLE_VOODOO_LOG=N sets logging level at N. -# -DENABLE_VRAM_DUMP=N sets logging level at N. # win/ logging: # -DENABLE_WIN_LOG=N sets logging level at N. -# -DENABLE_D2D_LOG=N sets logging level at N. -# -DENABLE_DDRAW_LOG=N sets logging level at N. +# -DENABLE_DISCORD_LOG=N sets logging level at N. # -DENABLE_DYNLD_LOG=N sets logging level at N. # -DENABLE_JOYSTICK_LOG=N sets logging level at N. -# -DENABLE_LOG_BREAKPOINT=N sets logging level at N. # -DENABLE_LOG_TOGGLES=N sets logging level at N. # -DENABLE_SDL_LOG=N sets logging level at N. # -DENABLE_SETTINGS_LOG=N sets logging level at N. diff --git a/src/acpi.c b/src/acpi.c index 17c9fe40b..91dc44eae 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -125,8 +125,10 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p) case 0x08: case 0x09: case 0x0a: case 0x0b: /* PMTMR - Power Management Timer Register (IO) */ ret = (dev->regs.timer_val >> shift32) & 0xff; +#ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); +#endif break; case 0x0c: case 0x0d: /* GPSTS - General Purpose Status Register (IO) */ @@ -213,8 +215,10 @@ acpi_reg_read_via(int size, uint16_t addr, void *p) case 0x08: case 0x09: case 0x0a: case 0x0b: /* PMTMR - Power Management Timer Register (IO) */ ret = (dev->regs.timer_val >> shift32) & 0xff; +#ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); +#endif break; case 0x10: case 0x11: case 0x12: case 0x13: /* PCNTRL - Processor Control Register (IO) */ diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index a6f57afbf..891606606 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -27,12 +27,14 @@ #include <86box/cdrom.h> #include <86box/cdrom_image.h> #include <86box/plat.h> +#include <86box/scsi_device.h> #include <86box/sound.h> /* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#undef MSFtoLBA #define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) #define RAW_SECTOR_SIZE 2352 @@ -1171,6 +1173,9 @@ cdrom_close(void) for (i = 0; i < CDROM_NUM; i++) { dev = &cdrom[i]; + if (dev->bus_type == CDROM_BUS_SCSI) + memset(&scsi_devices[dev->scsi_device_id], 0x00, sizeof(scsi_device_t)); + if (dev->close) dev->close(dev->priv); diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index d939762d7..802069978 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -83,14 +83,14 @@ bin_read(void *p, uint8_t *buffer, uint64_t seek, size_t count) return 0; if (fseeko64(tf->file, seek, SEEK_SET) == -1) { -#ifdef ENABLE_cdrom_image_backend_log +#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG cdrom_image_backend_log("CDROM: binary_read failed during seek!\n"); #endif return 0; } if (fread(buffer, count, 1, tf->file) != 1) { -#ifdef ENABLE_cdrom_image_backend_log +#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG cdrom_image_backend_log("CDROM: binary_read failed during read!\n"); #endif return 0; @@ -953,7 +953,7 @@ cdi_load_cue(cd_img_t *cdi, const wchar_t *cuefile) trk.file = track_file_init(filename, &error); } if (error) { -#ifdef ENABLE_cdrom_image_backend_log +#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG cdrom_image_backend_log("CUE: cannot open fille '%ls' in cue sheet!\n", filename); #endif @@ -971,7 +971,7 @@ cdi_load_cue(cd_img_t *cdi, const wchar_t *cuefile) /* Ignored commands. */ success = 1; } else { -#ifdef ENABLE_cdrom_image_backend_log +#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG cdrom_image_backend_log("CUE: unsupported command '%s' in cue sheet!\n", command.c_str()); #endif diff --git a/src/chipset/cs8230.c b/src/chipset/cs8230.c index bb13b353e..a0f64d55c 100644 --- a/src/chipset/cs8230.c +++ b/src/chipset/cs8230.c @@ -142,6 +142,11 @@ static void cs8230_write, NULL, NULL, cs8230); + if (mem_size > 768) { + mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024); + mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000); + } + return cs8230; } diff --git a/src/i82335.c b/src/chipset/i82335.c similarity index 100% rename from src/i82335.c rename to src/chipset/i82335.c diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c new file mode 100644 index 000000000..ca872599d --- /dev/null +++ b/src/chipset/intel_420ex.c @@ -0,0 +1,573 @@ +/* + * 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. + * + * Emulation of Intel 82420EX chipset that acts as both the + * northbridge and the southbridge. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/apm.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/timer.h> +#include <86box/pit.h> +#include <86box/port_92.h> +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/machine.h> +#include <86box/chipset.h> + + +#define MEM_STATE_SHADOW_R 0x01 +#define MEM_STATE_SHADOW_W 0x02 +#define MEM_STATE_SMRAM 0x04 + + +typedef struct +{ + uint8_t id, smram_locked, + regs[256]; + + uint16_t timer_base, + timer_latch; + + double fast_off_period; + + pc_timer_t timer, fast_off_timer; + + apm_t * apm; + port_92_t * port_92; +} i420ex_t; + + +#ifdef ENABLE_I420EX_LOG +int i420ex_do_log = ENABLE_I420EX_LOG; + + +static void +i420ex_log(const char *fmt, ...) +{ + va_list ap; + + if (i420ex_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define i420ex_log(fmt, ...) +#endif + + +static void +i420ex_map(uint32_t addr, uint32_t size, int state) +{ + switch (state & 3) { + case 0: + mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 1: + mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + break; + case 2: + mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + + +static void +i420ex_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) +{ + mem_set_mem_state_smram(smm, addr, size, is_smram); + flushmmucache(); +} + + +static void +i420ex_smram_handler_phase0(void) +{ + /* Disable low extended SMRAM. */ + if (smram[0].size != 0x00000000) { + i420ex_smram_map(0, smram[0].host_base, smram[0].size, 0); + i420ex_smram_map(1, smram[0].host_base, smram[0].size, 0); + + memset(&smram[0], 0x00, sizeof(smram_t)); + mem_mapping_disable(&ram_smram_mapping[0]); + } +} + + +static void +i420ex_smram_handler_phase1(i420ex_t *dev) +{ + uint8_t *regs = (uint8_t *) dev->regs; + + uint32_t base = 0x000a0000; + uint32_t size = 0x00010000; + + switch (regs[0x70] & 0x07) { + case 0: case 1: + default: + base = size = 0x00000000; + break; + case 2: + base = 0x000a0000; + smram[0].host_base = 0x000a0000; + smram[0].ram_base = 0x000a0000; + break; + case 3: + base = 0x000b0000; + smram[0].host_base = 0x000b0000; + smram[0].ram_base = 0x000b0000; + break; + case 4: + base = 0x000c0000; + smram[0].host_base = 0x000c0000; + smram[0].ram_base = 0x000a0000; + break; + case 5: + base = 0x000d0000; + smram[0].host_base = 0x000d0000; + smram[0].ram_base = 0x000a0000; + break; + case 6: + base = 0x000e0000; + smram[0].host_base = 0x000e0000; + smram[0].ram_base = 0x000a0000; + break; + case 7: + base = 0x000f0000; + smram[0].host_base = 0x000f0000; + smram[0].ram_base = 0x000a0000; + break; + } + + smram[0].size = size; + + if (size != 0x00000000) { + mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, 0x00010000); + mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base); + + /* If OSS = 1 and LSS = 0, extended SMRAM is visible outside SMM. */ + i420ex_smram_map(0, base, size, (regs[0x70] & 0x70) == 0x40); + + /* If the register is set accordingly, disable the mapping also in SMM. */ + i420ex_smram_map(1, base, size, !(regs[0x70] & 0x20)); + } +} + + +static void +i420ex_write(int func, int addr, uint8_t val, void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + + if (func > 0) + return; + + if (((addr >= 0x0f) && (addr < 0x4c)) && (addr != 0x40)) + return; + + /* The IB (original) variant of the I420EX has no PCI IRQ steering. */ + if ((addr >= 0x60) && (addr <= 0x63) && (dev->id < 0x03)) + return; + + switch (addr) { + case 0x05: + dev->regs[addr] = (val & 0x01); + break; + + case 0x07: + dev->regs[addr] &= ~(val & 0xf0); + break; + + case 0x40: + dev->regs[addr] = (val & 0x7f); + break; + case 0x44: + dev->regs[addr] = (val & 0x07); + break; + case 0x48: + dev->regs[addr] = (val & 0x3f); +#ifdef USE_420EX_IDE + ide_pri_disable(); + switch (val & 0x03) { + case 0x01: + ide_set_base(0, 0x01f0); + ide_set_side(0, 0x03f6); + ide_pri_enable(); + break; + case 0x02: + ide_set_base(0, 0x0170); + ide_set_side(0, 0x0376); + ide_pri_enable(); + break; + } +#endif + break; + case 0x49: case 0x53: + dev->regs[addr] = (val & 0x1f); + break; + case 0x4c: case 0x51: + case 0x57: + case 0x60: case 0x61: case 0x62: case 0x63: + case 0x64: + case 0x68: case 0x69: + dev->regs[addr] = val; + if (addr == 0x4c) { + dma_alias_remove(); + if (!(val & 0x80)) + dma_alias_set(); + } + break; + case 0x4d: + dev->regs[addr] = (dev->regs[addr] & 0xef) | (val & 0x10); + break; + case 0x4e: + dev->regs[addr] = (val & 0xf7); + break; + case 0x50: + dev->regs[addr] = (val & 0x0f); + break; + case 0x52: + dev->regs[addr] = (val & 0x7f); + break; + case 0x56: + dev->regs[addr] = (val & 0x3e); + break; + case 0x59: /* PAM0 */ + if ((dev->regs[0x59] ^ val) & 0xf0) { + i420ex_map(0xf0000, 0x10000, val >> 4); + shadowbios = (val & 0x10); + } + dev->regs[0x59] = val & 0xf0; + break; + case 0x5a: /* PAM1 */ + if ((dev->regs[0x5a] ^ val) & 0x0f) + i420ex_map(0xc0000, 0x04000, val & 0xf); + if ((dev->regs[0x5a] ^ val) & 0xf0) + i420ex_map(0xc4000, 0x04000, val >> 4); + dev->regs[0x5a] = val; + break; + case 0x5b: /*PAM2 */ + if ((dev->regs[0x5b] ^ val) & 0x0f) + i420ex_map(0xc8000, 0x04000, val & 0xf); + if ((dev->regs[0x5b] ^ val) & 0xf0) + i420ex_map(0xcc000, 0x04000, val >> 4); + dev->regs[0x5b] = val; + break; + case 0x5c: /*PAM3 */ + if ((dev->regs[0x5c] ^ val) & 0x0f) + i420ex_map(0xd0000, 0x04000, val & 0xf); + if ((dev->regs[0x5c] ^ val) & 0xf0) + i420ex_map(0xd4000, 0x04000, val >> 4); + dev->regs[0x5c] = val; + break; + case 0x5d: /* PAM4 */ + if ((dev->regs[0x5d] ^ val) & 0x0f) + i420ex_map(0xd8000, 0x04000, val & 0xf); + if ((dev->regs[0x5d] ^ val) & 0xf0) + i420ex_map(0xdc000, 0x04000, val >> 4); + dev->regs[0x5d] = val; + break; + case 0x5e: /* PAM5 */ + if ((dev->regs[0x5e] ^ val) & 0x0f) + i420ex_map(0xe0000, 0x04000, val & 0xf); + if ((dev->regs[0x5e] ^ val) & 0xf0) + i420ex_map(0xe4000, 0x04000, val >> 4); + dev->regs[0x5e] = val; + break; + case 0x5f: /* PAM6 */ + if ((dev->regs[0x5f] ^ val) & 0x0f) + i420ex_map(0xe8000, 0x04000, val & 0xf); + if ((dev->regs[0x5f] ^ val) & 0xf0) + i420ex_map(0xec000, 0x04000, val >> 4); + dev->regs[0x5f] = val; + break; + case 0x66: case 0x67: + i420ex_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x01), val); + dev->regs[addr] = val & 0x8f; + if (val & 0x80) + pci_set_irq_routing(PCI_INTA + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA + (addr & 0x01), val & 0xf); + break; + case 0x70: /* SMRAM */ + i420ex_smram_handler_phase0(); + if (dev->smram_locked) + dev->regs[0x70] = (dev->regs[0x70] & 0xdf) | (val & 0x20); + else { + dev->regs[0x70] = (dev->regs[0x70] & 0x88) | (val & 0x77); + dev->smram_locked = (val & 0x10); + if (dev->smram_locked) + dev->regs[0x70] &= 0xbf; + } + i420ex_smram_handler_phase1(dev); + break; + case 0xa0: + dev->regs[addr] = val & 0x1f; + apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(dev->regs[0xa2] & 0x80)); + switch ((val & 0x18) >> 3) { + case 0x00: + dev->fast_off_period = PCICLK * 32768.0 * 60000.0; + break; + case 0x01: + default: + dev->fast_off_period = 0.0; + break; + case 0x02: + dev->fast_off_period = PCICLK; + break; + case 0x03: + dev->fast_off_period = PCICLK * 32768.0; + break; + } + cpu_fast_off_count = dev->regs[0xa8] + 1; + timer_disable(&dev->fast_off_timer); + if (dev->fast_off_period != 0.0) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + break; + case 0xa2: + dev->regs[addr] = val & 0xff; + apm_set_do_smi(dev->apm, !!(dev->regs[0xa0] & 0x01) && !!(val & 0x80)); + break; + case 0xaa: + dev->regs[addr] &= (val & 0xff); + break; + case 0xac: case 0xae: + dev->regs[addr] = val & 0xff; + break; + case 0xa4: + dev->regs[addr] = val & 0xfb; + cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | dev->regs[addr]; + break; + case 0xa5: + dev->regs[addr] = val; + cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (dev->regs[addr] << 8); + break; + case 0xa7: + dev->regs[addr] = val & 0xe0; + cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (dev->regs[addr] << 24); + break; + case 0xa8: + dev->regs[addr] = val & 0xff; + cpu_fast_off_val = val; + cpu_fast_off_count = val + 1; + timer_disable(&dev->fast_off_timer); + if (dev->fast_off_period != 0.0) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + break; + } +} + + +static uint8_t +i420ex_read(int func, int addr, void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + uint8_t ret; + + ret = 0xff; + + if (func == 0) + ret = dev->regs[addr]; + + return ret; +} + + +static void +i420ex_reset_hard(void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + + memset(dev->regs, 0, 256); + + dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/ + dev->regs[0x02] = 0x86; dev->regs[0x03] = 0x04; /*82378IB (I420EX)*/ + dev->regs[0x04] = 0x07; + dev->regs[0x07] = 0x02; + dev->regs[0x08] = dev->id; + + dev->regs[0x4c] = 0x4d; + dev->regs[0x4e] = 0x03; + /* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */ + if (cpu_busspeed >= 33333333) + dev->regs[0x50] |= 0x02; + dev->regs[0x51] = 0x80; + dev->regs[0x60] = dev->regs[0x61] = dev->regs[0x62] = dev->regs[0x63] = dev->regs[0x64] = 0x01; + dev->regs[0x66] = 0x80; dev->regs[0x67] = 0x80; + dev->regs[0x69] = 0x02; + dev->regs[0xa0] = 0x08; + dev->regs[0xa8] = 0x0f; + + mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); +} + + +static void +i420ex_apm_out(uint16_t port, uint8_t val, void *p) +{ + i420ex_t *dev = (i420ex_t *) p; + + if (dev->apm->do_smi) + dev->regs[0xaa] |= 0x80; +} + + +static void +i420ex_fast_off_count(void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + + cpu_fast_off_count--; + + if (cpu_fast_off_count == 0) { + smi_line = 1; + dev->regs[0xaa] |= 0x20; + cpu_fast_off_count = dev->regs[0xa8] + 1; + } + + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); +} + + +static void +i420ex_reset(void *p) +{ + i420ex_t *dev = (i420ex_t *) p; + int i; + + for (i = 0; i < 7; i++) + i420ex_write(0, 0x59 + i, 0x00, p); + + for (i = 0; i <= 4; i++) + i420ex_write(0, 0x60 + i, 0x01, p); + + dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */ + dev->smram_locked = 0; + i420ex_write(0, 0x70, 0x00, p); + + mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + i420ex_write(0, 0xa0, 0x08, p); + i420ex_write(0, 0xa2, 0x00, p); + i420ex_write(0, 0xa4, 0x00, p); + i420ex_write(0, 0xa5, 0x00, p); + i420ex_write(0, 0xa6, 0x00, p); + i420ex_write(0, 0xa7, 0x00, p); + i420ex_write(0, 0xa8, 0x0f, p); +} + + +static void +i420ex_close(void *p) +{ + i420ex_t *dev = (i420ex_t *)p; + + free(dev); +} + + +static void +i420ex_speed_changed(void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + int te; + + te = timer_is_enabled(&dev->timer); + + timer_disable(&dev->timer); + if (te) + timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); + + if (dev->id == 0x03) { + te = timer_is_enabled(&dev->fast_off_timer); + + timer_stop(&dev->fast_off_timer); + if (te) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + } +} + + +static void * +i420ex_init(const device_t *info) +{ + i420ex_t *dev = (i420ex_t *) malloc(sizeof(i420ex_t)); + memset(dev, 0, sizeof(i420ex_t)); + + pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev); + + dev->id = info->local; + + timer_add(&dev->fast_off_timer, i420ex_fast_off_count, dev, 0); + + i420ex_reset_hard(dev); + + cpu_fast_off_flags = 0x00000000; + + cpu_fast_off_val = dev->regs[0xa8]; + cpu_fast_off_count = cpu_fast_off_val + 1; + + dev->apm = device_add(&apm_pci_device); + /* APM intercept handler to update 82420EX SMI status on APM SMI. */ + io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, i420ex_apm_out, NULL, NULL, dev); + + dev->port_92 = device_add(&port_92_pci_device); + + dma_alias_set(); + +#ifdef USE_420EX_IDE + device_add(&ide_pci_device); + ide_pri_disable(); +#else + device_add(&ide_pci_2ch_device); +#endif + + return dev; +} + + +const device_t i420ex_device = +{ + "Intel 82420EX", + DEVICE_PCI, + 0x00, + i420ex_init, + i420ex_close, + i420ex_reset, + NULL, + i420ex_speed_changed, + NULL, + NULL +}; diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index aee40c3e5..a65e06dd3 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -6,12 +6,11 @@ * * This file is part of the 86Box distribution. * - * Implementation of the Intel PCISet chips from 420TX to 440FX. + * Implementation of the Intel PCISet chips from 420TX to 440BX. * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * * Copyright 2019,2020 Miran Grca. */ @@ -38,21 +37,22 @@ enum INTEL_430LX, INTEL_430NX, INTEL_430FX, - INTEL_430FX_PB640, INTEL_430HX, INTEL_430VX, INTEL_430TX, INTEL_440FX, - INTEL_440LX, - INTEL_440EX, + INTEL_440LX, + INTEL_440EX, INTEL_440BX, + INTEL_440GX, INTEL_440ZX }; typedef struct { uint8_t pm2_cntrl, max_func, - smram_locked; + smram_locked, max_drb, + drb_default; uint8_t regs[2][256], regs_locked[2][256]; int type; } i4x0_t; @@ -63,16 +63,16 @@ i4x0_map(uint32_t addr, uint32_t size, int state) { switch (state & 3) { case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); break; case 1: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); break; case 2: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); break; case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); break; } flushmmucache_nopc(); @@ -80,55 +80,34 @@ i4x0_map(uint32_t addr, uint32_t size, int state) static void -i4x0_smram_map(int smm, uint32_t addr, uint32_t size, int ram) +i4x0_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) { - int state = ram ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); - - mem_set_mem_state_common(smm, addr, size, state); - flushmmucache(); + mem_set_mem_state_smram(smm, addr, size, is_smram); } static void i4x0_smram_handler_phase0(i4x0_t *dev) { - uint32_t i, n; + uint32_t tom = (mem_size << 10); /* Disable any active mappings. */ - if (dev->type >= INTEL_430FX) { - if (dev->type >= INTEL_440LX) { - /* Disable high extended SMRAM. */ - /* TODO: This area should point to A0000-FFFFF. */ - for (i = 0x100a0000; i < 0x100fffff; i += MEM_GRANULARITY_SIZE) { - /* This is to make sure that if the remaining area is smaller than - or equal to MEM_GRANULARITY_SIZE, we do not change the state of - too much memory. */ - n = ((mem_size << 10) - i); - /* Cap to MEM_GRANULARITY_SIZE if i is either at or beyond the end - of RAM or the remaining area is bigger than MEM_GRANULARITY_SIZE. */ - if ((i >= (mem_size << 10)) || (n > MEM_GRANULARITY_SIZE)) - n = MEM_GRANULARITY_SIZE; - i4x0_smram_map(0, i, n, (i < (mem_size << 10))); - i4x0_smram_map(1, i, n, (i < (mem_size << 10))); - if (n < MEM_GRANULARITY_SIZE) { - i4x0_smram_map(0, i + n, MEM_GRANULARITY_SIZE - n, 0); - i4x0_smram_map(1, i + n, MEM_GRANULARITY_SIZE - n, 0); - } - } + if (smram[0].size != 0x00000000) { + i4x0_smram_map(0, smram[0].host_base, smram[0].size, 0); + i4x0_smram_map(1, smram[0].host_base, smram[0].size, 0); - /* Disable TSEG. */ - i4x0_smram_map(1, ((mem_size << 10) - (1 << 20)), (1 << 20), 1); - } + memset(&smram[0], 0x00, sizeof(smram_t)); + mem_mapping_disable(&ram_smram_mapping[0]); + } - /* Disable low extended SMRAM. */ - i4x0_smram_map(0, 0xa0000, 0x20000, 0); - i4x0_smram_map(1, 0xa0000, 0x20000, 0); - } else { - /* Disable low extended SMRAM. */ - i4x0_smram_map(0, 0xa0000, 0x20000, 0); - i4x0_smram_map(0, (mem_size << 10) - 0x10000, 0x10000, 1); - i4x0_smram_map(1, 0xa0000, 0x20000, 0); - i4x0_smram_map(1, (mem_size << 10) - 0x10000, 0x10000, 1); + if ((dev->type >= INTEL_440BX) && (smram[1].size != 0x00000000)) { + i4x0_smram_map(1, smram[1].host_base, smram[1].size, 0); + + tom -= (1 << 20); + mem_set_mem_state_smm(tom, (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + + memset(&smram[1], 0x00, sizeof(smram_t)); + mem_mapping_disable(&ram_smram_mapping[1]); } } @@ -137,6 +116,7 @@ static void i4x0_smram_handler_phase1(i4x0_t *dev) { uint8_t *regs = (uint8_t *) dev->regs[0]; + uint32_t tom = (mem_size << 10); uint32_t s, base[2] = { 0x000a0000, 0x00020000 }; uint32_t size[2] = { 0, 0 }; @@ -147,26 +127,54 @@ i4x0_smram_handler_phase1(i4x0_t *dev) base[0] = 0x100a0000; size[0] = 0x00060000; } else { - base[0] = 0x000a0000; - size[0] = 0x00020000; + if (((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) && ((regs[0x72] & 0x07) == 0x04)) { + base[0] = 0x000c0000; + size[0] = 0x00010000; + } else { + base[0] = 0x000a0000; + size[0] = 0x00020000; + } } - /* If D_OPEN = 1 and D_LCK = 0, extended SMRAM is visible outside SMM. */ - i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x70) == 0x40)); + if (((regs[0x72] & 0x70) == 0x40) || ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20))) { + smram[0].host_base = base[0]; + smram[0].ram_base = base[0] & 0x000f0000; + smram[0].size = size[0]; - /* If the register is set accordingly, disable the mapping also in SMM. */ - i4x0_smram_map(1, base[0], size[0], ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20))); + mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size[0]); + mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base); + + /* If D_OPEN = 1 and D_LCK = 0, extended SMRAM is visible outside SMM. */ + i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x70) == 0x40)); + + /* If the register is set accordingly, disable the mapping also in SMM. */ + i4x0_smram_map(1, base[0], size[0], ((regs[0x72] & 0x08) && !(regs[0x72] & 0x20))); + } /* TSEG mapping. */ if (dev->type >= INTEL_440BX) { if ((regs[0x72] & 0x08) && (regs[0x73] & 0x01)) { size[1] = (1 << (17 + ((regs[0x73] >> 1) & 0x03))); - base[1] = (mem_size << 10) - size[1]; + tom -= size[1]; + base[1] = tom; } else base[1] = size[1] = 0x00000000; - i4x0_smram_map(1, base[1], size[1], 1); - } else - base[1] = size[1] = 0x00000000; + + if (size[1] != 0x00000000) { + smram[1].host_base = base[1] + (1 << 28); + smram[1].ram_base = base[1]; + smram[1].size = size[1]; + + mem_mapping_set_addr(&ram_smram_mapping[1], smram[1].host_base, smram[1].size); + if (smram[1].ram_base < (1 << 30)) + mem_mapping_set_exec(&ram_smram_mapping[1], ram + smram[1].ram_base); + else + mem_mapping_set_exec(&ram_smram_mapping[1], ram2 + smram[1].ram_base - (1 << 30)); + + mem_set_mem_state_smm(base[1], size[1], MEM_READ_EXTANY | MEM_WRITE_EXTANY); + i4x0_smram_map(1, smram[1].host_base, size[1], 1); + } + } } else { size[0] = 0x00010000; switch (regs[0x72] & 0x03) { @@ -189,20 +197,23 @@ i4x0_smram_handler_phase1(i4x0_t *dev) break; } - if (base[0] != 0x00000000) { + if (((((regs[0x72] & 0x38) == 0x20) || s) || (!(regs[0x72] & 0x10) || s)) && (size[0] != 0x00000000)) { + smram[0].host_base = base[0]; + smram[0].ram_base = base[0]; + smram[0].size = size[0]; + + mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size[0]); + mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base); + /* If OSS = 1 and LSS = 0, extended SMRAM is visible outside SMM. */ - i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x38) == 0x20) || s); - /* If base is on top of memory, this mapping will point to RAM. - TODO: It should actually point to EXTERNAL (with a SMRAM mapping) instead. */ - /* If we are open, not closed, and not locked, point to RAM. */ + i4x0_smram_map(0, base[0], size[0], (((regs[0x72] & 0x38) == 0x20) || s)); /* If the register is set accordingly, disable the mapping also in SMM. */ - i4x0_smram_map(0, base[0], size[0], !(regs[0x72] & 0x10) || s); - /* If base is on top of memory, this mapping will point to RAM. - TODO: It should actually point to EXTERNAL (with a SMRAM mapping) instead. */ - /* If we are not closed, point to RAM. */ + i4x0_smram_map(0, base[0], size[0], (!(regs[0x72] & 0x10) || s)); } } + + flushmmucache(); } @@ -254,11 +265,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x04: /*Command register*/ switch (dev->type) { case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: default: regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42); break; - case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: + case INTEL_430FX: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: regs[0x04] = (regs[0x04] & ~0x02) | (val & 0x02); break; @@ -268,7 +279,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) switch (dev->type) { case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[0x05] = (regs[0x05] & ~0x01) | (val & 0x01); break; } @@ -279,14 +290,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) default: regs[0x07] &= ~(val & 0x70); break; - case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430VX: case INTEL_430TX: + case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: case INTEL_440LX: case INTEL_440EX: regs[0x07] &= ~(val & 0x30); break; case INTEL_440FX: regs[0x07] &= ~(val & 0xf9); break; - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[0x07] &= ~(val & 0xf0); break; } @@ -303,14 +314,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x0f: switch (dev->type) { - case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: + case INTEL_430FX: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: regs[0x0f] = (val & 0x40); break; } break; case 0x12: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[0x12] = (val & 0xc0); i4x0_mask_bar(regs); break; @@ -318,7 +329,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x13: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[0x13] = val; i4x0_mask_bar(regs); break; @@ -326,7 +337,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x2c: case 0x2d: case 0x2e: case 0x2f: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: if (!regs_l[addr]) { regs[addr] = val; regs_l[addr] = 1; @@ -364,7 +375,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430NX: regs[0x50] = (val & 0xe7); break; - case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430FX: regs[0x50] = (val & 0xef); break; case INTEL_430HX: @@ -385,6 +396,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: regs[0x50] = (regs[0x50] & 0x14) | (val & 0xeb); break; + case INTEL_440GX: + /* TODO: Understand it more specifically */ + regs[0x50] = (regs[0x50] & 0x2b) | (val & 0x28); + /*regs[0x50] = (regs[0x50] & 0x2b) | (val & 0xd7);*/ + break; case INTEL_440ZX: regs[0x50] = (regs[0x50] & 0x34) | (val & 0xcb); break; @@ -405,13 +421,16 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: case INTEL_440ZX: regs[0x51] = (regs[0x50] & 0x70) | (val & 0x8f); break; + case INTEL_440GX: + regs[0x51] = (regs[0x50] & 0x88) | (val & 0x08); + /*regs[0x51] = (regs[0x50] & 0x88) | (val & 0x77);*/ + break; } break; case 0x52: /* Cache Control Register */ switch (dev->type) { case INTEL_420TX: case INTEL_420ZX: - case INTEL_430LX: - case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430LX: case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: default: regs[0x52] = (val & 0xfb); @@ -423,7 +442,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440LX: regs[0x52] = (val & 0xd0); break; - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[0x52] = val & 0x07; break; } @@ -443,7 +462,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440LX: regs[0x53] = val & 0x0a; break; - case INTEL_440EX: case INTEL_440BX: + case INTEL_440EX: case INTEL_440BX: case INTEL_440GX: /* Not applicable to 440ZX as that does not support ECC. */ regs[0x53] = val; break; @@ -506,8 +525,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430NX: case INTEL_440EX: regs[0x57] = val; break; - case INTEL_430FX: case INTEL_430FX_PB640: - case INTEL_430HX: case INTEL_430VX: + case INTEL_430FX: case INTEL_430HX: + case INTEL_430VX: regs[0x57] = val & 0xcf; break; case INTEL_430TX: @@ -519,7 +538,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440LX: regs[0x57] = val & 0x11; break; - case INTEL_440BX: + case INTEL_440BX: case INTEL_440GX: regs[0x57] = val & 0x3f; break; case INTEL_440ZX: @@ -537,8 +556,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: case INTEL_440ZX: regs[0x58] = val & 0x03; break; - case INTEL_430FX: case INTEL_430FX_PB640: - case INTEL_440FX: + case INTEL_430FX: case INTEL_440FX: regs[0x58] = val & 0x7f; break; case INTEL_430HX: case INTEL_430VX: @@ -619,8 +637,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) default: regs[addr] = val; break; - case INTEL_430FX: case INTEL_430FX_PB640: - case INTEL_430VX: + case INTEL_430FX: case INTEL_430VX: regs[addr] = val & 0x3f; break; case INTEL_430TX: @@ -635,6 +652,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: + case INTEL_440GX: case INTEL_440BX: case INTEL_440ZX: regs[addr] = val; break; @@ -650,7 +668,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) switch (dev->type) { case INTEL_430NX: case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: - case INTEL_440EX: + case INTEL_440EX: case INTEL_440GX: case INTEL_440BX: case INTEL_440ZX: regs[addr] = val; break; @@ -661,7 +679,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430NX: case INTEL_430HX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[addr] = val; break; case INTEL_430VX: @@ -678,7 +697,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430VX: case INTEL_430TX: regs[0x68] = val; break; - case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430FX: regs[0x68] = val & 0x1f; break; case INTEL_440FX: case INTEL_440LX: @@ -688,6 +707,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: regs[0x68] = (regs[0x68] & 0x38) | (val & 0xc7); break; + case INTEL_440GX: + regs[0x68] = (regs[0x68] & 0xc0) | (val & 0x3f); + break; case INTEL_440ZX: regs[0x68] = (regs[0x68] & 0x3f) | (val & 0xc0); break; @@ -697,6 +719,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) switch (dev->type) { case INTEL_430NX: case INTEL_440BX: + case INTEL_440GX: regs[0x69] = val; break; case INTEL_430VX: @@ -713,6 +736,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440LX: case INTEL_440EX: case INTEL_440BX: + case INTEL_440GX: regs[addr] = val; break; case INTEL_440ZX: @@ -728,6 +752,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440LX: case INTEL_440EX: case INTEL_440BX: + case INTEL_440GX: regs[addr] = val; break; case INTEL_440ZX: @@ -784,7 +809,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) if (dev->smram_locked) regs[0x72] = (regs[0x72] & 0xdf) | (val & 0x20); else { - regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78); + if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) + regs[0x72] = (regs[0x72] & 0x80) | (val & 0x7f); + else + regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78); dev->smram_locked = (val & 0x10); if (dev->smram_locked) regs[0x72] &= 0xbf; @@ -796,7 +824,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x72] = (regs[0x72] & 0xc0) | (val & 0x3f); dev->smram_locked = (val & 0x08); if (dev->smram_locked) - regs[0x72] &= 0xef; + regs[0x72] &= 0xdf; } } i4x0_smram_handler_phase1(dev); @@ -806,7 +834,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430VX: regs[0x73] = val & 0x03; break; - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: if (!dev->smram_locked) { i4x0_smram_handler_phase0(dev); regs[0x73] = (regs[0x72] & 0x38) | (val & 0xc7); @@ -826,13 +854,13 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x75: case 0x76: case 0x7b: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[addr] = val; } break; case 0x77: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[0x77] = val & 0x03; } break; @@ -841,7 +869,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430VX: regs[0x78] = val & 0xcf; break; - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[0x78] = val & 0x0f; break; } @@ -854,14 +882,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) if (val & 0x40) io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); break; - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[0x79] = val; break; } break; case 0x7a: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: case INTEL_440ZX: regs[0x7a] = (regs[0x7a] & 0x0a) | (val & 0xf5); io_removehandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); if (val & 0x40) @@ -875,7 +903,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430LX: case INTEL_430NX: regs[0x7c] = val & 0x8f; break; - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0x7c] = val & 0x1f; break; } @@ -911,7 +940,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440LX: regs[0x80] = val & 0x08; break; - case INTEL_440EX: + case INTEL_440EX: case INTEL_440GX: regs[0x80] = val & 0x18; break; case INTEL_440BX: case INTEL_440ZX: @@ -923,7 +952,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) switch (dev->type) { case INTEL_430HX: case INTEL_440BX: case INTEL_440FX: case INTEL_440LX: - case INTEL_440EX: + case INTEL_440EX: case INTEL_440GX: /* Not applicable on 82443ZX. */ regs[0x91] &= ~(val & 0x11); break; @@ -932,7 +961,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x92: switch (dev->type) { case INTEL_440LX: case INTEL_440EX: - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0x92] &= ~(val & 0x1f); break; } @@ -956,7 +986,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0xb0: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0xb0] = (val & 0x80); break; } @@ -969,11 +1000,15 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: case INTEL_440ZX: regs[0xb1] = (val & 0xa0); break; + case INTEL_440GX: + regs[0xb1] = (val & 0xa2); + break; } break; case 0xb4: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0xb4] = (val & 0x3f); i4x0_mask_bar(regs); break; @@ -981,7 +1016,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0xb9: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0xb9] = (val & 0xf0); break; } @@ -989,7 +1025,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0xba: case 0xbb: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[addr] = val; break; } @@ -997,7 +1034,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0xbc: switch (dev->type) { - case INTEL_440EX: + case INTEL_440EX: case INTEL_440GX: regs[addr] = (val & 0xf8); break; } @@ -1005,7 +1042,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0xbd: switch (dev->type) { - case INTEL_440EX: + case INTEL_440EX: case INTEL_440GX: regs[addr] = (val & 0xf8); break; } @@ -1013,14 +1050,15 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[addr] = val; break; } break; case 0xca: switch (dev->type) { - case INTEL_440BX: + case INTEL_440BX: case INTEL_440GX: regs[addr] = val; break; case INTEL_440ZX: @@ -1030,7 +1068,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0xcb: switch (dev->type) { - case INTEL_440BX: + case INTEL_440BX: case INTEL_440GX: regs[addr] = val; break; case INTEL_440ZX: @@ -1040,7 +1078,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0xcc: switch (dev->type) { - case INTEL_440BX: + case INTEL_440BX: case INTEL_440GX: regs[0xcc] = (val & 0x7f); break; case INTEL_440ZX: @@ -1051,7 +1089,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: if (!regs_l[addr]) regs[addr] = val; break; @@ -1059,7 +1098,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0xe5: case 0xed: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: if (!regs_l[addr]) regs[addr] = (val & 0x3f); break; @@ -1067,7 +1107,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0xe7: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0xe7] = 0x80; for (i = 0; i < 16; i++) regs_l[0xe0 + i] = !!(val & 0x80); @@ -1079,14 +1120,16 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0xf0: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0xf0] = (val & 0xc0); break; } break; case 0xf1: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0xf1] = (val & 0x03); break; } @@ -1097,18 +1140,22 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: case INTEL_440ZX: regs[0x04] = (val & 0x1f); break; + case INTEL_440GX: + regs[0x04] = val; } break; case 0x05: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0x05] = (val & 0x01); break; } break; case 0x0d: case 0x1b: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[addr] = (val & 0xf8); break; } @@ -1117,7 +1164,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x21: case 0x23: case 0x25: case 0x27: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[addr] = val; break; } @@ -1126,21 +1174,24 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x20: case 0x22: case 0x24: case 0x26: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[addr] = (val & 0xf0); break; } break; case 0x1f: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0x1f] &= ~(val & 0xf0); break; } break; case 0x3e: switch (dev->type) { - case INTEL_440BX: case INTEL_440ZX: + case INTEL_440BX: case INTEL_440GX: + case INTEL_440ZX: regs[0x3e] = (val & 0xed); break; } @@ -1184,10 +1235,16 @@ i4x0_reset(void *priv) for (i = 0; i < 6; i++) i4x0_write(0, 0x5a + i, 0x00, priv); - if (dev->type >= INTEL_430FX) + for (i = 0; i <= dev->max_drb; i++) + i4x0_write(0, 0x60 + i, dev->drb_default, priv); + + if (dev->type >= INTEL_430FX) { + dev->regs[0][0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */ i4x0_write(0, 0x72, 0x02, priv); - else + } else { + dev->regs[0][0x72] &= 0xf7; /* Forcibly unlock the SMRAM register. */ i4x0_write(0, 0x72, 0x00, priv); + } if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) { for (i = 0; i <= dev->max_func; i++) @@ -1217,9 +1274,6 @@ static void regs = (uint8_t *) dev->regs[0]; - // This is off by default and has to be moved to the appropriate register handling. - // io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); - regs[0x00] = 0x86; regs[0x01] = 0x80; /*Intel*/ switch (dev->type) { @@ -1250,6 +1304,8 @@ static void regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; + dev->max_drb = 5; + dev->drb_default = 0x02; break; case INTEL_430LX: regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */ @@ -1266,6 +1322,8 @@ static void regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; + dev->max_drb = 5; + dev->drb_default = 0x02; break; case INTEL_430NX: regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */ @@ -1284,12 +1342,12 @@ static void regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + dev->max_drb = 7; + dev->drb_default = 0x02; break; - case INTEL_430FX_PB640: - regs[0x08] = 0x02; - /* FALLTHROUGH */ case INTEL_430FX: regs[0x02] = 0x2d; regs[0x03] = 0x12; /* SB82437FX-66 */ + regs[0x08] = (info->local >> 8) & 0xff; regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ if (cpu_busspeed <= 50000000) regs[0x57] |= 0x01; @@ -1299,6 +1357,8 @@ static void regs[0x57] |= 0x03; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02; regs[0x72] = 0x02; + dev->max_drb = 4; + dev->drb_default = 0x02; break; case INTEL_430HX: regs[0x02] = 0x50; regs[0x03] = 0x12; /* 82439HX */ @@ -1311,6 +1371,8 @@ static void regs[0x57] |= 0x03; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_default = 0x02; break; case INTEL_430VX: regs[0x02] = 0x30; regs[0x03] = 0x70; /* 82437VX */ @@ -1330,6 +1392,8 @@ static void regs[0x72] = 0x02; regs[0x74] = 0x0e; regs[0x78] = 0x23; + dev->max_drb = 4; + dev->drb_default = 0x02; break; case INTEL_430TX: regs[0x02] = 0x00; regs[0x03] = 0x71; /* 82439TX */ @@ -1345,6 +1409,8 @@ static void regs[0x67] |= 0x80; regs[0x70] = 0x20; regs[0x72] = 0x02; + dev->max_drb = 5; + dev->drb_default = 0x02; break; case INTEL_440FX: regs[0x02] = 0x37; regs[0x03] = 0x12; /* 82441FX */ @@ -1359,6 +1425,8 @@ static void regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; regs[0x71] = 0x10; regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_default = 0x02; break; case INTEL_440LX: dev->max_func = 1; @@ -1381,6 +1449,8 @@ static void regs[0xa4] = 0x03; regs[0xa5] = 0x02; regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_default = 0x01; break; case INTEL_440EX: dev->max_func = 1; @@ -1403,6 +1473,8 @@ static void regs[0xa4] = 0x03; regs[0xa5] = 0x02; regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_default = 0x01; break; case INTEL_440BX: case INTEL_440ZX: regs[0x7a] = (info->local >> 8) & 0xff; @@ -1429,6 +1501,33 @@ static void regs[0xa4] = 0x03; regs[0xa5] = 0x02; regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_default = 0x01; + break; + case INTEL_440GX: + regs[0x7a] = (info->local >> 8) & 0xff; + dev->max_func = (regs[0x7a] & 0x02) ? 0 : 1; + + regs[0x02] = 0xa0; regs[0x03] = 0x71; /* 82443GX */ + regs[0x06] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0x08] = 0x02; + regs[0x10] = 0x08; + regs[0x34] = (regs[0x7a] & 0x02) ? 0x00 : 0xa0; + regs[0x51] |= 0x20; + regs[0x57] = 0x28; + regs[0x58] = 0x03; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x72] = 0x02; + regs[0x73] = 0x38; + regs[0x7b] = 0x38; + regs[0x90] = 0x80; + regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; + regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_default = 0x01; break; } @@ -1463,11 +1562,15 @@ static void regs[0x24] = 0xf0; regs[0x25] = 0xff; } - if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) { + if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440GX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) { regs = (uint8_t *) dev->regs[1]; regs[0x00] = 0x86; regs[0x01] = 0x80; /* Intel */ + if(dev->type != INTEL_440GX){ regs[0x02] = 0x91; regs[0x03] = 0x71; /* 82443BX */ + } else { + regs[0x02] = 0xa1; regs[0x03] = 0x71; /* 82443GX (They seem to share the same deal*/ + } regs[0x06] = 0x20; regs[0x07] = 0x02; regs[0x08] = 0x02; regs[0x0a] = 0x04; regs[0x0b] = 0x06; @@ -1560,11 +1663,11 @@ const device_t i430fx_device = }; -const device_t i430fx_pb640_device = +const device_t i430fx_rev02_device = { - "Intel SB82437FX-66 (PB640)", + "Intel SB82437FX-66 (Rev. 02)", DEVICE_PCI, - INTEL_430FX_PB640, + 0x0200 | INTEL_430FX, i4x0_init, i4x0_close, i4x0_reset, @@ -1677,6 +1780,19 @@ const device_t i440bx_device = NULL }; +const device_t i440gx_device = +{ + "Intel 82443GX", + DEVICE_PCI, + 0x8000 | INTEL_440GX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; const device_t i440zx_device = { diff --git a/src/intel_piix.c b/src/chipset/intel_piix.c similarity index 96% rename from src/intel_piix.c rename to src/chipset/intel_piix.c index 34ab4eb3b..43ad5abaf 100644 --- a/src/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -13,10 +13,8 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. */ #include @@ -53,7 +51,7 @@ #include <86box/zip.h> #include <86box/machine.h> #include <86box/smbus_piix4.h> -#include <86box/piix.h> +#include <86box/chipset.h> typedef struct @@ -281,10 +279,10 @@ piix_write(int func, int addr, uint8_t val, void *priv) /* Return on unsupported function. */ if (dev->max_func > 0) { - if (func > dev->max_func) + if (func > dev->max_func) return; } else { - if (func > 1) + if (func > 1) return; } @@ -480,11 +478,11 @@ piix_write(int func, int addr, uint8_t val, void *priv) apm_set_do_smi(dev->apm, !!(fregs[0xa0] & 0x01) && !!(val & 0x80)); } break; - case 0xaa: case 0xac: case 0xae: + case 0xac: case 0xae: if (dev->type < 4) fregs[addr] = val & 0xff; break; - case 0xa3: case 0xab: + case 0xa3: if (dev->type == 3) fregs[addr] = val & 0x01; break; @@ -524,6 +522,14 @@ piix_write(int func, int addr, uint8_t val, void *priv) timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); } break; + case 0xaa: + if (dev->type < 4) + fregs[addr] &= val; + break; + case 0xab: + if (dev->type == 3) + fregs[addr] &= (val & 0x01); + break; case 0xb0: if (dev->type == 4) fregs[addr] = (fregs[addr] & 0x8c) | (val & 0x73); @@ -755,16 +761,16 @@ piix_write(int func, int addr, uint8_t val, void *priv) fregs[addr] = val & 0x01; break; case 0x6a: - if (dev->type == 4) + if (dev->type <= 4) fregs[0x6a] = val & 0x01; break; case 0xc0: - if (dev->type == 4) - fregs[0xc0] = val; + if (dev->type <= 4) + fregs[0xc0] = (fregs[0xc0] & ~(val & 0xbf)) | (val & 0x20); break; case 0xc1: - if (dev->type == 4) - fregs[0xc1] = val & 0xbf; + if (dev->type <= 4) + fregs[0xc1] &= ~val; break; case 0xff: if (dev->type == 4) { @@ -873,6 +879,9 @@ piix_read(int func, int addr, void *priv) piix_t *dev = (piix_t *) priv; uint8_t ret = 0xff, *fregs; + if ((dev->type == 3) && (func == 2) && (dev->max_func == 1) && (addr >= 0x40)) + ret = 0x00; + /* Return on unsupported function. */ if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) { fregs = (uint8_t *) dev->regs[func]; @@ -995,6 +1004,8 @@ piix_reset_hard(piix_t *dev) fregs[0x69] = 0x02; if ((dev->type == 1) && (dev->rev != 2)) fregs[0x6a] = 0x04; + else if (dev->type == 3) + fregs[0x6a] = 0x10; fregs[0x70] = (dev->type < 4) ? 0x80 : 0x00; fregs[0x71] = (dev->type < 3) ? 0x80 : 0x00; if (dev->type <= 4) { @@ -1065,7 +1076,7 @@ piix_reset_hard(piix_t *dev) fregs[0xc1] = 0x20; fregs[0xff] = (dev->type > 3) ? 0x10 : 0x00; } - dev->max_func = 1; /* It starts with USB disabled, then enables it. */ + dev->max_func = 2; /* It starts with USB disabled, then enables it. */ } /* Function 3: Power Management */ @@ -1149,6 +1160,13 @@ piix_reset(void *p) piix_write(0, 0xa7, 0x00, p); piix_write(0, 0xa8, 0x0f, p); } + + piix_write(1, 0x04, 0x00, p); + piix_write(1, 0x41, 0x00, p); + piix_write(1, 0x43, 0x00, p); + + ide_pri_disable(); + ide_sec_disable(); } @@ -1161,6 +1179,20 @@ piix_close(void *p) } +static void +piix_speed_changed(void *priv) +{ + piix_t *dev = (piix_t *) priv; + int te; + + te = timer_is_enabled(&dev->fast_off_timer); + + timer_stop(&dev->fast_off_timer); + if (te) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); +} + + static void *piix_init(const device_t *info) { @@ -1300,7 +1332,7 @@ const device_t piix_device = piix_close, piix_reset, NULL, - NULL, + piix_speed_changed, NULL, NULL }; @@ -1314,7 +1346,7 @@ const device_t piix_rev02_device = piix_close, piix_reset, NULL, - NULL, + piix_speed_changed, NULL, NULL }; @@ -1328,7 +1360,7 @@ const device_t piix3_device = piix_close, piix_reset, NULL, - NULL, + piix_speed_changed, NULL, NULL }; @@ -1342,7 +1374,7 @@ const device_t piix4_device = piix_close, piix_reset, NULL, - NULL, + piix_speed_changed, NULL, NULL }; @@ -1356,7 +1388,7 @@ const device_t piix4e_device = piix_close, piix_reset, NULL, - NULL, + piix_speed_changed, NULL, NULL }; @@ -1370,7 +1402,7 @@ const device_t slc90e66_device = piix_close, piix_reset, NULL, - NULL, + piix_speed_changed, NULL, NULL }; diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c new file mode 100644 index 000000000..370bed928 --- /dev/null +++ b/src/chipset/intel_sio.c @@ -0,0 +1,573 @@ +/* + * 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. + * + * Emulation of Intel System I/O PCI chip. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/apm.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/timer.h> +#include <86box/pit.h> +#include <86box/port_92.h> +#include <86box/machine.h> +#include <86box/chipset.h> + + +typedef struct +{ + uint8_t id, + regs[256]; + + uint16_t timer_base, + timer_latch; + + double fast_off_period; + + pc_timer_t timer, fast_off_timer; + + apm_t * apm; + port_92_t * port_92; +} sio_t; + + +#ifdef ENABLE_SIO_LOG +int sio_do_log = ENABLE_SIO_LOG; + + +static void +sio_log(const char *fmt, ...) +{ + va_list ap; + + if (sio_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define sio_log(fmt, ...) +#endif + + +static void +sio_timer_write(uint16_t addr, uint8_t val, void *priv) +{ + sio_t *dev = (sio_t *) priv; + + if (!(addr & 0x0002)) { + if (addr & 0x0001) + dev->timer_latch = (dev->timer_latch & 0xff) | (val << 8); + else + dev->timer_latch = (dev->timer_latch & 0xff00) | val; + + timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); + } +} + + +static void +sio_timer_writew(uint16_t addr, uint16_t val, void *priv) +{ + sio_t *dev = (sio_t *) priv; + + if (!(addr & 0x0002)) { + dev->timer_latch = val; + + timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); + } +} + + +static uint8_t +sio_timer_read(uint16_t addr, void *priv) +{ + sio_t *dev = (sio_t *) priv; + uint16_t sio_timer_latch; + uint8_t ret = 0xff; + + if (!(addr & 0x0002)) { + sub_cycles((int)(PITCONST >> 32)); + + sio_timer_latch = timer_get_remaining_us(&dev->timer); + + if (addr & 0x0001) + ret = sio_timer_latch >> 8; + else + ret = sio_timer_latch & 0xff; + } + + return ret; +} + + +static uint16_t +sio_timer_readw(uint16_t addr, void *priv) +{ + sio_t *dev = (sio_t *) priv; + uint16_t ret = 0xffff; + + if (!(addr & 0x0002)) { + sub_cycles((int)(PITCONST >> 32)); + + ret = timer_get_remaining_us(&dev->timer); + } + + return ret; +} + + +static void +sio_write(int func, int addr, uint8_t val, void *priv) +{ + sio_t *dev = (sio_t *) priv; + uint8_t old; + + if (func > 0) + return; + + if (((addr >= 0x0f) && (addr < 0x4c)) && (addr != 0x40)) + return; + + /* The IB (original) variant of the SIO has no PCI IRQ steering. */ + if ((addr >= 0x60) && (addr <= 0x63) && (dev->id < 0x03)) + return; + + old = dev->regs[addr]; + + switch (addr) { + case 0x04: /*Command register*/ + if (dev->id == 0x03) + dev->regs[addr] = (dev->regs[addr] & 0xf7) | (val & 0x08); + break; + + case 0x07: + dev->regs[addr] &= ~(val & 0x38); + break; + + case 0x40: + if (dev->id == 0x03) { + dev->regs[addr] = (val & 0x7f); + + if (!((val ^ old) & 0x40)) + return; + + dma_alias_remove(); + if (!(val & 0x40)) + dma_alias_set(); + } else + dev->regs[addr] = (val & 0x3f); + break; + case 0x41: case 0x44: + dev->regs[addr] = (val & 0x1f); + break; + case 0x42: + if (dev->id == 0x03) + dev->regs[addr] = val; + else + dev->regs[addr] = (val & 0x77); + break; + case 0x43: + if (dev->id == 0x03) + dev->regs[addr] = (val & 0x01); + break; + case 0x45: case 0x46: + case 0x47: case 0x48: + case 0x49: case 0x4a: + case 0x4b: case 0x4e: + case 0x54: case 0x55: + case 0x56: + dev->regs[addr] = val; + break; + case 0x4c: case 0x4d: + dev->regs[addr] = (val & 0x7f); + break; + case 0x4f: + dev->regs[addr] = val; + + if (!((val ^ old) & 0x40)) + return; + + port_92_remove(dev->port_92); + if (val & 0x40) + port_92_add(dev->port_92); + break; + case 0x57: + dev->regs[addr] = val; + + dma_remove_sg(); + dma_set_sg_base(val); + break; + case 0x60: case 0x61: case 0x62: case 0x63: + if (dev->id == 0x03) { + sio_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x03), val); + dev->regs[addr] = val & 0x8f; + if (val & 0x80) + pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf); + } + break; + case 0x80: + case 0x81: + if (addr == 0x80) + dev->regs[addr] = val & 0xfd; + else + dev->regs[addr] = val; + + if (dev->timer_base & 0x01) { + io_removehandler(dev->timer_base & 0xfffc, 0x0004, + sio_timer_read, sio_timer_readw, NULL, + sio_timer_write, sio_timer_writew, NULL, dev); + } + dev->timer_base = (dev->regs[0x81] << 8) | (dev->regs[0x80] & 0xfd); + if (dev->timer_base & 0x01) { + io_sethandler(dev->timer_base & 0xfffc, 0x0004, + sio_timer_read, sio_timer_readw, NULL, + sio_timer_write, sio_timer_writew, NULL, dev); + } + break; + case 0xa0: + if (dev->id == 0x03) { + dev->regs[addr] = val & 0x1f; + apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(dev->regs[0xa2] & 0x80)); + switch ((val & 0x18) >> 3) { + case 0x00: + dev->fast_off_period = PCICLK * 32768.0 * 60000.0; + break; + case 0x01: + default: + dev->fast_off_period = 0.0; + break; + case 0x02: + dev->fast_off_period = PCICLK; + break; + case 0x03: + dev->fast_off_period = PCICLK * 32768.0; + break; + } + cpu_fast_off_count = dev->regs[0xa8] + 1; + timer_disable(&dev->fast_off_timer); + if (dev->fast_off_period != 0.0) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + } + break; + case 0xa2: + if (dev->id == 0x03) { + dev->regs[addr] = val & 0xff; + apm_set_do_smi(dev->apm, !!(dev->regs[0xa0] & 0x01) && !!(val & 0x80)); + } + break; + case 0xaa: + if (dev->id == 0x03) + dev->regs[addr] &= (val & 0xff); + break; + case 0xac: case 0xae: + if (dev->id == 0x03) + dev->regs[addr] = val & 0xff; + break; + case 0xa4: + if (dev->id == 0x03) { + dev->regs[addr] = val & 0xfb; + cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | dev->regs[addr]; + } + break; + case 0xa5: + if (dev->id == 0x03) { + dev->regs[addr] = val & 0xff; + cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (dev->regs[addr] << 8); + } + break; + case 0xa7: + if (dev->id == 0x03) { + dev->regs[addr] = val & 0xa0; + cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (dev->regs[addr] << 24); + } + break; + case 0xa8: + dev->regs[addr] = val & 0xff; + cpu_fast_off_val = val; + cpu_fast_off_count = val + 1; + timer_disable(&dev->fast_off_timer); + if (dev->fast_off_period != 0.0) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + break; + } +} + + +static uint8_t +sio_read(int func, int addr, void *priv) +{ + sio_t *dev = (sio_t *) priv; + uint8_t ret; + + ret = 0xff; + + if (func == 0) + ret = dev->regs[addr]; + + return ret; +} + + +static void +sio_config_write(uint16_t addr, uint8_t val, void *priv) +{ +} + + +static uint8_t +sio_config_read(uint16_t port, void *priv) +{ + uint8_t ret = 0x00; + + switch (port & 0x000f) { + case 3: + ret = 0xff; + break; + case 5: + ret = 0xd3; + + switch (cpu_pci_speed) { + case 20000000: + ret |= 0x0c; + break; + case 25000000: + default: + ret |= 0x00; + break; + case 30000000: + ret |= 0x08; + break; + case 33333333: + ret |= 0x04; + break; + } + break; + } + + return ret; +} + + +static void +sio_reset_hard(void *priv) +{ + sio_t *dev = (sio_t *) priv; + + memset(dev->regs, 0, 256); + + dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/ + dev->regs[0x02] = 0x84; dev->regs[0x03] = 0x04; /*82378IB (SIO)*/ + dev->regs[0x04] = 0x07; + dev->regs[0x07] = 0x02; + dev->regs[0x08] = dev->id; + + dev->regs[0x40] = 0x20; dev->regs[0x41] = 0x00; + dev->regs[0x42] = 0x04; + dev->regs[0x45] = 0x10; dev->regs[0x46] = 0x0f; + dev->regs[0x48] = 0x01; + dev->regs[0x4a] = 0x10; dev->regs[0x4b] = 0x0f; + dev->regs[0x4c] = 0x56; dev->regs[0x4d] = 0x40; + dev->regs[0x4e] = 0x07; dev->regs[0x4f] = 0x4f; + dev->regs[0x57] = 0x04; + if (dev->id == 0x03) { + dev->regs[0x60] = 0x80; dev->regs[0x61] = 0x80; dev->regs[0x62] = 0x80; dev->regs[0x63] = 0x80; + } + dev->regs[0x80] = 0x78; + if (dev->id == 0x03) { + dev->regs[0xa0] = 0x08; + dev->regs[0xa8] = 0x0f; + } + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + + if (dev->timer_base & 0x0001) { + io_removehandler(dev->timer_base & 0xfffc, 0x0004, + sio_timer_read, sio_timer_readw, NULL, + sio_timer_write, sio_timer_writew, NULL, dev); + } + + dev->timer_base = 0x0078; +} + + +static void +sio_apm_out(uint16_t port, uint8_t val, void *p) +{ + sio_t *dev = (sio_t *) p; + + if (dev->apm->do_smi) + dev->regs[0xaa] |= 0x80; +} + + +static void +sio_fast_off_count(void *priv) +{ + sio_t *dev = (sio_t *) priv; + + cpu_fast_off_count--; + + if (cpu_fast_off_count == 0) { + smi_line = 1; + dev->regs[0xaa] |= 0x20; + cpu_fast_off_count = dev->regs[0xa8] + 1; + } + + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); +} + + +static void +sio_reset(void *p) +{ + sio_t *dev = (sio_t *) p; + + sio_write(0, 0x57, 0x04, p); + + dma_set_params(1, 0xffffffff); + + if (dev->id == 0x03) { + sio_write(0, 0xa0, 0x08, p); + sio_write(0, 0xa2, 0x00, p); + sio_write(0, 0xa4, 0x00, p); + sio_write(0, 0xa5, 0x00, p); + sio_write(0, 0xa6, 0x00, p); + sio_write(0, 0xa7, 0x00, p); + sio_write(0, 0xa8, 0x0f, p); + } +} + + +static void +sio_close(void *p) +{ + sio_t *dev = (sio_t *)p; + + free(dev); +} + + +static void +sio_speed_changed(void *priv) +{ + sio_t *dev = (sio_t *) priv; + int te; + + te = timer_is_enabled(&dev->timer); + + timer_disable(&dev->timer); + if (te) + timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); + + if (dev->id == 0x03) { + te = timer_is_enabled(&dev->fast_off_timer); + + timer_stop(&dev->fast_off_timer); + if (te) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + } +} + + +static void * +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); + + dev->id = info->local; + + if (dev->id == 0x03) + timer_add(&dev->fast_off_timer, sio_fast_off_count, dev, 0); + + sio_reset_hard(dev); + + cpu_fast_off_flags = 0x00000000; + + if (dev->id == 0x03) { + cpu_fast_off_val = dev->regs[0xa8]; + cpu_fast_off_count = cpu_fast_off_val + 1; + } else + cpu_fast_off_val = cpu_fast_off_count = 0; + + if (dev->id == 0x03) { + dev->apm = device_add(&apm_pci_device); + /* APM intercept handler to update 82378ZB SMI status on APM SMI. */ + io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, sio_apm_out, NULL, NULL, dev); + } + + dev->port_92 = device_add(&port_92_pci_device); + + dma_set_sg_base(0x04); + dma_set_params(1, 0xffffffff); + dma_ext_mode_init(); + dma_high_page_init(); + + if (dev->id == 0x03) + dma_alias_set(); + + io_sethandler(0x0073, 0x0001, + sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, dev); + io_sethandler(0x0075, 0x0001, + sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, dev); + + timer_add(&dev->timer, NULL, NULL, 0); + + return dev; +} + + +const device_t sio_device = +{ + "Intel 82378IB (SIO)", + DEVICE_PCI, + 0x00, + sio_init, + sio_close, + sio_reset, + NULL, + sio_speed_changed, + NULL, + NULL +}; + + +const device_t sio_zb_device = +{ + "Intel 82378ZB (SIO)", + DEVICE_PCI, + 0x03, + sio_init, + sio_close, + sio_reset, + NULL, + sio_speed_changed, + NULL, + NULL +}; diff --git a/src/mcr.c b/src/chipset/mcr.c similarity index 100% rename from src/mcr.c rename to src/chipset/mcr.c diff --git a/src/chipset/rabbit.c b/src/chipset/rabbit.c deleted file mode 100644 index 3e637746e..000000000 --- a/src/chipset/rabbit.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include <86box/timer.h> -#include <86box/io.h> -#include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/mem.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/chipset.h> - - -typedef struct -{ - uint8_t cur_reg, - regs[16]; -} rabbit_t; - -/* -static void -rabbit_recalcmapping(rabbit_t *dev) -{ - uint32_t base; - uint32_t i, shflags = 0; - - shadowbios = 0; - shadowbios_write = 0; - - for (i = 0; i < 8; i++) { - base = 0xc0000 + (i << 15); - - if (dev->regs[0x00] & 0x08) { - shadowbios |= (base >= 0xe0000) && (dev->regs[0x02] & 0x80); - shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40); - shflags = (dev->regs[0x00] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - shflags |= (dev->regs[0x00] & 0x08) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL; - mem_set_mem_state(base, 0x8000, shflags); - } else - mem_set_mem_state(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTERNAL); - } - - flushmmucache(); -} -*/ - -static void -rabbit_write(uint16_t addr, uint8_t val, void *priv) -{ - rabbit_t *dev = (rabbit_t *) priv; - - switch (addr) { - case 0x22: - dev->cur_reg = val; - break; - case 0x23: - dev->regs[dev->cur_reg] = val; - /* - if (dev->cur_reg == 0x00) { - rabbit_recalcmapping(dev); - } - */ - break; - } -} - - -static uint8_t -rabbit_read(uint16_t addr, void *priv) -{ - uint8_t ret = 0xff; - rabbit_t *dev = (rabbit_t *) priv; - - switch (addr) { - case 0x23: - ret = dev->regs[dev->cur_reg]; - break; - } - - return ret; -} - - -static void -rabbit_close(void *priv) -{ - rabbit_t *dev = (rabbit_t *) priv; - - free(dev); -} - - -static void * -rabbit_init(const device_t *info) -{ - rabbit_t *dev = (rabbit_t *) malloc(sizeof(rabbit_t)); - memset(dev, 0, sizeof(rabbit_t)); - - io_sethandler(0x0022, 0x0001, rabbit_read, NULL, NULL, rabbit_write, NULL, NULL, dev); - io_sethandler(0x0023, 0x0001, rabbit_read, NULL, NULL, rabbit_write, NULL, NULL, dev); - - return dev; -} - - -const device_t rabbit_device = { - "SiS Rabbit", - 0, - 0, - rabbit_init, rabbit_close, NULL, - NULL, NULL, NULL, - NULL -}; \ No newline at end of file diff --git a/src/chipset/sis_85c310.c b/src/chipset/sis_85c310.c new file mode 100644 index 000000000..2a11f9654 --- /dev/null +++ b/src/chipset/sis_85c310.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/chipset.h> + + +typedef struct +{ + uint8_t cur_reg, tries, + regs[258]; +} rabbit_t; + + +static void +rabbit_recalcmapping(rabbit_t *dev) +{ + uint32_t shread, shwrite; + uint32_t shflags = 0; + + shread = !!(dev->regs[0x101] & 0x40); + shwrite = !!(dev->regs[0x100] & 0x02); + + shflags = shread ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + shflags |= shwrite ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + + shadowbios = !!shread; + shadowbios_write = !!shwrite; + +#ifdef USE_SHADOW_C0000 + mem_set_mem_state(0x000c0000, 0x00040000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); +#else + mem_set_mem_state(0x000e0000, 0x00020000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); +#endif + + switch (dev->regs[0x100] & 0x09) { + case 0x01: +/* The one BIOS we use seems to use something else to control C0000-DFFFF shadow, + no idea what. */ +#ifdef USE_SHADOW_C0000 + /* 64K at 0C0000-0CFFFF */ + mem_set_mem_state(0x000c0000, 0x00010000, shflags); + /* FALLTHROUGH */ +#endif + case 0x00: + /* 64K at 0F0000-0FFFFF */ + mem_set_mem_state(0x000f0000, 0x00010000, shflags); + break; + + case 0x09: +#ifdef USE_SHADOW_C0000 + /* 128K at 0C0000-0DFFFF */ + mem_set_mem_state(0x000c0000, 0x00020000, shflags); + /* FALLTHROUGH */ +#endif + case 0x08: + /* 128K at 0E0000-0FFFFF */ + mem_set_mem_state(0x000e0000, 0x00020000, shflags); + break; + } + + flushmmucache(); +} + + +static void +rabbit_write(uint16_t addr, uint8_t val, void *priv) +{ + rabbit_t *dev = (rabbit_t *) priv; + + switch (addr) { + case 0x22: + dev->cur_reg = val; + dev->tries = 0; + break; + case 0x23: + if (dev->cur_reg == 0x83) { + if (dev->tries < 0x02) { + dev->regs[dev->tries++ | 0x100] = val; + if (dev->tries == 0x02) + rabbit_recalcmapping(dev); + } + } else + dev->regs[dev->cur_reg] = val; + break; + } +} + + +static uint8_t +rabbit_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + rabbit_t *dev = (rabbit_t *) priv; + + switch (addr) { + case 0x23: + if (dev->cur_reg == 0x83) { + if (dev->tries < 0x02) + ret = dev->regs[dev->tries++ | 0x100]; + } else + ret = dev->regs[dev->cur_reg]; + break; + } + + return ret; +} + + +static void +rabbit_close(void *priv) +{ + rabbit_t *dev = (rabbit_t *) priv; + + free(dev); +} + + +static void * +rabbit_init(const device_t *info) +{ + rabbit_t *dev = (rabbit_t *) malloc(sizeof(rabbit_t)); + memset(dev, 0, sizeof(rabbit_t)); + + io_sethandler(0x0022, 0x0002, rabbit_read, NULL, NULL, rabbit_write, NULL, NULL, dev); + + return dev; +} + + +const device_t rabbit_device = { + "SiS Rabbit", + 0, + 0, + rabbit_init, rabbit_close, NULL, + NULL, NULL, NULL, + NULL +}; \ No newline at end of file diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 6122f2761..a3200669a 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -46,16 +46,16 @@ apollo_map(uint32_t addr, uint32_t size, int state) { switch (state & 3) { case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); break; case 1: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); break; case 2: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); break; case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); break; } @@ -64,20 +64,17 @@ apollo_map(uint32_t addr, uint32_t size, int state) static void -apollo_smram_map(int smm, uint32_t addr, uint32_t size, int ram) +apollo_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) { - int state = (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (((is_smram & 0x03) == 0x01) || ((is_smram & 0x03) == 0x02)) { + smram[0].ram_base = 0x000a0000; + smram[0].size = size; - if (ram == 0) - state = (MEM_READ_EXTANY | MEM_WRITE_EXTANY); - else if (ram == 1) - state = (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - else if (ram == 2) - state = (MEM_READ_EXTERNAL_EX | MEM_WRITE_EXTANY); - else if (ram == 3) - state = (MEM_READ_DISABLED | MEM_WRITE_DISABLED); + mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size); + mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base); + } - mem_set_mem_state_common(smm, addr, size, state); + mem_set_mem_state_smram_ex(smm, addr, size, is_smram & 0x03); flushmmucache(); } @@ -272,6 +269,14 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) if ((dev->pci_conf[0][0x63] ^ val) & 0xc0) apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6); dev->pci_conf[0][0x63] = val; + if (smram[0].size != 0x00000000) { + mem_set_mem_state_smram_ex(0, smram[0].host_base, smram[0].size, 0x00); + mem_set_mem_state_smram_ex(1, smram[0].host_base, smram[0].size, 0x00); + + memset(&smram[0], 0x00, sizeof(smram_t)); + mem_mapping_disable(&ram_smram_mapping[0]); + flushmmucache(); + } if (dev->id == 0x0691) switch (val & 0x03) { case 0x00: default: @@ -310,9 +315,9 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) /* Reserved */ apollo_smram_map(1, 0x000a0000, 0x00020000, 3); if (dev->id == 0x0597) { - /* TODO: SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx - (this needs a 3xxxx-4xxxx mapping set to EXTERNAL). */ - apollo_smram_map(1, 0x00030000, 0x00020000, 3); + /* SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx. */ + smram[0].host_base = 0x00030000; + apollo_smram_map(1, 0x00030000, 0x00020000, 1); } apollo_smram_map(0, 0x000a0000, 0x00020000, 3); break; diff --git a/src/via_vt82c586b.c b/src/chipset/via_vt82c586b.c similarity index 99% rename from src/via_vt82c586b.c rename to src/chipset/via_vt82c586b.c index b2721c5d4..3524ed30b 100644 --- a/src/via_vt82c586b.c +++ b/src/chipset/via_vt82c586b.c @@ -45,7 +45,7 @@ #include <86box/hdc_ide_sff8038i.h> #include <86box/zip.h> #include <86box/machine.h> -#include <86box/via_vt82c586b.h> +#include <86box/chipset.h> #define ACPI_TIMER_FREQ 3579545 diff --git a/src/via_vt82c596b.c b/src/chipset/via_vt82c596b.c similarity index 99% rename from src/via_vt82c596b.c rename to src/chipset/via_vt82c596b.c index e982e4e05..5cc9a2e4e 100644 --- a/src/via_vt82c596b.c +++ b/src/chipset/via_vt82c596b.c @@ -49,7 +49,7 @@ #include <86box/hdc_ide_sff8038i.h> #include <86box/zip.h> #include <86box/machine.h> -#include <86box/via_vt82c586b.h> +#include <86box/chipset.h> // As of now #include <86box/smbus_piix4.h> diff --git a/src/cpu/codegen.c b/src/codegen/codegen.c similarity index 100% rename from src/cpu/codegen.c rename to src/codegen/codegen.c diff --git a/src/cpu/codegen.h b/src/codegen/codegen.h similarity index 99% rename from src/cpu/codegen.h rename to src/codegen/codegen.h index 24cb20de6..086d00347 100644 --- a/src/cpu/codegen.h +++ b/src/codegen/codegen.h @@ -38,7 +38,7 @@ #define _CODEGEN_H_ #include <86box/mem.h> -#include "../cpu_common/x86_ops.h" +#include "x86_ops.h" #ifdef __amd64__ #include "codegen_x86-64.h" diff --git a/src/cpu/codegen_accumulate.h b/src/codegen/codegen_accumulate.h similarity index 100% rename from src/cpu/codegen_accumulate.h rename to src/codegen/codegen_accumulate.h diff --git a/src/cpu/codegen_accumulate_x86-64.c b/src/codegen/codegen_accumulate_x86-64.c similarity index 100% rename from src/cpu/codegen_accumulate_x86-64.c rename to src/codegen/codegen_accumulate_x86-64.c diff --git a/src/cpu/codegen_accumulate_x86.c b/src/codegen/codegen_accumulate_x86.c similarity index 100% rename from src/cpu/codegen_accumulate_x86.c rename to src/codegen/codegen_accumulate_x86.c diff --git a/src/cpu/codegen_ops.c b/src/codegen/codegen_ops.c similarity index 100% rename from src/cpu/codegen_ops.c rename to src/codegen/codegen_ops.c diff --git a/src/cpu/codegen_ops.h b/src/codegen/codegen_ops.h similarity index 100% rename from src/cpu/codegen_ops.h rename to src/codegen/codegen_ops.h diff --git a/src/cpu/codegen_ops_arith.h b/src/codegen/codegen_ops_arith.h similarity index 100% rename from src/cpu/codegen_ops_arith.h rename to src/codegen/codegen_ops_arith.h diff --git a/src/cpu/codegen_ops_fpu.h b/src/codegen/codegen_ops_fpu.h similarity index 100% rename from src/cpu/codegen_ops_fpu.h rename to src/codegen/codegen_ops_fpu.h diff --git a/src/cpu/codegen_ops_jump.h b/src/codegen/codegen_ops_jump.h similarity index 100% rename from src/cpu/codegen_ops_jump.h rename to src/codegen/codegen_ops_jump.h diff --git a/src/cpu/codegen_ops_logic.h b/src/codegen/codegen_ops_logic.h similarity index 100% rename from src/cpu/codegen_ops_logic.h rename to src/codegen/codegen_ops_logic.h diff --git a/src/cpu/codegen_ops_misc.h b/src/codegen/codegen_ops_misc.h similarity index 100% rename from src/cpu/codegen_ops_misc.h rename to src/codegen/codegen_ops_misc.h diff --git a/src/cpu/codegen_ops_mmx.h b/src/codegen/codegen_ops_mmx.h similarity index 100% rename from src/cpu/codegen_ops_mmx.h rename to src/codegen/codegen_ops_mmx.h diff --git a/src/cpu/codegen_ops_mov.h b/src/codegen/codegen_ops_mov.h similarity index 100% rename from src/cpu/codegen_ops_mov.h rename to src/codegen/codegen_ops_mov.h diff --git a/src/cpu/codegen_ops_shift.h b/src/codegen/codegen_ops_shift.h similarity index 100% rename from src/cpu/codegen_ops_shift.h rename to src/codegen/codegen_ops_shift.h diff --git a/src/cpu/codegen_ops_stack.h b/src/codegen/codegen_ops_stack.h similarity index 100% rename from src/cpu/codegen_ops_stack.h rename to src/codegen/codegen_ops_stack.h diff --git a/src/cpu/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h similarity index 100% rename from src/cpu/codegen_ops_x86-64.h rename to src/codegen/codegen_ops_x86-64.h diff --git a/src/cpu/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h similarity index 100% rename from src/cpu/codegen_ops_x86.h rename to src/codegen/codegen_ops_x86.h diff --git a/src/cpu/codegen_ops_xchg.h b/src/codegen/codegen_ops_xchg.h similarity index 100% rename from src/cpu/codegen_ops_xchg.h rename to src/codegen/codegen_ops_xchg.h diff --git a/src/cpu/codegen_x86-64.c b/src/codegen/codegen_x86-64.c similarity index 100% rename from src/cpu/codegen_x86-64.c rename to src/codegen/codegen_x86-64.c diff --git a/src/cpu/codegen_x86-64.h b/src/codegen/codegen_x86-64.h similarity index 100% rename from src/cpu/codegen_x86-64.h rename to src/codegen/codegen_x86-64.h diff --git a/src/cpu/codegen_x86.c b/src/codegen/codegen_x86.c similarity index 99% rename from src/cpu/codegen_x86.c rename to src/codegen/codegen_x86.c index 222e7c2c7..44d66b42f 100644 --- a/src/cpu/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -48,7 +48,7 @@ #include <86box/mem.h> #include "x86.h" #include "x86_flags.h" -#include "../cpu_common/x86_ops.h" +#include "x86_ops.h" #include "x87.h" #include "386_common.h" diff --git a/src/cpu/codegen_x86.h b/src/codegen/codegen_x86.h similarity index 100% rename from src/cpu/codegen_x86.h rename to src/codegen/codegen_x86.h diff --git a/src/cpu/x86_flags.h b/src/codegen/x86_flags.h similarity index 100% rename from src/cpu/x86_flags.h rename to src/codegen/x86_flags.h diff --git a/src/cpu/x86_ops_call.h b/src/codegen/x86_ops_call.h similarity index 100% rename from src/cpu/x86_ops_call.h rename to src/codegen/x86_ops_call.h diff --git a/src/cpu/x86_ops_shift.h b/src/codegen/x86_ops_shift.h similarity index 100% rename from src/cpu/x86_ops_shift.h rename to src/codegen/x86_ops_shift.h diff --git a/src/cpu/x86seg.c b/src/codegen/x86seg.c similarity index 100% rename from src/cpu/x86seg.c rename to src/codegen/x86seg.c diff --git a/src/cpu_new/codegen.c b/src/codegen_new/codegen.c similarity index 99% rename from src/cpu_new/codegen.c rename to src/codegen_new/codegen.c index e38dfb7a2..f385fb448 100644 --- a/src/cpu_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -614,7 +614,10 @@ generate_call: To prevent having zero cycle blocks (eg with a jump instruction pointing to itself), apply the cycles that would be taken if this jump is taken, then reverse it for subsequent instructions if the jump is not taken*/ - int jump_cycles = codegen_timing_jump_cycles(); + int jump_cycles = 0; + + if (codegen_timing_jump_cycles) + codegen_timing_jump_cycles(); if (jump_cycles) codegen_accumulate(ACCREG_cycles, -jump_cycles); diff --git a/src/cpu_new/codegen.h b/src/codegen_new/codegen.h similarity index 99% rename from src/cpu_new/codegen.h rename to src/codegen_new/codegen.h index 8471b18c5..38a061f97 100644 --- a/src/cpu_new/codegen.h +++ b/src/codegen_new/codegen.h @@ -3,7 +3,7 @@ #include <86box/mem.h> #include -#include "../cpu_common/x86_ops.h" +#include "x86_ops.h" /*Handling self-modifying code (of which there is a lot on x86) : diff --git a/src/cpu_new/codegen_accumulate.c b/src/codegen_new/codegen_accumulate.c similarity index 100% rename from src/cpu_new/codegen_accumulate.c rename to src/codegen_new/codegen_accumulate.c diff --git a/src/cpu_new/codegen_accumulate.h b/src/codegen_new/codegen_accumulate.h similarity index 100% rename from src/cpu_new/codegen_accumulate.h rename to src/codegen_new/codegen_accumulate.h diff --git a/src/cpu_new/codegen_allocator.c b/src/codegen_new/codegen_allocator.c similarity index 100% rename from src/cpu_new/codegen_allocator.c rename to src/codegen_new/codegen_allocator.c diff --git a/src/cpu_new/codegen_allocator.h b/src/codegen_new/codegen_allocator.h similarity index 100% rename from src/cpu_new/codegen_allocator.h rename to src/codegen_new/codegen_allocator.h diff --git a/src/cpu_new/codegen_backend.h b/src/codegen_new/codegen_backend.h similarity index 100% rename from src/cpu_new/codegen_backend.h rename to src/codegen_new/codegen_backend.h diff --git a/src/cpu_new/codegen_backend_arm.c b/src/codegen_new/codegen_backend_arm.c similarity index 100% rename from src/cpu_new/codegen_backend_arm.c rename to src/codegen_new/codegen_backend_arm.c diff --git a/src/cpu_new/codegen_backend_arm.h b/src/codegen_new/codegen_backend_arm.h similarity index 100% rename from src/cpu_new/codegen_backend_arm.h rename to src/codegen_new/codegen_backend_arm.h diff --git a/src/cpu_new/codegen_backend_arm64.c b/src/codegen_new/codegen_backend_arm64.c similarity index 100% rename from src/cpu_new/codegen_backend_arm64.c rename to src/codegen_new/codegen_backend_arm64.c diff --git a/src/cpu_new/codegen_backend_arm64.h b/src/codegen_new/codegen_backend_arm64.h similarity index 100% rename from src/cpu_new/codegen_backend_arm64.h rename to src/codegen_new/codegen_backend_arm64.h diff --git a/src/cpu_new/codegen_backend_arm64_defs.h b/src/codegen_new/codegen_backend_arm64_defs.h similarity index 100% rename from src/cpu_new/codegen_backend_arm64_defs.h rename to src/codegen_new/codegen_backend_arm64_defs.h diff --git a/src/cpu_new/codegen_backend_arm64_imm.c b/src/codegen_new/codegen_backend_arm64_imm.c similarity index 100% rename from src/cpu_new/codegen_backend_arm64_imm.c rename to src/codegen_new/codegen_backend_arm64_imm.c diff --git a/src/cpu_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c similarity index 100% rename from src/cpu_new/codegen_backend_arm64_ops.c rename to src/codegen_new/codegen_backend_arm64_ops.c diff --git a/src/cpu_new/codegen_backend_arm64_ops.h b/src/codegen_new/codegen_backend_arm64_ops.h similarity index 100% rename from src/cpu_new/codegen_backend_arm64_ops.h rename to src/codegen_new/codegen_backend_arm64_ops.h diff --git a/src/cpu_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c similarity index 100% rename from src/cpu_new/codegen_backend_arm64_uops.c rename to src/codegen_new/codegen_backend_arm64_uops.c diff --git a/src/cpu_new/codegen_backend_arm_defs.h b/src/codegen_new/codegen_backend_arm_defs.h similarity index 100% rename from src/cpu_new/codegen_backend_arm_defs.h rename to src/codegen_new/codegen_backend_arm_defs.h diff --git a/src/cpu_new/codegen_backend_arm_ops.c b/src/codegen_new/codegen_backend_arm_ops.c similarity index 100% rename from src/cpu_new/codegen_backend_arm_ops.c rename to src/codegen_new/codegen_backend_arm_ops.c diff --git a/src/cpu_new/codegen_backend_arm_ops.h b/src/codegen_new/codegen_backend_arm_ops.h similarity index 100% rename from src/cpu_new/codegen_backend_arm_ops.h rename to src/codegen_new/codegen_backend_arm_ops.h diff --git a/src/cpu_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c similarity index 100% rename from src/cpu_new/codegen_backend_arm_uops.c rename to src/codegen_new/codegen_backend_arm_uops.c diff --git a/src/cpu_new/codegen_backend_x86-64.c b/src/codegen_new/codegen_backend_x86-64.c similarity index 100% rename from src/cpu_new/codegen_backend_x86-64.c rename to src/codegen_new/codegen_backend_x86-64.c diff --git a/src/cpu_new/codegen_backend_x86-64.h b/src/codegen_new/codegen_backend_x86-64.h similarity index 100% rename from src/cpu_new/codegen_backend_x86-64.h rename to src/codegen_new/codegen_backend_x86-64.h diff --git a/src/cpu_new/codegen_backend_x86-64_defs.h b/src/codegen_new/codegen_backend_x86-64_defs.h similarity index 100% rename from src/cpu_new/codegen_backend_x86-64_defs.h rename to src/codegen_new/codegen_backend_x86-64_defs.h diff --git a/src/cpu_new/codegen_backend_x86-64_ops.c b/src/codegen_new/codegen_backend_x86-64_ops.c similarity index 100% rename from src/cpu_new/codegen_backend_x86-64_ops.c rename to src/codegen_new/codegen_backend_x86-64_ops.c diff --git a/src/cpu_new/codegen_backend_x86-64_ops.h b/src/codegen_new/codegen_backend_x86-64_ops.h similarity index 100% rename from src/cpu_new/codegen_backend_x86-64_ops.h rename to src/codegen_new/codegen_backend_x86-64_ops.h diff --git a/src/cpu_new/codegen_backend_x86-64_ops_helpers.h b/src/codegen_new/codegen_backend_x86-64_ops_helpers.h similarity index 100% rename from src/cpu_new/codegen_backend_x86-64_ops_helpers.h rename to src/codegen_new/codegen_backend_x86-64_ops_helpers.h diff --git a/src/cpu_new/codegen_backend_x86-64_ops_sse.c b/src/codegen_new/codegen_backend_x86-64_ops_sse.c similarity index 100% rename from src/cpu_new/codegen_backend_x86-64_ops_sse.c rename to src/codegen_new/codegen_backend_x86-64_ops_sse.c diff --git a/src/cpu_new/codegen_backend_x86-64_ops_sse.h b/src/codegen_new/codegen_backend_x86-64_ops_sse.h similarity index 100% rename from src/cpu_new/codegen_backend_x86-64_ops_sse.h rename to src/codegen_new/codegen_backend_x86-64_ops_sse.h diff --git a/src/cpu_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c similarity index 100% rename from src/cpu_new/codegen_backend_x86-64_uops.c rename to src/codegen_new/codegen_backend_x86-64_uops.c diff --git a/src/cpu_new/codegen_backend_x86.c b/src/codegen_new/codegen_backend_x86.c similarity index 100% rename from src/cpu_new/codegen_backend_x86.c rename to src/codegen_new/codegen_backend_x86.c diff --git a/src/cpu_new/codegen_backend_x86.h b/src/codegen_new/codegen_backend_x86.h similarity index 100% rename from src/cpu_new/codegen_backend_x86.h rename to src/codegen_new/codegen_backend_x86.h diff --git a/src/cpu_new/codegen_backend_x86_defs.h b/src/codegen_new/codegen_backend_x86_defs.h similarity index 100% rename from src/cpu_new/codegen_backend_x86_defs.h rename to src/codegen_new/codegen_backend_x86_defs.h diff --git a/src/cpu_new/codegen_backend_x86_ops.c b/src/codegen_new/codegen_backend_x86_ops.c similarity index 100% rename from src/cpu_new/codegen_backend_x86_ops.c rename to src/codegen_new/codegen_backend_x86_ops.c diff --git a/src/cpu_new/codegen_backend_x86_ops.h b/src/codegen_new/codegen_backend_x86_ops.h similarity index 100% rename from src/cpu_new/codegen_backend_x86_ops.h rename to src/codegen_new/codegen_backend_x86_ops.h diff --git a/src/cpu_new/codegen_backend_x86_ops_fpu.c b/src/codegen_new/codegen_backend_x86_ops_fpu.c similarity index 100% rename from src/cpu_new/codegen_backend_x86_ops_fpu.c rename to src/codegen_new/codegen_backend_x86_ops_fpu.c diff --git a/src/cpu_new/codegen_backend_x86_ops_fpu.h b/src/codegen_new/codegen_backend_x86_ops_fpu.h similarity index 100% rename from src/cpu_new/codegen_backend_x86_ops_fpu.h rename to src/codegen_new/codegen_backend_x86_ops_fpu.h diff --git a/src/cpu_new/codegen_backend_x86_ops_helpers.h b/src/codegen_new/codegen_backend_x86_ops_helpers.h similarity index 100% rename from src/cpu_new/codegen_backend_x86_ops_helpers.h rename to src/codegen_new/codegen_backend_x86_ops_helpers.h diff --git a/src/cpu_new/codegen_backend_x86_ops_sse.c b/src/codegen_new/codegen_backend_x86_ops_sse.c similarity index 100% rename from src/cpu_new/codegen_backend_x86_ops_sse.c rename to src/codegen_new/codegen_backend_x86_ops_sse.c diff --git a/src/cpu_new/codegen_backend_x86_ops_sse.h b/src/codegen_new/codegen_backend_x86_ops_sse.h similarity index 100% rename from src/cpu_new/codegen_backend_x86_ops_sse.h rename to src/codegen_new/codegen_backend_x86_ops_sse.h diff --git a/src/cpu_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c similarity index 100% rename from src/cpu_new/codegen_backend_x86_uops.c rename to src/codegen_new/codegen_backend_x86_uops.c diff --git a/src/cpu_new/codegen_block.c b/src/codegen_new/codegen_block.c similarity index 100% rename from src/cpu_new/codegen_block.c rename to src/codegen_new/codegen_block.c diff --git a/src/cpu_new/codegen_ir.c b/src/codegen_new/codegen_ir.c similarity index 100% rename from src/cpu_new/codegen_ir.c rename to src/codegen_new/codegen_ir.c diff --git a/src/cpu_new/codegen_ir.h b/src/codegen_new/codegen_ir.h similarity index 100% rename from src/cpu_new/codegen_ir.h rename to src/codegen_new/codegen_ir.h diff --git a/src/cpu_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h similarity index 100% rename from src/cpu_new/codegen_ir_defs.h rename to src/codegen_new/codegen_ir_defs.h diff --git a/src/cpu_new/codegen_ops.c b/src/codegen_new/codegen_ops.c similarity index 100% rename from src/cpu_new/codegen_ops.c rename to src/codegen_new/codegen_ops.c diff --git a/src/cpu_new/codegen_ops.h b/src/codegen_new/codegen_ops.h similarity index 100% rename from src/cpu_new/codegen_ops.h rename to src/codegen_new/codegen_ops.h diff --git a/src/cpu_new/codegen_ops_3dnow.c b/src/codegen_new/codegen_ops_3dnow.c similarity index 100% rename from src/cpu_new/codegen_ops_3dnow.c rename to src/codegen_new/codegen_ops_3dnow.c diff --git a/src/cpu_new/codegen_ops_3dnow.h b/src/codegen_new/codegen_ops_3dnow.h similarity index 100% rename from src/cpu_new/codegen_ops_3dnow.h rename to src/codegen_new/codegen_ops_3dnow.h diff --git a/src/cpu_new/codegen_ops_arith.c b/src/codegen_new/codegen_ops_arith.c similarity index 100% rename from src/cpu_new/codegen_ops_arith.c rename to src/codegen_new/codegen_ops_arith.c diff --git a/src/cpu_new/codegen_ops_arith.h b/src/codegen_new/codegen_ops_arith.h similarity index 100% rename from src/cpu_new/codegen_ops_arith.h rename to src/codegen_new/codegen_ops_arith.h diff --git a/src/cpu_new/codegen_ops_branch.c b/src/codegen_new/codegen_ops_branch.c similarity index 100% rename from src/cpu_new/codegen_ops_branch.c rename to src/codegen_new/codegen_ops_branch.c diff --git a/src/cpu_new/codegen_ops_branch.h b/src/codegen_new/codegen_ops_branch.h similarity index 100% rename from src/cpu_new/codegen_ops_branch.h rename to src/codegen_new/codegen_ops_branch.h diff --git a/src/cpu_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c similarity index 100% rename from src/cpu_new/codegen_ops_fpu_arith.c rename to src/codegen_new/codegen_ops_fpu_arith.c diff --git a/src/cpu_new/codegen_ops_fpu_arith.h b/src/codegen_new/codegen_ops_fpu_arith.h similarity index 100% rename from src/cpu_new/codegen_ops_fpu_arith.h rename to src/codegen_new/codegen_ops_fpu_arith.h diff --git a/src/cpu_new/codegen_ops_fpu_constant.c b/src/codegen_new/codegen_ops_fpu_constant.c similarity index 100% rename from src/cpu_new/codegen_ops_fpu_constant.c rename to src/codegen_new/codegen_ops_fpu_constant.c diff --git a/src/cpu_new/codegen_ops_fpu_constant.h b/src/codegen_new/codegen_ops_fpu_constant.h similarity index 100% rename from src/cpu_new/codegen_ops_fpu_constant.h rename to src/codegen_new/codegen_ops_fpu_constant.h diff --git a/src/cpu_new/codegen_ops_fpu_loadstore.c b/src/codegen_new/codegen_ops_fpu_loadstore.c similarity index 100% rename from src/cpu_new/codegen_ops_fpu_loadstore.c rename to src/codegen_new/codegen_ops_fpu_loadstore.c diff --git a/src/cpu_new/codegen_ops_fpu_loadstore.h b/src/codegen_new/codegen_ops_fpu_loadstore.h similarity index 100% rename from src/cpu_new/codegen_ops_fpu_loadstore.h rename to src/codegen_new/codegen_ops_fpu_loadstore.h diff --git a/src/cpu_new/codegen_ops_fpu_misc.c b/src/codegen_new/codegen_ops_fpu_misc.c similarity index 100% rename from src/cpu_new/codegen_ops_fpu_misc.c rename to src/codegen_new/codegen_ops_fpu_misc.c diff --git a/src/cpu_new/codegen_ops_fpu_misc.h b/src/codegen_new/codegen_ops_fpu_misc.h similarity index 100% rename from src/cpu_new/codegen_ops_fpu_misc.h rename to src/codegen_new/codegen_ops_fpu_misc.h diff --git a/src/cpu_new/codegen_ops_helpers.c b/src/codegen_new/codegen_ops_helpers.c similarity index 100% rename from src/cpu_new/codegen_ops_helpers.c rename to src/codegen_new/codegen_ops_helpers.c diff --git a/src/cpu_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h similarity index 100% rename from src/cpu_new/codegen_ops_helpers.h rename to src/codegen_new/codegen_ops_helpers.h diff --git a/src/cpu_new/codegen_ops_jump.c b/src/codegen_new/codegen_ops_jump.c similarity index 100% rename from src/cpu_new/codegen_ops_jump.c rename to src/codegen_new/codegen_ops_jump.c diff --git a/src/cpu_new/codegen_ops_jump.h b/src/codegen_new/codegen_ops_jump.h similarity index 100% rename from src/cpu_new/codegen_ops_jump.h rename to src/codegen_new/codegen_ops_jump.h diff --git a/src/cpu_new/codegen_ops_logic.c b/src/codegen_new/codegen_ops_logic.c similarity index 100% rename from src/cpu_new/codegen_ops_logic.c rename to src/codegen_new/codegen_ops_logic.c diff --git a/src/cpu_new/codegen_ops_logic.h b/src/codegen_new/codegen_ops_logic.h similarity index 100% rename from src/cpu_new/codegen_ops_logic.h rename to src/codegen_new/codegen_ops_logic.h diff --git a/src/cpu_new/codegen_ops_misc.c b/src/codegen_new/codegen_ops_misc.c similarity index 100% rename from src/cpu_new/codegen_ops_misc.c rename to src/codegen_new/codegen_ops_misc.c diff --git a/src/cpu_new/codegen_ops_misc.h b/src/codegen_new/codegen_ops_misc.h similarity index 100% rename from src/cpu_new/codegen_ops_misc.h rename to src/codegen_new/codegen_ops_misc.h diff --git a/src/cpu_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c similarity index 100% rename from src/cpu_new/codegen_ops_mmx_arith.c rename to src/codegen_new/codegen_ops_mmx_arith.c diff --git a/src/cpu_new/codegen_ops_mmx_arith.h b/src/codegen_new/codegen_ops_mmx_arith.h similarity index 100% rename from src/cpu_new/codegen_ops_mmx_arith.h rename to src/codegen_new/codegen_ops_mmx_arith.h diff --git a/src/cpu_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c similarity index 100% rename from src/cpu_new/codegen_ops_mmx_cmp.c rename to src/codegen_new/codegen_ops_mmx_cmp.c diff --git a/src/cpu_new/codegen_ops_mmx_cmp.h b/src/codegen_new/codegen_ops_mmx_cmp.h similarity index 100% rename from src/cpu_new/codegen_ops_mmx_cmp.h rename to src/codegen_new/codegen_ops_mmx_cmp.h diff --git a/src/cpu_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c similarity index 100% rename from src/cpu_new/codegen_ops_mmx_loadstore.c rename to src/codegen_new/codegen_ops_mmx_loadstore.c diff --git a/src/cpu_new/codegen_ops_mmx_loadstore.h b/src/codegen_new/codegen_ops_mmx_loadstore.h similarity index 100% rename from src/cpu_new/codegen_ops_mmx_loadstore.h rename to src/codegen_new/codegen_ops_mmx_loadstore.h diff --git a/src/cpu_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c similarity index 100% rename from src/cpu_new/codegen_ops_mmx_logic.c rename to src/codegen_new/codegen_ops_mmx_logic.c diff --git a/src/cpu_new/codegen_ops_mmx_logic.h b/src/codegen_new/codegen_ops_mmx_logic.h similarity index 100% rename from src/cpu_new/codegen_ops_mmx_logic.h rename to src/codegen_new/codegen_ops_mmx_logic.h diff --git a/src/cpu_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c similarity index 100% rename from src/cpu_new/codegen_ops_mmx_pack.c rename to src/codegen_new/codegen_ops_mmx_pack.c diff --git a/src/cpu_new/codegen_ops_mmx_pack.h b/src/codegen_new/codegen_ops_mmx_pack.h similarity index 100% rename from src/cpu_new/codegen_ops_mmx_pack.h rename to src/codegen_new/codegen_ops_mmx_pack.h diff --git a/src/cpu_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c similarity index 100% rename from src/cpu_new/codegen_ops_mmx_shift.c rename to src/codegen_new/codegen_ops_mmx_shift.c diff --git a/src/cpu_new/codegen_ops_mmx_shift.h b/src/codegen_new/codegen_ops_mmx_shift.h similarity index 100% rename from src/cpu_new/codegen_ops_mmx_shift.h rename to src/codegen_new/codegen_ops_mmx_shift.h diff --git a/src/cpu_new/codegen_ops_mov.c b/src/codegen_new/codegen_ops_mov.c similarity index 100% rename from src/cpu_new/codegen_ops_mov.c rename to src/codegen_new/codegen_ops_mov.c diff --git a/src/cpu_new/codegen_ops_mov.h b/src/codegen_new/codegen_ops_mov.h similarity index 100% rename from src/cpu_new/codegen_ops_mov.h rename to src/codegen_new/codegen_ops_mov.h diff --git a/src/cpu_new/codegen_ops_shift.c b/src/codegen_new/codegen_ops_shift.c similarity index 100% rename from src/cpu_new/codegen_ops_shift.c rename to src/codegen_new/codegen_ops_shift.c diff --git a/src/cpu_new/codegen_ops_shift.h b/src/codegen_new/codegen_ops_shift.h similarity index 100% rename from src/cpu_new/codegen_ops_shift.h rename to src/codegen_new/codegen_ops_shift.h diff --git a/src/cpu_new/codegen_ops_stack.c b/src/codegen_new/codegen_ops_stack.c similarity index 100% rename from src/cpu_new/codegen_ops_stack.c rename to src/codegen_new/codegen_ops_stack.c diff --git a/src/cpu_new/codegen_ops_stack.h b/src/codegen_new/codegen_ops_stack.h similarity index 100% rename from src/cpu_new/codegen_ops_stack.h rename to src/codegen_new/codegen_ops_stack.h diff --git a/src/cpu_new/codegen_reg.c b/src/codegen_new/codegen_reg.c similarity index 100% rename from src/cpu_new/codegen_reg.c rename to src/codegen_new/codegen_reg.c diff --git a/src/cpu_new/codegen_reg.h b/src/codegen_new/codegen_reg.h similarity index 100% rename from src/cpu_new/codegen_reg.h rename to src/codegen_new/codegen_reg.h diff --git a/src/cpu_new/x86_flags.h b/src/codegen_new/x86_flags.h similarity index 100% rename from src/cpu_new/x86_flags.h rename to src/codegen_new/x86_flags.h diff --git a/src/cpu_new/x86_ops_call.h b/src/codegen_new/x86_ops_call.h similarity index 100% rename from src/cpu_new/x86_ops_call.h rename to src/codegen_new/x86_ops_call.h diff --git a/src/cpu_new/x86_ops_shift.h b/src/codegen_new/x86_ops_shift.h similarity index 100% rename from src/cpu_new/x86_ops_shift.h rename to src/codegen_new/x86_ops_shift.h diff --git a/src/cpu_new/x86seg.c b/src/codegen_new/x86seg.c similarity index 100% rename from src/cpu_new/x86seg.c rename to src/codegen_new/x86seg.c diff --git a/src/config.c b/src/config.c index 419bcc324..5d3962c6f 100644 --- a/src/config.c +++ b/src/config.c @@ -47,6 +47,7 @@ #include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/gameport.h> #include <86box/machine.h> #include <86box/mouse.h> @@ -450,7 +451,7 @@ load_general(void) video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 0); + video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 1); force_43 = !!config_get_int(cat, "force_43", 0); scale = config_get_int(cat, "scale", 1); @@ -528,6 +529,9 @@ load_machine(void) cpu = config_get_int(cat, "cpu", 0); cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); + p = (char *)config_get_string(cat, "fpu_type", "none"); + fpu_type = fpu_get_type(machine, cpu_manufacturer, cpu, p); + mem_size = config_get_int(cat, "mem_size", 4096); #if 0 @@ -536,13 +540,11 @@ load_machine(void) mem_size = (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); #endif - if (mem_size > 1048576) - mem_size = 1048576; + if (mem_size > 2097152) + mem_size = 2097152; cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); - enable_external_fpu = !!config_get_int(cat, "cpu_enable_fpu", 0); - p = config_get_string(cat, "time_sync", NULL); if (p != NULL) { if (!strcmp(p, "disabled")) @@ -711,9 +713,9 @@ load_network(void) if (p != NULL) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { if ((network_ndev == 1) && strcmp(network_host, "none")) { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2094); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2094, (wchar_t *) IDS_2129); } else if (network_dev_to_id(p) == -1) { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2095); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2129); } strcpy(network_host, "none"); @@ -782,6 +784,12 @@ load_other_peripherals(void) else scsi_card_current = 0; + p = config_get_string(cat, "fdc", NULL); + if (p != NULL) + fdc_type = fdc_card_get_from_internal_name(p); + else + fdc_type = FDC_INTERNAL; + p = config_get_string(cat, "hdc", NULL); if (p == NULL) { if (machines[machine].flags & MACHINE_HDC) { @@ -855,7 +863,7 @@ load_hard_disks(void) case HDD_BUS_MFM: max_spt = 26; /* 26 for RLL */ max_hpc = 15; - max_tracks = 1023; + max_tracks = 2047; break; case HDD_BUS_XTA: @@ -1336,6 +1344,7 @@ config_load(void) #endif scale = 1; machine = machine_get_machine_from_internal_name("ibmpc"); + fpu_type = fpu_get_type(machine, cpu_manufacturer, cpu, "none"); gfxcard = video_get_video_from_internal_name("cga"); vid_api = plat_vidapi("default"); time_sync = TIME_SYNC_ENABLED; @@ -1509,6 +1518,11 @@ save_machine(void) else config_set_int(cat, "cpu_waitstates", cpu_waitstates); + if (fpu_type == 0) + config_delete_var(cat, "fpu_type"); + else + config_set_string(cat, "fpu_type", fpu_get_internal_name(machine, cpu_manufacturer, cpu, fpu_type)); + if (mem_size == 4096) config_delete_var(cat, "mem_size"); else @@ -1516,11 +1530,6 @@ save_machine(void) config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); - if (enable_external_fpu == 0) - config_delete_var(cat, "cpu_enable_fpu"); - else - config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); - if (time_sync & TIME_SYNC_ENABLED) if (time_sync & TIME_SYNC_UTC) config_set_string(cat, "time_sync", "utc"); @@ -1742,6 +1751,12 @@ save_other_peripherals(void) config_set_string(cat, "scsicard", scsi_card_get_internal_name(scsi_card_current)); + if (fdc_type == FDC_INTERNAL) + config_delete_var(cat, "fdc"); + else + config_set_string(cat, "fdc", + fdc_card_get_internal_name(fdc_type)); + config_set_string(cat, "hdc", hdc_get_internal_name(hdc_current)); diff --git a/src/cpu_common/386.c b/src/cpu/386.c similarity index 100% rename from src/cpu_common/386.c rename to src/cpu/386.c diff --git a/src/cpu_common/386_common.c b/src/cpu/386_common.c similarity index 98% rename from src/cpu_common/386_common.c rename to src/cpu/386_common.c index 47db7c5db..1bda39a95 100644 --- a/src/cpu_common/386_common.c +++ b/src/cpu/386_common.c @@ -24,10 +24,13 @@ #include "386_common.h" #include "x86_flags.h" #include "x86seg.h" + +#ifdef USE_DYNAREC #include "codegen.h" - - #define CPU_BLOCK_END() cpu_block_end = 1 +#else +#define CPU_BLOCK_END() +#endif x86seg gdt, ldt, idt, tr; @@ -60,6 +63,8 @@ extern uint32_t pccache; int in_sys = 0; +smram_t temp_smram[2]; + #define AMD_SYSCALL_EIP (star & 0xFFFFFFFF) #define AMD_SYSCALL_SB ((star >> 32) & 0xFFFF) @@ -1021,15 +1026,13 @@ enter_smm(int in_hlt) EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); in_smm = 1; - mem_mapping_recalc(0x00030000, 0x00020000); - mem_mapping_recalc(0x000a0000, 0x00060000); - - if (!cpu_16bitbus) - mem_mapping_recalc(0x100a0000, 0x00060000); - - if (mem_size >= 1024) - mem_mapping_recalc((mem_size << 10) - (1 << 20), (1 << 20)); - + if (smram[0].size) + mem_mapping_recalc(smram[0].host_base, smram[0].size); + if (smram[1].size) + mem_mapping_recalc(smram[1].host_base, smram[1].size); + /* This is used by leave_smm() to make sure we don't keep the old mappings in SMM mode if the SMM + handler has told the chipset to change the actual mappings. */ + memcpy(temp_smram, smram, sizeof(temp_smram)); flushmmucache(); memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); @@ -1157,12 +1160,15 @@ leave_smm(void) smram_restore_state_p6(saved_state); in_smm = 0; - mem_mapping_recalc(0x00030000, 0x00020000); - mem_mapping_recalc(0x000a0000, 0x00060000); - if (!cpu_16bitbus) - mem_mapping_recalc(0x100a0000, 0x00060000); - if (mem_size >= 1024) - mem_mapping_recalc((mem_size << 10) - (1 << 20), (1 << 20)); + if (temp_smram[0].size) + mem_mapping_recalc(temp_smram[0].host_base, temp_smram[0].size); + if (temp_smram[1].size) + mem_mapping_recalc(temp_smram[1].host_base, temp_smram[1].size); + memset(temp_smram, 0x00, sizeof(temp_smram)); + if (smram[0].size) + mem_mapping_recalc(smram[0].host_base, smram[0].size); + if (smram[1].size) + mem_mapping_recalc(smram[1].host_base, smram[1].size); flushmmucache(); cpu_state.op32 = use32; @@ -1564,7 +1570,9 @@ sysenter(uint32_t fetchdat) return 1; do_seg_load(&cpu_state.seg_ss, seg_data); cpu_state.seg_ss.checked = 0; +#ifdef USE_DYNAREC codegen_flat_ss = 0; +#endif if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; @@ -1657,7 +1665,9 @@ sysexit(uint32_t fetchdat) return 1; do_seg_load(&cpu_state.seg_ss, seg_data); cpu_state.seg_ss.checked = 0; +#ifdef USE_DYNAREC codegen_flat_ss = 0; +#endif if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; @@ -1725,7 +1735,9 @@ syscall(uint32_t fetchdat) return 1; do_seg_load(&cpu_state.seg_ss, seg_data); cpu_state.seg_ss.checked = 0; +#ifdef USE_DYNAREC codegen_flat_ss = 0; +#endif if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; @@ -1782,7 +1794,9 @@ sysret(uint32_t fetchdat) return 1; do_seg_load(&cpu_state.seg_ss, seg_data); cpu_state.seg_ss.checked = 0; +#ifdef USE_DYNAREC codegen_flat_ss = 0; +#endif if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; @@ -1797,3 +1811,13 @@ sysret(uint32_t fetchdat) return 1; } + + +#ifndef USE_DYNAREC +/* This is for compatibility with new x87 code. */ +void codegen_set_rounding_mode(int mode) +{ + /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */ + cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); +} +#endif diff --git a/src/cpu_common/386_common.h b/src/cpu/386_common.h similarity index 100% rename from src/cpu_common/386_common.h rename to src/cpu/386_common.h diff --git a/src/cpu_common/386_dynarec.c b/src/cpu/386_dynarec.c similarity index 100% rename from src/cpu_common/386_dynarec.c rename to src/cpu/386_dynarec.c diff --git a/src/cpu_common/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c similarity index 100% rename from src/cpu_common/386_dynarec_ops.c rename to src/cpu/386_dynarec_ops.c diff --git a/src/cpu_common/386_ops.h b/src/cpu/386_ops.h similarity index 100% rename from src/cpu_common/386_ops.h rename to src/cpu/386_ops.h diff --git a/src/cpu_common/808x.c b/src/cpu/808x.c similarity index 99% rename from src/cpu_common/808x.c rename to src/cpu/808x.c index 6bc896753..a712e6830 100644 --- a/src/cpu_common/808x.c +++ b/src/cpu/808x.c @@ -953,7 +953,6 @@ reset_common(int hard) makeznptable(); resetreadlookup(); makemod1table(); - resetmcr(); pfq_clear(); cpu_set_edx(); mmu_perm = 4; @@ -984,6 +983,8 @@ reset_common(int hard) ppi_reset(); } in_sys = 0; + + shadowbios = shadowbios_write = 0; } diff --git a/src/cpu_common/codegen_public.h b/src/cpu/codegen_public.h similarity index 100% rename from src/cpu_common/codegen_public.h rename to src/cpu/codegen_public.h diff --git a/src/cpu/codegen_timing_common.h b/src/cpu/codegen_timing_common.h index 0ec5adcac..71daf80ef 100644 --- a/src/cpu/codegen_timing_common.h +++ b/src/cpu/codegen_timing_common.h @@ -68,7 +68,7 @@ /*Instruction writes to ST(reg)*/ #define FPU_WRITE_STREG (1ull << 32) /*Instruction reads from and writes to ST(reg)*/ -#define FPU_RW_STREG (3ull << 30) +#define FPU_RW_STREG (3ull << 31) #define FPU_FXCH (1ull << 33) diff --git a/src/cpu/codegen_timing_k6.c b/src/cpu/codegen_timing_k6.c index a9b1aca13..1186c4bf0 100644 --- a/src/cpu/codegen_timing_k6.c +++ b/src/cpu/codegen_timing_k6.c @@ -5,10 +5,9 @@ #include #include #include <86box/86box.h> -#include "cpu.h" #include <86box/mem.h> +#include "cpu.h" #include <86box/machine.h> - #include "x86.h" #include "x86_ops.h" #include "x87.h" diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c index c95821df9..ec6b8f2a7 100644 --- a/src/cpu/codegen_timing_pentium.c +++ b/src/cpu/codegen_timing_pentium.c @@ -1035,8 +1035,6 @@ static void codegen_instruction(uint64_t *timings, uint64_t *deps, uint8_t opcod } if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) { - /* if (fpu_latency) - fatal("Bad latency FPU\n");*/ fpu_latency = FPU_F_LATENCY(timings[opcode]); } @@ -1069,8 +1067,6 @@ static void codegen_instruction(uint64_t *timings, uint64_t *deps, uint8_t opcod !(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]); } } diff --git a/src/cpu_common/cpu.c b/src/cpu/cpu.c similarity index 95% rename from src/cpu_common/cpu.c rename to src/cpu/cpu.c index b8ed3918b..aa942acd9 100644 --- a/src/cpu_common/cpu.c +++ b/src/cpu/cpu.c @@ -59,7 +59,9 @@ #ifdef USE_DYNAREC # include "codegen.h" #endif +#include "x87_timings.h" +/*#define ENABLE_CPU_LOG 1*/ static void cpu_write(uint16_t addr, uint8_t val, void *priv); static uint8_t cpu_read(uint16_t addr, void *priv); @@ -171,7 +173,6 @@ int is286, int hasfpu; - uint64_t tsc = 0; msr_t msr; cpu_state_t cpu_state; @@ -195,6 +196,7 @@ uint64_t apic_base_msr = 0; uint64_t pat_msr = 0; uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint64_t ecx17_msr = 0; +uint64_t ecx2a_msr = 0; uint64_t ecx79_msr = 0; uint64_t ecx8x_msr[4] = {0, 0, 0, 0}; uint64_t ecx116_msr = 0; @@ -203,9 +205,23 @@ uint64_t ecx11e_msr = 0; uint64_t ecx186_msr = 0; uint64_t ecx187_msr = 0; uint64_t ecx1e0_msr = 0; + +/* Model Identification MSR's used by some Acer BIOSes*/ +uint64_t ecx404_msr = 0; +uint64_t ecx408_msr = 0; +uint64_t ecx40c_msr = 0; +uint64_t ecx410_msr = 0; uint64_t ecx570_msr = 0; uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */ + +/* MSR used by some Intel AMI boards */ +uint64_t ecx1002ff_msr = 0; + +/* Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ +uint64_t ecxf0f00250_msr = 0; +uint64_t ecxf0f00258_msr = 0; + uint64_t star = 0; /* AMD K6-2+. */ uint64_t amd_efer = 0, amd_whcr = 0, @@ -279,6 +295,54 @@ cpu_set_edx(void) EDX = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].edx_reset; } +int fpu_get_type(int machine, int cpu_manufacturer, int cpu, const char *internal_name) +{ + CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int fpu_type = fpus[0].type; + int c = 0; + + while (fpus[c].internal_name) + { + if (!strcmp(internal_name, fpus[c].internal_name)) + fpu_type = fpus[c].type; + c++; + } + + return fpu_type; +} + +const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int cpu, int type) +{ + CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int c = 0; + + while (fpus[c].internal_name) + { + if (fpus[c].type == type) + return fpus[c].internal_name; + c++; + } + + return fpus[0].internal_name; +} + +const char *fpu_get_name_from_index(int machine, int cpu_manufacturer, int cpu, int c) +{ + CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + + return fpus[c].name; +} + +int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c) +{ + CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + + return fpus[c].type; +} void cpu_set(void) @@ -326,7 +390,7 @@ cpu_set(void) (cpu_s->cpu_type == CPU_PENTIUM2D); /* The Samuel 2 datasheet claims it's Celeron-compatible. */ is_p6 |= (cpu_s->cpu_type == CPU_CYRIX3S); - hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); + hasfpu = (fpu_type != FPU_NONE); hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL); #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); @@ -345,11 +409,7 @@ cpu_set(void) cpu_dmulti = cpu_s->multi; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; - if ((cpu_s->cpu_type == CPU_8088) || (cpu_s->cpu_type == CPU_8086) || - (cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) || - (cpu_s->cpu_type == CPU_386DX) || (cpu_s->cpu_type == CPU_i486SX)) { - hasfpu = !!enable_external_fpu; - } + cpu_update_waitstates(); @@ -492,7 +552,7 @@ cpu_set(void) #else x86_setopcodes(ops_286, ops_286_0f); #endif - if (enable_external_fpu) + if (fpu_type == FPU_287) { #ifdef USE_DYNAREC x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; @@ -600,6 +660,39 @@ cpu_set(void) x86_setopcodes(ops_386, ops_486_0f); #endif case CPU_386DX: + if (fpu_type == FPU_287) /*In case we get Deskpro 386 emulation*/ + { +#ifdef USE_DYNAREC + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; +#endif + x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; + x86_opcodes_da_a16 = ops_fpu_287_da_a16; + x86_opcodes_da_a32 = ops_fpu_287_da_a32; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a32 = ops_fpu_287_db_a32; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; + 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; + } timing_rr = 2; /*register dest - register src*/ timing_rm = 6; /*register dest - memory src*/ timing_mr = 7; /*memory dest - register src*/ @@ -1385,7 +1478,9 @@ cpu_set(void) cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX | CPU_FEATURE_3DNOW; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; +#ifdef USE_DYNAREC codegen_timing_set(&codegen_timing_k6); +#endif break; case CPU_PENTIUMPRO: @@ -1600,9 +1695,30 @@ cpu_set(void) default: fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); } + + + switch (fpu_type) + { + case FPU_NONE: + break; + + case FPU_8087: + x87_timings = x87_timings_8087; + break; + + case FPU_287: + x87_timings = x87_timings_287; + break; + + case FPU_287XL: + case FPU_387: + x87_timings = x87_timings_387; + break; + + default: + x87_timings = x87_timings_486; + } } - - char * cpu_current_pc(char *bufp) { @@ -2745,7 +2861,7 @@ void cpu_RDMSR() case 0x1B: EAX = apic_base_msr & 0xffffffff; EDX = apic_base_msr >> 32; - /* pclog("APIC_BASE read : %08X%08X\n", EDX, EAX); */ + cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); break; case 0x2A: EAX = 0xC4000000; @@ -2877,10 +2993,38 @@ void cpu_RDMSR() EAX = mtrr_deftype_msr & 0xffffffff; EDX = mtrr_deftype_msr >> 32; break; + case 0x404: + EAX = ecx404_msr & 0xffffffff; + EDX = ecx404_msr >> 32; + break; + case 0x408: + EAX = ecx408_msr & 0xffffffff; + EDX = ecx408_msr >> 32; + break; + case 0x40c: + EAX = ecx40c_msr & 0xffffffff; + EDX = ecx40c_msr >> 32; + break; + case 0x410: + EAX = ecx410_msr & 0xffffffff; + EDX = ecx410_msr >> 32; + break; case 0x570: EAX = ecx570_msr & 0xffffffff; EDX = ecx570_msr >> 32; break; + case 0x1002ff: + EAX = ecx1002ff_msr & 0xffffffff; + EDX = ecx1002ff_msr >> 32; + break; + case 0xf0f00250: + EAX = ecxf0f00250_msr & 0xffffffff; + EDX = ecxf0f00250_msr >> 32; + break; + case 0xf0f00258: + EAX = ecxf0f00258_msr & 0xffffffff; + EDX = ecxf0f00258_msr >> 32; + break; default: i686_invalid_rdmsr: cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); @@ -3234,9 +3378,12 @@ void cpu_WRMSR() ecx17_msr = EAX | ((uint64_t)EDX << 32); break; case 0x1B: - /* pclog("APIC_BASE write: %08X%08X\n", EDX, EAX); */ + cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); // apic_base_msr = EAX | ((uint64_t)EDX << 32); break; + case 0x2A: + ecx2a_msr = EAX | ((uint64_t)EDX << 32); + break; case 0x79: ecx79_msr = EAX | ((uint64_t)EDX << 32); break; @@ -3319,9 +3466,30 @@ void cpu_WRMSR() case 0x2FF: mtrr_deftype_msr = EAX | ((uint64_t)EDX << 32); break; + case 0x404: + ecx404_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0x408: + ecx408_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0x40c: + ecx40c_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0x410: + ecx410_msr = EAX | ((uint64_t)EDX << 32); + break; case 0x570: ecx570_msr = EAX | ((uint64_t)EDX << 32); - break; + break; + case 0x1002ff: + ecx1002ff_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xf0f00250: + ecxf0f00250_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xf0f00258: + ecxf0f00258_msr = EAX | ((uint64_t)EDX << 32); + break; default: i686_invalid_wrmsr: cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); diff --git a/src/cpu_common/cpu.h b/src/cpu/cpu.h similarity index 96% rename from src/cpu_common/cpu.h rename to src/cpu/cpu.h index 9fb34d6b8..758b4294c 100644 --- a/src/cpu_common/cpu.h +++ b/src/cpu/cpu.h @@ -20,6 +20,16 @@ */ #ifndef EMU_CPU_H # define EMU_CPU_H + +enum { + FPU_NONE, + FPU_8087, + FPU_287, + FPU_287XL, + FPU_387, + FPU_INTERNAL +}; + enum { CPU_8088, /* 808x class CPUs */ CPU_8086, @@ -91,10 +101,16 @@ enum { #define CPU_REQUIRES_DYNAREC 2 #define CPU_ALTERNATE_XTAL 4 +typedef struct { + const char *name; + const char *internal_name; + const int type; +} FPU; typedef struct { const char *name; int cpu_type; + const FPU *fpus; int rspeed; double multi; uint32_t edx_reset; @@ -375,6 +391,7 @@ extern int cpu_16bitbus, cpu_64bitbus; extern int cpu_busspeed, cpu_pci_speed; extern int cpu_multi; extern double cpu_dmulti; +extern double fpu_multi; extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ @@ -574,5 +591,9 @@ extern int sysexit(uint32_t fetchdat); extern int syscall(uint32_t fetchdat); extern int sysret(uint32_t fetchdat); +extern int fpu_get_type(int machine, int cpu_manufacturer, int cpu, const char *internal_name); +extern const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int cpu, int type); +extern const char *fpu_get_name_from_index(int machine, int cpu_manufacturer, int cpu, int c); +extern int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c); #endif /*EMU_CPU_H*/ diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c new file mode 100644 index 000000000..71df19605 --- /dev/null +++ b/src/cpu/cpu_table.c @@ -0,0 +1,814 @@ +/* + * 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. + * + * Define all known processor types. + * + * Available cpuspeeds: + * + * 0 = 16 MHz + * 1 = 20 MHz + * 2 = 25 MHz + * 3 = 33 MHz + * 4 = 40 MHz + * 5 = 50 MHz + * 6 = 66 MHz + * 7 = 75 MHz + * 8 = 80 MHz + * 9 = 90 MHz + * 10 = 100 MHz + * 11 = 120 MHz + * 12 = 133 MHz + * 13 = 150 MHz + * 14 = 160 MHz + * 15 = 166 MHz + * 16 = 180 MHz + * 17 = 200 MHz + * + * + * + * Authors: Sarah Walker, + * leilei, + * Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 leilei. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + */ +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/machine.h> + +FPU fpus_none[] = +{ + {"None", "none", FPU_NONE}, + {NULL, NULL, 0} +}; +FPU fpus_8088[] = +{ + {"None", "none", FPU_NONE}, + {"8087", "8087", FPU_8087}, + {NULL, NULL, 0} +}; +FPU fpus_80286[] = +{ + {"None", "none", FPU_NONE}, + {"287", "287", FPU_287}, + {"287XL","287xl", FPU_287XL}, + {NULL, NULL, 0} +}; +FPU fpus_80386[] = +{ + {"None", "none", FPU_NONE}, + {"387", "387", FPU_387}, + {NULL, NULL, 0} +}; +FPU fpus_internal[] = +{ + {"Internal", "internal", FPU_INTERNAL}, + {NULL, NULL, 0} +}; + + +CPU cpus_8088[] = { + /*8088 standard*/ + {"8088/4.77", CPU_8088, fpus_8088, 4772728, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, fpus_8088, 7159092, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/8", CPU_8088, fpus_8088, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/10", CPU_8088, fpus_8088, 10000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, fpus_8088, 12000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, fpus_8088, 16000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_pcjr[] = { + /*8088 PCjr*/ + {"8088/4.77", CPU_8088, fpus_none, 4772728, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_europc[] = { + /*8088 EuroPC*/ + {"8088/4.77", CPU_8088, fpus_8088, 4772728, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, fpus_8088, 7159092, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8088/9.54", CPU_8088, fpus_8088, 9545456, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_8086[] = { + /*8086 standard*/ + {"8086/7.16", CPU_8086, fpus_8088, 7159092, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8086/8", CPU_8086, fpus_8088, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/9.54", CPU_8086, fpus_8088, 9545456, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8086/10", CPU_8086, fpus_8088, 10000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/12", CPU_8086, fpus_8088, 12000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/16", CPU_8086, fpus_8088, 16000000, 1, 0, 0, 0, 0, 0,0,0,0, 2}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_pc1512[] = { + /*8086 Amstrad*/ + {"8086/8", CPU_8086, fpus_8088, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_286[] = { + /*286*/ + {"286/6", CPU_286, fpus_80286, 6000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/8", CPU_286, fpus_80286, 8000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/10", CPU_286, fpus_80286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, fpus_80286, 12500000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, fpus_80286, 16000000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, fpus_80286, 20000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, fpus_80286, 25000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_ibmat[] = { + /*286*/ + {"286/6", CPU_286, fpus_80286, 6000000, 1, 0, 0, 0, 0, 3,3,3,3, 1}, + {"286/8", CPU_286, fpus_80286, 8000000, 1, 0, 0, 0, 0, 3,3,3,3, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_ibmxt286[] = { + /*286*/ + {"286/6", CPU_286, fpus_80286, 6000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_ps1_m2011[] = { + /*286*/ + {"286/10", CPU_286, fpus_80286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 9} +}; + +CPU cpus_ps2_m30_286[] = { + /*286*/ + {"286/10", CPU_286, fpus_80286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, fpus_80286, 12500000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, fpus_80286, 16000000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, fpus_80286, 20000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, fpus_80286, 25000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_i386SX[] = { + /*i386SX*/ + {"i386SX/16", CPU_386SX, fpus_80386, 16000000, 1, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"i386SX/20", CPU_386SX, fpus_80386, 20000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/25", CPU_386SX, fpus_80386, 25000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/33", CPU_386SX, fpus_80386, 33333333, 1, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"i386SX/40", CPU_386SX, fpus_80386, 40000000, 1, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_i386DX[] = { + /*i386DX/RapidCAD*/ + {"i386DX/16", CPU_386DX, fpus_80386, 16000000, 1, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"i386DX/20", CPU_386DX, fpus_80386, 20000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/25", CPU_386DX, fpus_80386, 25000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/33", CPU_386DX, fpus_80386, 33333333, 1, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"i386DX/40", CPU_386DX, fpus_80386, 40000000, 1, 0x0308, 0, 0, 0, 7,7,3,3, 5}, + {"RapidCAD/25", CPU_RAPIDCAD, fpus_internal, 25000000, 1, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"RapidCAD/33", CPU_RAPIDCAD, fpus_internal, 33333333, 1, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"RapidCAD/40", CPU_RAPIDCAD, fpus_internal, 40000000, 1, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + + +CPU cpus_Am386SX[] = { + /*Am386SX*/ + {"Am386SX/16", CPU_386SX, fpus_80386, 16000000, 1, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"Am386SX/20", CPU_386SX, fpus_80386, 20000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/25", CPU_386SX, fpus_80386, 25000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/33", CPU_386SX, fpus_80386, 33333333, 1, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386SX/40", CPU_386SX, fpus_80386, 40000000, 1, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_Am386DX[] = { + /*Am386DX*/ + {"Am386DX/25", CPU_386DX, fpus_80386, 25000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386DX/33", CPU_386DX, fpus_80386, 33333333, 1, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386DX/40", CPU_386DX, fpus_80386, 40000000, 1, 0x0308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_486SLC[] = { + /*Cx486SLC*/ + {"Cx486SLC/20", CPU_486SLC, fpus_80386, 20000000, 1, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/25", CPU_486SLC, fpus_80386, 25000000, 1, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/33", CPU_486SLC, fpus_80386, 33333333, 1, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, + {"Cx486SRx2/32", CPU_486SLC, fpus_80386, 32000000, 2, 0x406, 0, 0x0006, 0, 6,6,6,6, 4}, + {"Cx486SRx2/40", CPU_486SLC, fpus_80386, 40000000, 2, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"Cx486SRx2/50", CPU_486SLC, fpus_80386, 50000000, 2, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM386SLC[] = { + /*IBM 386SLC*/ + {"386SLC/16", CPU_IBM386SLC, fpus_80386, 16000000, 1, 0xA301, 0, 0, 0, 3,3,3,3, 2}, + {"386SLC/20", CPU_IBM386SLC, fpus_80386, 20000000, 1, 0xA301, 0, 0, 0, 4,4,3,3, 3}, + {"386SLC/25", CPU_IBM386SLC, fpus_80386, 25000000, 1, 0xA301, 0, 0, 0, 4,4,3,3, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM486SLC[] = { + /*IBM 486SLC*/ + {"486SLC/33", CPU_IBM486SLC, fpus_80386, 33333333, 1, 0xA401, 0, 0, 0, 6,6,3,3, 4}, + {"486SLC2/40", CPU_IBM486SLC, fpus_80386, 40000000, 2, 0xA421, 0, 0, 0, 7,7,6,6, 5}, + {"486SLC2/50", CPU_IBM486SLC, fpus_80386, 50000000, 2, 0xA421, 0, 0, 0, 8,8,6,6, 6}, + {"486SLC2/66", CPU_IBM486SLC, fpus_80386, 66666666, 2, 0xA421, 0, 0, 0, 12,12,6,6, 8}, + {"486SLC3/60", CPU_IBM486SLC, fpus_80386, 60000000, 3, 0xA439, 0, 0, 0, 12,12,9,9, 7}, + {"486SLC3/75", CPU_IBM486SLC, fpus_80386, 75000000, 3, 0xA439, 0, 0, 0, 12,12,9,9, 9}, + {"486SLC3/100", CPU_IBM486SLC, fpus_80386, 100000000, 3, 0xA439, 0, 0, 0, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM486BL[] = { + /*IBM Blue Lightning*/ + {"486BL2/50", CPU_IBM486BL, fpus_80386, 50000000, 2, 0xA439, 0, 0, 0, 8,8,6,6, 6}, + {"486BL2/66", CPU_IBM486BL, fpus_80386, 66666666, 2, 0xA439, 0, 0, 0, 12,12,6,6, 8}, + {"486BL3/75", CPU_IBM486BL, fpus_80386, 75000000, 3, 0xA439, 0, 0, 0, 12,12,9,9, 9}, + {"486BL3/100", CPU_IBM486BL, fpus_80386, 100000000, 3, 0xA439, 0, 0, 0, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_486DLC[] = { + /*Cx486DLC*/ + {"Cx486DLC/25", CPU_486DLC, fpus_80386, 25000000, 1, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3}, + {"Cx486DLC/33", CPU_486DLC, fpus_80386, 33333333, 1, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4}, + {"Cx486DLC/40", CPU_486DLC, fpus_80386, 40000000, 1, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5}, + {"Cx486DRx2/32", CPU_486DLC, fpus_80386, 32000000, 2, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4}, + {"Cx486DRx2/40", CPU_486DLC, fpus_80386, 40000000, 2, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, + {"Cx486DRx2/50", CPU_486DLC, fpus_80386, 50000000, 2, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, + {"Cx486DRx2/66", CPU_486DLC, fpus_80386, 66666666, 2, 0x407, 0, 0x0007, 0, 12,12,6,6, 8}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} +}; + +CPU cpus_i486S1[] = { + /*i486*/ + {"i486SX/16", CPU_i486SX, fpus_none, 16000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, + {"i486SX/20", CPU_i486SX, fpus_none, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/25", CPU_i486SX, fpus_none, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/33", CPU_i486SX, fpus_none, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486SX2/50", CPU_i486SX2, fpus_none, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_none, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, + {"i486DX/25", CPU_i486DX, fpus_internal, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486DX/33", CPU_i486DX, fpus_internal, 33333333, 1, 0x414, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486DX/50", CPU_i486DX, fpus_internal, 50000000, 1, 0x411, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, + {"i486DX2/40", CPU_i486DX2, fpus_internal, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, + {"i486DX2/50", CPU_i486DX2, fpus_internal, 50000000, 2, 0x433, 0x433, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486DX2/66", CPU_i486DX2, fpus_internal, 66666666, 2, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, + {"iDX4 OverDrive 75", CPU_iDX4, fpus_internal, 75000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*Only added the DX4 OverDrive as the others would be redundant*/ + {"iDX4 OverDrive 100", CPU_iDX4, fpus_internal, 100000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} +}; +CPU cpus_Am486S1[] = { + /*Am486*/ + {"Am486SX/33", CPU_Am486SX, fpus_none, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486SX/40", CPU_Am486SX, fpus_none, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486SX2/50", CPU_Am486SX2, fpus_none, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX2, fpus_none, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ + {"Am486DX/33", CPU_Am486DX, fpus_internal, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486DX/40", CPU_Am486DX, fpus_internal, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486DX2/50", CPU_Am486DX2, fpus_internal, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Am486DX2/66", CPU_Am486DX2, fpus_internal, 66666666, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486DX2/80", CPU_Am486DX2, fpus_internal, 80000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +CPU cpus_Cx486S1[] = { + /*Cyrix 486*/ + {"Cx486S/25", CPU_Cx486S, fpus_none, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"Cx486S/33", CPU_Cx486S, fpus_none, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486S/40", CPU_Cx486S, fpus_none, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX/33", CPU_Cx486DX, fpus_internal, 33333333, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486DX/40", CPU_Cx486DX, fpus_internal, 40000000, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX2/50", CPU_Cx486DX2, fpus_internal, 50000000, 2.0, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Cx486DX2/66", CPU_Cx486DX2, fpus_internal, 66666666, 2.0, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Cx486DX2/80", CPU_Cx486DX2, fpus_internal, 80000000, 2.0, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"", -1, 0, 0.0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_i486[] = { + /*i486/P24T*/ + {"i486SX/16", CPU_i486SX, fpus_none, 16000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 3, 3, 3, 3, 2}, + {"i486SX/20", CPU_i486SX, fpus_none, 20000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"i486SX/25", CPU_i486SX, fpus_none, 25000000, 1.0, 0x422, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"i486SX/33", CPU_i486SX, fpus_none, 33333333, 1.0, 0x42a, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"i486SX2/50", CPU_i486SX2, fpus_none, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_none, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8}, + {"i486DX/25", CPU_i486DX, fpus_internal, 25000000, 1.0, 0x404, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"i486DX/33", CPU_i486DX, fpus_internal, 33333333, 1.0, 0x414, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"i486DX/50", CPU_i486DX, fpus_internal, 50000000, 1.0, 0x411, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 6}, + {"i486DX2/40", CPU_i486DX2, fpus_internal, 40000000, 2.0, 0x430, 0x430, 0x0000, CPU_SUPPORTS_DYNAREC, 7, 7, 6, 6, 5}, + {"i486DX2/50", CPU_i486DX2, fpus_internal, 50000000, 2.0, 0x433, 0x433, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"i486DX2/66", CPU_i486DX2, fpus_internal, 66666666, 2.0, 0x435, 0x435, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"iDX4/75", CPU_iDX4, fpus_internal, 75000000, 3.0, 0x480, 0x480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, fpus_internal, 100000000, 3.0, 0x483, 0x483, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ + {"iDX4 OverDrive 75", CPU_iDX4, fpus_internal, 75000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, + {"iDX4 OverDrive 100", CPU_iDX4, fpus_internal, 100000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, + {"Pentium OverDrive 63", CPU_P24T, fpus_internal, 62500000, 2.5, 0x1531, 0x1531, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, + {"Pentium OverDrive 83", CPU_P24T, fpus_internal, 83333333, 2.5, 0x1532, 0x1532, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10}, + {"", -1, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Am486[] = { + /*Am486/5x86*/ + {"Am486SX/33", CPU_Am486SX, fpus_none, 33333333, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486SX/40", CPU_Am486SX, fpus_none, 40000000, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486SX2/50", CPU_Am486SX2, fpus_none, 50000000, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX2, fpus_none, 66666666, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486DX/33", CPU_Am486DX, fpus_internal, 33333333, 1.0, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486DX/40", CPU_Am486DX, fpus_internal, 40000000, 1.0, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486DX2/50", CPU_Am486DX2, fpus_internal, 50000000, 2.0, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Am486DX2/66", CPU_Am486DX2, fpus_internal, 66666666, 2.0, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486DX2/80", CPU_Am486DX2, fpus_internal, 80000000, 2.0, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"Am486DX4/75", CPU_Am486DX4, fpus_internal, 75000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, + {"Am486DX4/90", CPU_Am486DX4, fpus_internal, 90000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + {"Am486DX4/100", CPU_Am486DX4, fpus_internal, 100000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + {"Am486DX4/120", CPU_Am486DX4, fpus_internal, 120000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, + {"Am5x86/P75", CPU_Am5x86, fpus_internal, 133333333, 4.0, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, + {"Am5x86/P75+", CPU_Am5x86, fpus_internal, 150000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ + {"Am5x86/P90", CPU_Am5x86, fpus_internal, 160000000, 4.0, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Cx486[] = { + /*Cyrix 486*/ + {"Cx486S/25", CPU_Cx486S, fpus_none, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"Cx486S/33", CPU_Cx486S, fpus_none, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486S/40", CPU_Cx486S, fpus_none, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX/33", CPU_Cx486DX, fpus_internal, 33333333, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486DX/40", CPU_Cx486DX, fpus_internal, 40000000, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX2/50", CPU_Cx486DX2, fpus_internal, 50000000, 2.0, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Cx486DX2/66", CPU_Cx486DX2, fpus_internal, 66666666, 2.0, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Cx486DX2/80", CPU_Cx486DX2, fpus_internal, 80000000, 2.0, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"Cx486DX4/75", CPU_Cx486DX4, fpus_internal, 75000000, 3.0, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, + {"Cx486DX4/100", CPU_Cx486DX4, fpus_internal, 100000000, 3.0, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + + /*Cyrix 5x86*/ + {"Cx5x86/80", CPU_Cx5x86, fpus_internal, 80000000, 2.0, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, /*If we're including the Pentium 50, might as well include this*/ + {"Cx5x86/100", CPU_Cx5x86, fpus_internal, 100000000, 3.0, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + {"Cx5x86/120", CPU_Cx5x86, fpus_internal, 120000000, 3.0, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, + {"Cx5x86/133", CPU_Cx5x86, fpus_internal, 133333333, 4.0, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +CPU cpus_6x863V[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_6x86[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86L*/ + {"Cx6x86L/PR133+", CPU_Cx6x86L, fpus_internal, 110000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86L/PR150+", CPU_Cx6x86L, fpus_internal, 120000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86L/PR166+", CPU_Cx6x86L, fpus_internal, 133333333, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86L/PR200+", CPU_Cx6x86L, fpus_internal, 150000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86MX/MII*/ + {"Cx6x86MX/PR166", CPU_Cx6x86MX, fpus_internal, 133333333, 2.0, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86MX/PR200", CPU_Cx6x86MX, fpus_internal, 166666666, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Cx6x86MX/PR233", CPU_Cx6x86MX, fpus_internal, 187500000, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"Cx6x86MX/PR266", CPU_Cx6x86MX, fpus_internal, 208333333, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"MII/PR300", CPU_Cx6x86MX, fpus_internal, 233333333, 3.5, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"MII/PR333", CPU_Cx6x86MX, fpus_internal, 250000000, 3.0, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; + + CPU cpus_6x86SS7[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, fpus_internal, 80000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, fpus_internal, 100000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, fpus_internal, 110000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, fpus_internal, 120000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, fpus_internal, 133333333, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, fpus_internal, 150000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86L*/ + {"Cx6x86L/PR133+", CPU_Cx6x86L, fpus_internal, 110000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86L/PR150+", CPU_Cx6x86L, fpus_internal, 120000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86L/PR166+", CPU_Cx6x86L, fpus_internal, 133333333, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86L/PR200+", CPU_Cx6x86L, fpus_internal, 150000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86MX/MII*/ + {"Cx6x86MX/PR166", CPU_Cx6x86MX, fpus_internal, 133333333, 2.0, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86MX/PR200", CPU_Cx6x86MX, fpus_internal, 166666666, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Cx6x86MX/PR233", CPU_Cx6x86MX, fpus_internal, 187500000, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"Cx6x86MX/PR266", CPU_Cx6x86MX, fpus_internal, 208333333, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"MII/PR300", CPU_Cx6x86MX, fpus_internal, 233333333, 3.5, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"MII/PR333", CPU_Cx6x86MX, fpus_internal, 250000000, 3.0, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"MII/PR366", CPU_Cx6x86MX, fpus_internal, 250000000, 2.5, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, + {"MII/PR400", CPU_Cx6x86MX, fpus_internal, 285000000, 3.0, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, + {"MII/PR433", CPU_Cx6x86MX, fpus_internal, 300000000, 3.0, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; +#endif + +CPU cpus_WinChip[] = { + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, fpus_internal, 75000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, + {"WinChip 90", CPU_WINCHIP, fpus_internal, 90000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, + {"WinChip 100", CPU_WINCHIP, fpus_internal, 100000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, + {"WinChip 120", CPU_WINCHIP, fpus_internal, 120000000, 2.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, + {"WinChip 133", CPU_WINCHIP, fpus_internal, 133333333, 2.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, + {"WinChip 150", CPU_WINCHIP, fpus_internal, 150000000, 2.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, + {"WinChip 166", CPU_WINCHIP, fpus_internal, 166666666, 2.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, + {"WinChip 180", CPU_WINCHIP, fpus_internal, 180000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, + {"WinChip 200", CPU_WINCHIP, fpus_internal, 200000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 225", CPU_WINCHIP, fpus_internal, 225000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 240", CPU_WINCHIP, fpus_internal, 240000000, 4.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, + {"WinChip 2/200", CPU_WINCHIP2, fpus_internal, 200000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2/225", CPU_WINCHIP2, fpus_internal, 225000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 2/240", CPU_WINCHIP2, fpus_internal, 240000000, 4.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, fpus_internal, 250000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, fpus_internal, 200000000, 3.0, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2A/233", CPU_WINCHIP2, fpus_internal, 233333333, 3.5, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_WinChip_SS7[] = { + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, fpus_internal, 75000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, + {"WinChip 90", CPU_WINCHIP, fpus_internal, 90000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, + {"WinChip 100", CPU_WINCHIP, fpus_internal, 100000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, + {"WinChip 120", CPU_WINCHIP, fpus_internal, 120000000, 2.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, + {"WinChip 133", CPU_WINCHIP, fpus_internal, 133333333, 2.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, + {"WinChip 150", CPU_WINCHIP, fpus_internal, 150000000, 2.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, + {"WinChip 166", CPU_WINCHIP, fpus_internal, 166666666, 2.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, + {"WinChip 180", CPU_WINCHIP, fpus_internal, 180000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, + {"WinChip 200", CPU_WINCHIP, fpus_internal, 200000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 225", CPU_WINCHIP, fpus_internal, 225000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 240", CPU_WINCHIP, fpus_internal, 240000000, 4.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, + {"WinChip 2/200", CPU_WINCHIP2, fpus_internal, 200000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2/225", CPU_WINCHIP2, fpus_internal, 225000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*9}, + {"WinChip 2/240", CPU_WINCHIP2, fpus_internal, 240000000, 4.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, fpus_internal, 250000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, fpus_internal, 200000000, 3.0, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2A/233", CPU_WINCHIP2, fpus_internal, 233333333, 3.5, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, (7*8)/2}, + {"WinChip 2A/266", CPU_WINCHIP2, fpus_internal, 233333333, 7.0/3.0, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 7, 7, 28}, + {"WinChip 2A/300", CPU_WINCHIP2, fpus_internal, 250000000, 2.5, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium5V[] = { + /*Intel Pentium (5V, socket 4)*/ + {"Pentium 60", CPU_PENTIUM, fpus_internal, 60000000, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, + {"Pentium 66", CPU_PENTIUM, fpus_internal, 66666666, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8}, + {"Pentium OverDrive 120", CPU_PENTIUM, fpus_internal, 120000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"Pentium OverDrive 133", CPU_PENTIUM, fpus_internal, 133333333, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium5V50[] = { + /*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/ + {"Pentium 50 (Q0399)", CPU_PENTIUM, fpus_internal, 50000000, 1, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4,3,3, 6}, + {"Pentium 60", CPU_PENTIUM, fpus_internal, 60000000, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, + {"Pentium 66", CPU_PENTIUM, fpus_internal, 66666666, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8}, + {"Pentium OverDrive 100", CPU_PENTIUM, fpus_internal, 100000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8,6,6, 12}, + {"Pentium OverDrive 120", CPU_PENTIUM, fpus_internal, 120000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"Pentium OverDrive 133", CPU_PENTIUM, fpus_internal, 133333333, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_PentiumS5[] = { + /*Intel Pentium (Socket 5)*/ + {"Pentium 75", CPU_PENTIUM, fpus_internal, 75000000, 1.5, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, fpus_internal, 75000000, 1.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"Pentium 90", CPU_PENTIUM, fpus_internal, 90000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"Pentium 100/50", CPU_PENTIUM, fpus_internal, 100000000, 2.0, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12}, + {"Pentium 100/66", CPU_PENTIUM, fpus_internal, 100000000, 1.5, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"Pentium 120", CPU_PENTIUM, fpus_internal, 120000000, 2.0, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + + /*Intel Pentium OverDrive*/ + {"Pentium OverDrive 125", CPU_PENTIUM, fpus_internal, 125000000, 3.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16}, + {"Pentium OverDrive 150", CPU_PENTIUM, fpus_internal, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, fpus_internal, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, fpus_internal, 125000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, fpus_internal, 150000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, fpus_internal, 166000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, fpus_internal, 180000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, fpus_internal, 200000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"", -1, 0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium3V[] = { + /*Intel Pentium*/ + {"Pentium 75", CPU_PENTIUM, fpus_internal, 75000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, fpus_internal, 75000000, 1.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium 90", CPU_PENTIUM, fpus_internal, 90000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"Pentium 100/50", CPU_PENTIUM, fpus_internal, 100000000, 2.0, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Pentium 100/66", CPU_PENTIUM, fpus_internal, 100000000, 1.5, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"Pentium 120", CPU_PENTIUM, fpus_internal, 120000000, 2.0, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Pentium 133", CPU_PENTIUM, fpus_internal, 133333333, 2.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Pentium 150", CPU_PENTIUM, fpus_internal, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium 166", CPU_PENTIUM, fpus_internal, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium 200", CPU_PENTIUM, fpus_internal, 200000000, 3.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium OverDrive*/ + {"Pentium OverDrive 125", CPU_PENTIUM, fpus_internal, 125000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive 150", CPU_PENTIUM, fpus_internal, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, fpus_internal, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, fpus_internal, 125000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, fpus_internal, 150000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, fpus_internal, 166000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, fpus_internal, 180000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, fpus_internal, 200000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium[] = { + /*Intel Pentium*/ + {"Pentium 75", CPU_PENTIUM, fpus_internal, 75000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, fpus_internal, 75000000, 1.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium 90", CPU_PENTIUM, fpus_internal, 90000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"Pentium 100/50", CPU_PENTIUM, fpus_internal, 100000000, 2.0, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Pentium 100/66", CPU_PENTIUM, fpus_internal, 100000000, 1.5, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"Pentium 120", CPU_PENTIUM, fpus_internal, 120000000, 2.0, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Pentium 133", CPU_PENTIUM, fpus_internal, 133333333, 2.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Pentium 150", CPU_PENTIUM, fpus_internal, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium 166", CPU_PENTIUM, fpus_internal, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium 200", CPU_PENTIUM, fpus_internal, 200000000, 3.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium MMX*/ + {"Pentium MMX 166", CPU_PENTIUMMMX, fpus_internal, 166666666, 2.5, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium MMX 200", CPU_PENTIUMMMX, fpus_internal, 200000000, 3.0, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"Pentium MMX 233", CPU_PENTIUMMMX, fpus_internal, 233333333, 3.5, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + + /*Mobile Pentium*/ + {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, fpus_internal, 120000000, 2.0, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, fpus_internal, 133333333, 2.0, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, fpus_internal, 150000000, 2.5, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, fpus_internal, 166666666, 2.5, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, fpus_internal, 200000000, 3.0, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, fpus_internal, 233333333, 3.5, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, fpus_internal, 266666666, 4.0, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, fpus_internal, 300000000, 4.5, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + + /*Intel Pentium OverDrive*/ + {"Pentium OverDrive 125", CPU_PENTIUM, fpus_internal, 125000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive 150", CPU_PENTIUM, fpus_internal, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, fpus_internal, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, fpus_internal, 125000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, fpus_internal, 150000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, fpus_internal, 166000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, fpus_internal, 180000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, fpus_internal, 200000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"", -1, 0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) +CPU cpus_K5[] = { + /*AMD K5 (Socket 5)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, fpus_internal, 75000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, fpus_internal, 75000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, fpus_internal, 90000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, fpus_internal, 90000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, fpus_internal, 100000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, fpus_internal, 100000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"", -1, 0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + +CPU cpus_K56[] = { +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + /*AMD K5 (Socket 7)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, fpus_internal, 75000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, fpus_internal, 75000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, fpus_internal, 90000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, fpus_internal, 90000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, fpus_internal, 100000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, fpus_internal, 100000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, +#endif + + /*AMD K6 (Socket 7*/ + {"K6 (Model 6) 166", CPU_K6, fpus_internal, 166666666, 2.5, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K6 (Model 6) 200", CPU_K6, fpus_internal, 200000000, 3.0, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 6) 233", CPU_K6, fpus_internal, 233333333, 3.5, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6 (Model 7) 200", CPU_K6, fpus_internal, 200000000, 3.0, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 7) 233", CPU_K6, fpus_internal, 233333333, 3.5, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6 (Model 7) 266", CPU_K6, fpus_internal, 266666666, 4.0, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, + {"K6 (Model 7) 300", CPU_K6, fpus_internal, 300000000, 4.5, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, + + /*AMD K6-2 (Socket 7)*/ + {"K6-2/233", CPU_K6_2, fpus_internal, 233333333, 3.5, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, fpus_internal, 266666666, 4.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, + {"K6-2/300 AFR-66", CPU_K6_2, fpus_internal, 300000000, 4.5, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, + {"K6-2/366", CPU_K6_2, fpus_internal, 366666666, 5.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_K56_SS7[] = { +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + /*AMD K5 (Socket 7)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, fpus_internal, 75000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, fpus_internal, 75000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, fpus_internal, 90000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, fpus_internal, 90000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, fpus_internal, 100000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, fpus_internal, 100000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, fpus_internal, 120000000, 2.0, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, fpus_internal, 133333333, 2.0, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, fpus_internal, 150000000, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, fpus_internal, 166666666, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, fpus_internal, 200000000, 3.0, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, +#endif + + /*AMD K6 (Socket 7)*/ + {"K6 (Model 6) 166", CPU_K6, fpus_internal, 166666666, 2.5, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K6 (Model 6) 200", CPU_K6, fpus_internal, 200000000, 3.0, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 6) 233", CPU_K6, fpus_internal, 233333333, 3.5, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 200", CPU_K6, fpus_internal, 200000000, 3.0, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 7) 233", CPU_K6, fpus_internal, 233333333, 3.5, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 266", CPU_K6, fpus_internal, 266666666, 4.0, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6 (Model 7) 300", CPU_K6, fpus_internal, 300000000, 4.5, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + + /*AMD K6-2 (Socket 7/Super Socket 7)*/ + {"K6-2/233", CPU_K6_2, fpus_internal, 233333333, 3.5, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, fpus_internal, 266666666, 4.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, + {"K6-2/300", CPU_K6_2, fpus_internal, 300000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36}, + {"K6-2/333", CPU_K6_2, fpus_internal, 332500000, 3.5, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40}, + {"K6-2/350", CPU_K6_2C, fpus_internal, 350000000, 3.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42}, + {"K6-2/366", CPU_K6_2C, fpus_internal, 366666666, 5.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44}, + {"K6-2/380", CPU_K6_2C, fpus_internal, 380000000, 4.0, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46}, + {"K6-2/400", CPU_K6_2C, fpus_internal, 400000000, 4.0, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-2/450", CPU_K6_2C, fpus_internal, 450000000, 4.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2/475", CPU_K6_2C, fpus_internal, 475000000, 5.0, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2/500", CPU_K6_2C, fpus_internal, 500000000, 5.0, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2/533", CPU_K6_2C, fpus_internal, 533333333, 5.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2/550", CPU_K6_2C, fpus_internal, 550000000, 5.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + + /*AMD K6-2+/K6-3/K6-3+ (Super Socket 7)*/ + {"K6-2+/450", CPU_K6_2P, fpus_internal, 450000000, 4.5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2+/475", CPU_K6_2P, fpus_internal, 475000000, 5.0, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2+/500", CPU_K6_2P, fpus_internal, 500000000, 5.0, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2+/533", CPU_K6_2P, fpus_internal, 533333333, 5.5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2+/550", CPU_K6_2P, fpus_internal, 550000000, 5.5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + {"K6-III/400", CPU_K6_3, fpus_internal, 400000000, 4.0, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III/450", CPU_K6_3, fpus_internal, 450000000, 4.5, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/75", CPU_K6_3P, fpus_internal, 75000000, 1.5, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K6-III+/400", CPU_K6_3P, fpus_internal, 400000000, 4.0, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III+/450", CPU_K6_3P, fpus_internal, 450000000, 4.5, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/475", CPU_K6_3P, fpus_internal, 475000000, 5.0, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-III+/500", CPU_K6_3P, fpus_internal, 500000000, 5.0, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_PentiumPro[] = { + /*Intel Pentium Pro*/ + {"Pentium Pro 50", CPU_PENTIUMPRO, fpus_internal, 50000000, 1.0, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium Pro 60" , CPU_PENTIUMPRO, fpus_internal, 60000000, 1.0, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium Pro 66" , CPU_PENTIUMPRO, fpus_internal, 66666666, 1.0, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium Pro 75", CPU_PENTIUMPRO, fpus_internal, 75000000, 1.5, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium Pro 150", CPU_PENTIUMPRO, fpus_internal, 150000000, 2.5, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium Pro 166", CPU_PENTIUMPRO, fpus_internal, 166666666, 2.5, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium Pro 180", CPU_PENTIUMPRO, fpus_internal, 180000000, 3.0, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, + {"Pentium Pro 200", CPU_PENTIUMPRO, fpus_internal, 200000000, 3.0, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium II OverDrive*/ + {"Pentium II Overdrive 50", CPU_PENTIUM2D, fpus_internal, 50000000, 1.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Overdrive 60", CPU_PENTIUM2D, fpus_internal, 60000000, 1.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Overdrive 66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Overdrive 75", CPU_PENTIUM2D, fpus_internal, 75000000, 1.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Overdrive 210", CPU_PENTIUM2D, fpus_internal, 210000000, 3.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"Pentium II Overdrive 233", CPU_PENTIUM2D, fpus_internal, 233333333, 3.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Pentium II Overdrive 240", CPU_PENTIUM2D, fpus_internal, 240000000, 4.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29}, + {"Pentium II Overdrive 266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Pentium II Overdrive 270", CPU_PENTIUM2D, fpus_internal, 270000000, 4.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33}, + {"Pentium II Overdrive 300/66", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"Pentium II Overdrive 300/60", CPU_PENTIUM2D, fpus_internal, 300000000, 5.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"Pentium II Overdrive 333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_PentiumII66[] = { + /*Intel Pentium II Klamath*/ + {"Pentium II Klamath 50", CPU_PENTIUM2, fpus_internal, 50000000, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Klamath 60", CPU_PENTIUM2, fpus_internal, 60000000, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Klamath 66", CPU_PENTIUM2, fpus_internal, 66666666, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Klamath 75", CPU_PENTIUM2, fpus_internal, 75000000, 1.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Klamath 233", CPU_PENTIUM2, fpus_internal, 233333333, 3.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Pentium II Klamath 266", CPU_PENTIUM2, fpus_internal, 266666666, 4.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Pentium II Klamath 300/66", CPU_PENTIUM2, fpus_internal, 300000000, 4.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + + /*Intel Pentium II Deschutes*/ + {"Pentium II Deschutes 50", CPU_PENTIUM2D, fpus_internal, 50000000, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Deschutes 60", CPU_PENTIUM2D, fpus_internal, 60000000, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Deschutes 66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Deschutes 75", CPU_PENTIUM2D, fpus_internal, 75000000, 1.5, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Deschutes 266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Pentium II Deschutes 300/66", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"Pentium II Deschutes 333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +}; + +CPU cpus_PentiumII[] = { + /*Intel Pentium II Klamath*/ + {"Pentium II Klamath 50", CPU_PENTIUM2, fpus_internal, 50000000, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Klamath 60", CPU_PENTIUM2, fpus_internal, 60000000, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Klamath 66", CPU_PENTIUM2, fpus_internal, 66666666, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Klamath 75", CPU_PENTIUM2, fpus_internal, 75000000, 1.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Klamath 233", CPU_PENTIUM2, fpus_internal, 233333333, 3.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Pentium II Klamath 266", CPU_PENTIUM2, fpus_internal, 266666666, 4.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Pentium II Klamath 300/66", CPU_PENTIUM2, fpus_internal, 300000000, 4.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + + /*Intel Pentium II Deschutes*/ + {"Pentium II Deschutes 50", CPU_PENTIUM2D, fpus_internal, 50000000, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Deschutes 60", CPU_PENTIUM2D, fpus_internal, 60000000, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Deschutes 66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Deschutes 75", CPU_PENTIUM2D, fpus_internal, 75000000, 1.5, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Deschutes 266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Pentium II Deschutes 300/66", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"Pentium II Deschutes 333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"Pentium II Deschutes 350", CPU_PENTIUM2D, fpus_internal, 350000000, 3.5, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32,32,11,11, 42}, + {"Pentium II Deschutes 400", CPU_PENTIUM2D, fpus_internal, 400000000, 4.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, + {"Pentium II Deschutes 450", CPU_PENTIUM2D, fpus_internal, 450000000, 4.5, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41,41,14,14, 54}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +}; + +CPU cpus_Xeon[] = { + /* Slot 2 Xeons. Literal P2D's with more cache + The <400Mhz Xeons are only meant to not cause any struggle + to the recompiler. */ + {"Pentium II Xeon 75", CPU_PENTIUM2D, fpus_internal, 75000000, 1.5, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Xeon 133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Pentium II Xeon 166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium II Xeon 400", CPU_PENTIUM2D, fpus_internal, 400000000, 4.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Celeron[] = { + /* Mendocino Celerons. Exact architecture as the P2D series with their L2 cache on-dye. + Intended for the PGA370 boards but they were capable to fit on a PGA 370 to Slot 1 + adaptor card so they work on Slot 1 motherboards too!. + + The 100Mhz & 166Mhz Mendocino is only meant to not cause any struggle + to the recompiler. */ + {"Celeron Mendocino 100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Celeron Mendocino 166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Celeron Mendocino 300/66", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"Celeron Mendocino 333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"Celeron Mendocino 366", CPU_PENTIUM2D, fpus_internal, 366666666, 5.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33,17,17, 44}, + {"Celeron Mendocino 400", CPU_PENTIUM2D, fpus_internal, 400000000, 6.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, + {"Celeron Mendocino 433", CPU_PENTIUM2D, fpus_internal, 433333333, 6.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 39,39,13,13, 51}, + {"Celeron Mendocino 500", CPU_PENTIUM2D, fpus_internal, 500000000, 7.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45,45,15,15, 60}, + {"Celeron Mendocino 533", CPU_PENTIUM2D, fpus_internal, 533333333, 8.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48,48,17,17, 64}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Cyrix3[] = { + /*VIA Cyrix III (Samuel)*/ + {"Cyrix III 66", CPU_CYRIX3S, fpus_internal, 66666666, 1.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 8}, /*66 MHz version*/ + {"Cyrix III 233", CPU_CYRIX3S, fpus_internal, 233333333, 3.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, 28}, + {"Cyrix III 266", CPU_CYRIX3S, fpus_internal, 266666666, 4.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 32}, + {"Cyrix III 300", CPU_CYRIX3S, fpus_internal, 300000000, 4.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 27, 27, 13, 13, 36}, + {"Cyrix III 333", CPU_CYRIX3S, fpus_internal, 333333333, 5.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 30, 30, 15, 15, 40}, + {"Cyrix III 350", CPU_CYRIX3S, fpus_internal, 350000000, 3.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 32, 32, 11, 11, 42}, + {"Cyrix III 400", CPU_CYRIX3S, fpus_internal, 400000000, 4.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 36, 36, 12, 12, 48}, + {"Cyrix III 450", CPU_CYRIX3S, fpus_internal, 450000000, 4.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 41, 41, 14, 14, 54}, /*^ is lower P2 speeds to allow emulation below 466 mhz*/ + {"Cyrix III 500", CPU_CYRIX3S, fpus_internal, 500000000, 5.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 45, 45, 15, 15, 60}, + {"Cyrix III 550", CPU_CYRIX3S, fpus_internal, 550000000, 5.5, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 50, 50, 17, 17, 66}, + {"Cyrix III 600", CPU_CYRIX3S, fpus_internal, 600000000, 6.0, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 54, 54, 18, 18, 72}, + {"Cyrix III 650", CPU_CYRIX3S, fpus_internal, 650000000, 6.5, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 58, 58, 20, 20, 78}, + {"Cyrix III 700", CPU_CYRIX3S, fpus_internal, 700000000, 7.0, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 62, 62, 21, 21, 84}, + {"", -1, 0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; diff --git a/src/cpu_common/x86.h b/src/cpu/x86.h similarity index 100% rename from src/cpu_common/x86.h rename to src/cpu/x86.h diff --git a/src/cpu_common/x86_ops.h b/src/cpu/x86_ops.h similarity index 100% rename from src/cpu_common/x86_ops.h rename to src/cpu/x86_ops.h diff --git a/src/cpu_common/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h similarity index 100% rename from src/cpu_common/x86_ops_3dnow.h rename to src/cpu/x86_ops_3dnow.h diff --git a/src/cpu_common/x86_ops_amd.h b/src/cpu/x86_ops_amd.h similarity index 100% rename from src/cpu_common/x86_ops_amd.h rename to src/cpu/x86_ops_amd.h diff --git a/src/cpu_common/x86_ops_arith.h b/src/cpu/x86_ops_arith.h similarity index 100% rename from src/cpu_common/x86_ops_arith.h rename to src/cpu/x86_ops_arith.h diff --git a/src/cpu_common/x86_ops_atomic.h b/src/cpu/x86_ops_atomic.h similarity index 100% rename from src/cpu_common/x86_ops_atomic.h rename to src/cpu/x86_ops_atomic.h diff --git a/src/cpu_common/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h similarity index 100% rename from src/cpu_common/x86_ops_bcd.h rename to src/cpu/x86_ops_bcd.h diff --git a/src/cpu_common/x86_ops_bit.h b/src/cpu/x86_ops_bit.h similarity index 100% rename from src/cpu_common/x86_ops_bit.h rename to src/cpu/x86_ops_bit.h diff --git a/src/cpu_common/x86_ops_bitscan.h b/src/cpu/x86_ops_bitscan.h similarity index 100% rename from src/cpu_common/x86_ops_bitscan.h rename to src/cpu/x86_ops_bitscan.h diff --git a/src/cpu_common/x86_ops_flag.h b/src/cpu/x86_ops_flag.h similarity index 97% rename from src/cpu_common/x86_ops_flag.h rename to src/cpu/x86_ops_flag.h index 0d9db70a7..68f1bac2a 100644 --- a/src/cpu_common/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -99,7 +99,7 @@ static int opSAHF(uint32_t fetchdat) CLOCK_CYCLES(3); PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); -#ifdef USE_NEW_DYNAREC +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) codegen_flags_changed = 0; #endif @@ -182,7 +182,7 @@ static int opPOPF_286(uint32_t fetchdat) CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); -#ifdef USE_NEW_DYNAREC +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) codegen_flags_changed = 0; #endif @@ -242,7 +242,7 @@ static int opPOPF(uint32_t fetchdat) CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); -#ifdef USE_NEW_DYNAREC +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) codegen_flags_changed = 0; #endif @@ -276,7 +276,7 @@ static int opPOPFD(uint32_t fetchdat) CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); -#ifdef USE_NEW_DYNAREC +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) codegen_flags_changed = 0; #endif diff --git a/src/cpu_common/x86_ops_fpu.h b/src/cpu/x86_ops_fpu.h similarity index 100% rename from src/cpu_common/x86_ops_fpu.h rename to src/cpu/x86_ops_fpu.h diff --git a/src/cpu_common/x86_ops_i686.h b/src/cpu/x86_ops_i686.h similarity index 100% rename from src/cpu_common/x86_ops_i686.h rename to src/cpu/x86_ops_i686.h diff --git a/src/cpu_common/x86_ops_inc_dec.h b/src/cpu/x86_ops_inc_dec.h similarity index 100% rename from src/cpu_common/x86_ops_inc_dec.h rename to src/cpu/x86_ops_inc_dec.h diff --git a/src/cpu_common/x86_ops_int.h b/src/cpu/x86_ops_int.h similarity index 100% rename from src/cpu_common/x86_ops_int.h rename to src/cpu/x86_ops_int.h diff --git a/src/cpu_common/x86_ops_io.h b/src/cpu/x86_ops_io.h similarity index 100% rename from src/cpu_common/x86_ops_io.h rename to src/cpu/x86_ops_io.h diff --git a/src/cpu_common/x86_ops_jump.h b/src/cpu/x86_ops_jump.h similarity index 100% rename from src/cpu_common/x86_ops_jump.h rename to src/cpu/x86_ops_jump.h diff --git a/src/cpu_common/x86_ops_misc.h b/src/cpu/x86_ops_misc.h similarity index 100% rename from src/cpu_common/x86_ops_misc.h rename to src/cpu/x86_ops_misc.h diff --git a/src/cpu_common/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h similarity index 100% rename from src/cpu_common/x86_ops_mmx.h rename to src/cpu/x86_ops_mmx.h diff --git a/src/cpu_common/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h similarity index 100% rename from src/cpu_common/x86_ops_mmx_arith.h rename to src/cpu/x86_ops_mmx_arith.h diff --git a/src/cpu_common/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h similarity index 100% rename from src/cpu_common/x86_ops_mmx_cmp.h rename to src/cpu/x86_ops_mmx_cmp.h diff --git a/src/cpu_common/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h similarity index 100% rename from src/cpu_common/x86_ops_mmx_logic.h rename to src/cpu/x86_ops_mmx_logic.h diff --git a/src/cpu_common/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h similarity index 100% rename from src/cpu_common/x86_ops_mmx_mov.h rename to src/cpu/x86_ops_mmx_mov.h diff --git a/src/cpu_common/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h similarity index 100% rename from src/cpu_common/x86_ops_mmx_pack.h rename to src/cpu/x86_ops_mmx_pack.h diff --git a/src/cpu_common/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h similarity index 100% rename from src/cpu_common/x86_ops_mmx_shift.h rename to src/cpu/x86_ops_mmx_shift.h diff --git a/src/cpu_common/x86_ops_mov.h b/src/cpu/x86_ops_mov.h similarity index 100% rename from src/cpu_common/x86_ops_mov.h rename to src/cpu/x86_ops_mov.h diff --git a/src/cpu_common/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h similarity index 100% rename from src/cpu_common/x86_ops_mov_ctrl.h rename to src/cpu/x86_ops_mov_ctrl.h diff --git a/src/cpu_common/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h similarity index 100% rename from src/cpu_common/x86_ops_mov_seg.h rename to src/cpu/x86_ops_mov_seg.h diff --git a/src/cpu_common/x86_ops_movx.h b/src/cpu/x86_ops_movx.h similarity index 100% rename from src/cpu_common/x86_ops_movx.h rename to src/cpu/x86_ops_movx.h diff --git a/src/cpu_common/x86_ops_msr.h b/src/cpu/x86_ops_msr.h similarity index 96% rename from src/cpu_common/x86_ops_msr.h rename to src/cpu/x86_ops_msr.h index 4c9fd9fe5..6624218e4 100644 --- a/src/cpu_common/x86_ops_msr.h +++ b/src/cpu/x86_ops_msr.h @@ -14,8 +14,10 @@ static int opRDTSC(uint32_t fetchdat) EAX = tsc & 0xffffffff; EDX = tsc >> 32; CLOCK_CYCLES(1); +#ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); +#endif return 0; } diff --git a/src/cpu_common/x86_ops_mul.h b/src/cpu/x86_ops_mul.h similarity index 100% rename from src/cpu_common/x86_ops_mul.h rename to src/cpu/x86_ops_mul.h diff --git a/src/cpu_common/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h similarity index 100% rename from src/cpu_common/x86_ops_pmode.h rename to src/cpu/x86_ops_pmode.h diff --git a/src/cpu_common/x86_ops_prefix.h b/src/cpu/x86_ops_prefix.h similarity index 100% rename from src/cpu_common/x86_ops_prefix.h rename to src/cpu/x86_ops_prefix.h diff --git a/src/cpu_common/x86_ops_rep.h b/src/cpu/x86_ops_rep.h similarity index 100% rename from src/cpu_common/x86_ops_rep.h rename to src/cpu/x86_ops_rep.h diff --git a/src/cpu_common/x86_ops_ret.h b/src/cpu/x86_ops_ret.h similarity index 100% rename from src/cpu_common/x86_ops_ret.h rename to src/cpu/x86_ops_ret.h diff --git a/src/cpu_common/x86_ops_set.h b/src/cpu/x86_ops_set.h similarity index 100% rename from src/cpu_common/x86_ops_set.h rename to src/cpu/x86_ops_set.h diff --git a/src/cpu_common/x86_ops_stack.h b/src/cpu/x86_ops_stack.h similarity index 100% rename from src/cpu_common/x86_ops_stack.h rename to src/cpu/x86_ops_stack.h diff --git a/src/cpu_common/x86_ops_string.h b/src/cpu/x86_ops_string.h similarity index 100% rename from src/cpu_common/x86_ops_string.h rename to src/cpu/x86_ops_string.h diff --git a/src/cpu_common/x86_ops_xchg.h b/src/cpu/x86_ops_xchg.h similarity index 100% rename from src/cpu_common/x86_ops_xchg.h rename to src/cpu/x86_ops_xchg.h diff --git a/src/cpu_common/x86seg.h b/src/cpu/x86seg.h similarity index 100% rename from src/cpu_common/x86seg.h rename to src/cpu/x86seg.h diff --git a/src/cpu_common/x87.c b/src/cpu/x87.c similarity index 100% rename from src/cpu_common/x87.c rename to src/cpu/x87.c diff --git a/src/cpu_common/x87.h b/src/cpu/x87.h similarity index 100% rename from src/cpu_common/x87.h rename to src/cpu/x87.h diff --git a/src/cpu_common/x87_ops.h b/src/cpu/x87_ops.h similarity index 99% rename from src/cpu_common/x87_ops.h rename to src/cpu/x87_ops.h index 80560a8ae..0e0a07dd5 100644 --- a/src/cpu_common/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -22,6 +22,7 @@ */ #include #include +#include "x87_timings.h" #ifdef _MSC_VER # include #endif @@ -320,7 +321,7 @@ static __inline uint16_t x87_compare(double a, double b) if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) return C3; - if (!is386 && !(cpu_state.npxc & 0x1000) && + if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) eb = ea; @@ -357,7 +358,7 @@ static __inline uint16_t x87_compare(double a, double b) uint32_t result = 0; double ea = a, eb = b; - if (!is386 && !(cpu_state.npxc & 0x1000) && + if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) eb = ea; diff --git a/src/cpu_common/x87_ops_arith.h b/src/cpu/x87_ops_arith.h similarity index 83% rename from src/cpu_common/x87_ops_arith.h rename to src/cpu/x87_ops_arith.h index 853da6678..26a414f75 100644 --- a/src/cpu_common/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -1,4 +1,4 @@ -#define opFPU(name, optype, a_size, load_var, get, use_var) \ +#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ { \ optype t; \ @@ -12,7 +12,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ if ((cpu_state.npxc >> 10) & 3) \ fesetround(FE_TONEAREST); \ FP_TAG_VALID; \ - CLOCK_CYCLES(8); \ + CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ return 0; \ } \ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -24,7 +24,7 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - CLOCK_CYCLES(4); \ + CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \ return 0; \ } \ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -37,7 +37,7 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ x87_pop(); \ - CLOCK_CYCLES(4); \ + CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \ return 0; \ } \ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -49,7 +49,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), ST(0), use_var); \ FP_TAG_VALID; \ - CLOCK_CYCLES(73); \ + CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \ return 0; \ } \ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -61,7 +61,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), use_var, ST(0)); \ FP_TAG_VALID; \ - CLOCK_CYCLES(73); \ + CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \ return 0; \ } \ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -73,7 +73,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) *= use_var; \ FP_TAG_VALID; \ - CLOCK_CYCLES(11); \ + CLOCK_CYCLES(x87_timings.fmul ## cycle_postfix); \ return 0; \ } \ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -85,7 +85,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) -= use_var; \ FP_TAG_VALID; \ - CLOCK_CYCLES(8); \ + CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ return 0; \ } \ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -97,27 +97,27 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) = use_var - ST(0); \ FP_TAG_VALID; \ - CLOCK_CYCLES(8); \ + CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ return 0; \ } -opFPU(s, x87_ts, 16, t.i, geteal, t.s) +opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32) #ifndef FPU_8087 -opFPU(s, x87_ts, 32, t.i, geteal, t.s) +opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) #endif -opFPU(d, x87_td, 16, t.i, geteaq, t.d) +opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) #ifndef FPU_8087 -opFPU(d, x87_td, 32, t.i, geteaq, t.d) +opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) #endif -opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t) +opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16) #ifndef FPU_8087 -opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t) +opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16) #endif -opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t) +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) +opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32) #endif @@ -127,7 +127,7 @@ static int opFADD(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(0) + ST(fetchdat & 7); FP_TAG_VALID; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFADDr(uint32_t fetchdat) @@ -136,7 +136,7 @@ static int opFADDr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); FP_TAG_VALID_F; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFADDP(uint32_t fetchdat) @@ -146,7 +146,7 @@ static int opFADDP(uint32_t fetchdat) ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } @@ -157,7 +157,7 @@ static int opFCOM(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3; else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fcom); return 0; } @@ -168,7 +168,7 @@ static int opFCOMP(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fcom); return 0; } @@ -180,14 +180,14 @@ static int opFCOMPP(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); p = (uint64_t *)&ST(0); q = (uint64_t *)&ST(1); - if ((*p == ((uint64_t)1 << 63) && *q == 0) && is386) + if ((*p == ((uint64_t)1 << 63) && *q == 0) && (fpu_type >= FPU_287XL)) cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ else cpu_state.npxs |= x87_compare(ST(0), ST(1)); x87_pop(); x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fcom); return 0; } #ifndef FPU_8087 @@ -199,7 +199,7 @@ static int opFUCOMPP(uint32_t fetchdat) cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); x87_pop(); x87_pop(); - CLOCK_CYCLES(5); + CLOCK_CYCLES(x87_timings.fucom); return 0; } @@ -211,7 +211,7 @@ static int opFCOMI(uint32_t fetchdat) cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fcom); return 0; } static int opFCOMIP(uint32_t fetchdat) @@ -223,7 +223,7 @@ static int opFCOMIP(uint32_t fetchdat) if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fcom); return 0; } #endif @@ -234,7 +234,7 @@ static int opFDIV(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(0), ST(0), ST(fetchdat & 7)); FP_TAG_VALID; - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } static int opFDIVr(uint32_t fetchdat) @@ -243,7 +243,7 @@ static int opFDIVr(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); FP_TAG_VALID_F; - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } static int opFDIVP(uint32_t fetchdat) @@ -253,7 +253,7 @@ static int opFDIVP(uint32_t fetchdat) x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } @@ -263,7 +263,7 @@ static int opFDIVR(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(0), ST(fetchdat&7), ST(0)); FP_TAG_VALID; - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } static int opFDIVRr(uint32_t fetchdat) @@ -272,7 +272,7 @@ static int opFDIVRr(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); FP_TAG_VALID_F; - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } static int opFDIVRP(uint32_t fetchdat) @@ -282,7 +282,7 @@ static int opFDIVRP(uint32_t fetchdat) x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } @@ -292,7 +292,7 @@ static int opFMUL(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(0) * ST(fetchdat & 7); FP_TAG_VALID; - CLOCK_CYCLES(16); + CLOCK_CYCLES(x87_timings.fmul); return 0; } static int opFMULr(uint32_t fetchdat) @@ -301,7 +301,7 @@ static int opFMULr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); FP_TAG_VALID_F; - CLOCK_CYCLES(16); + CLOCK_CYCLES(x87_timings.fmul); return 0; } static int opFMULP(uint32_t fetchdat) @@ -311,7 +311,7 @@ static int opFMULP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(16); + CLOCK_CYCLES(x87_timings.fmul); return 0; } @@ -321,7 +321,7 @@ static int opFSUB(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(0) - ST(fetchdat & 7); FP_TAG_VALID; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFSUBr(uint32_t fetchdat) @@ -330,7 +330,7 @@ static int opFSUBr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); FP_TAG_VALID_F; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFSUBP(uint32_t fetchdat) @@ -340,7 +340,7 @@ static int opFSUBP(uint32_t fetchdat) ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } @@ -350,7 +350,7 @@ static int opFSUBR(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(fetchdat & 7) - ST(0); FP_TAG_VALID; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFSUBRr(uint32_t fetchdat) @@ -359,7 +359,7 @@ static int opFSUBRr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); FP_TAG_VALID_F; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFSUBRP(uint32_t fetchdat) @@ -369,7 +369,7 @@ static int opFSUBRP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } @@ -380,7 +380,7 @@ static int opFUCOM(uint32_t fetchdat) cpu_state.pc++; cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fucom); return 0; } @@ -391,7 +391,7 @@ static int opFUCOMP(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fucom); return 0; } @@ -403,7 +403,7 @@ static int opFUCOMI(uint32_t fetchdat) cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fucom); return 0; } static int opFUCOMIP(uint32_t fetchdat) @@ -415,7 +415,7 @@ static int opFUCOMIP(uint32_t fetchdat) if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fucom); return 0; } #endif diff --git a/src/cpu_common/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h similarity index 88% rename from src/cpu_common/x87_ops_loadstore.h rename to src/cpu/x87_ops_loadstore.h index 4d4983962..7f1cf4900 100644 --- a/src/cpu_common/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -23,7 +23,7 @@ static int opFILDiw_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; x87_push((double)temp); - CLOCK_CYCLES(13); + CLOCK_CYCLES(x87_timings.fild_16); return 0; } #ifndef FPU_8087 @@ -35,7 +35,7 @@ static int opFILDiw_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; x87_push((double)temp); - CLOCK_CYCLES(13); + CLOCK_CYCLES(x87_timings.fild_16); return 0; } #endif @@ -48,7 +48,7 @@ static int opFISTiw_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); seteaw((int16_t)temp64); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_16); return cpu_state.abrt; } #ifndef FPU_8087 @@ -60,7 +60,7 @@ static int opFISTiw_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); seteaw((int16_t)temp64); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_16); return cpu_state.abrt; } #endif @@ -74,7 +74,7 @@ static int opFISTPiw_a16(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_16); return 0; } #ifndef FPU_8087 @@ -87,7 +87,7 @@ static int opFISTPiw_a32(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_16); return 0; } #endif @@ -103,7 +103,7 @@ static int opFILDiq_a16(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = temp64; FP_TAG_DEFAULT; - CLOCK_CYCLES(10); + CLOCK_CYCLES(x87_timings.fild_64); return 0; } #ifndef FPU_8087 @@ -118,7 +118,7 @@ static int opFILDiq_a32(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = temp64; FP_TAG_DEFAULT; - CLOCK_CYCLES(10); + CLOCK_CYCLES(x87_timings.fild_64); return 0; } #endif @@ -147,6 +147,7 @@ static int FBSTP_a16(uint32_t fetchdat) if (ST(0) < 0.0) tempc |= 0x80; writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; x87_pop(); + CLOCK_CYCLES(x87_timings.fbstp); return 0; } #ifndef FPU_8087 @@ -174,6 +175,7 @@ static int FBSTP_a32(uint32_t fetchdat) if (ST(0) < 0.0) tempc |= 0x80; writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; x87_pop(); + CLOCK_CYCLES(x87_timings.fbstp); return 0; } #endif @@ -190,7 +192,7 @@ static int FISTPiq_a16(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_64); return 0; } #ifndef FPU_8087 @@ -206,7 +208,7 @@ static int FISTPiq_a32(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_64); return 0; } #endif @@ -219,7 +221,7 @@ static int opFILDil_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); templ = geteal(); if (cpu_state.abrt) return 1; x87_push((double)templ); - CLOCK_CYCLES(9); + CLOCK_CYCLES(x87_timings.fild_32); return 0; } #ifndef FPU_8087 @@ -231,7 +233,7 @@ static int opFILDil_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); templ = geteal(); if (cpu_state.abrt) return 1; x87_push((double)templ); - CLOCK_CYCLES(9); + CLOCK_CYCLES(x87_timings.fild_32); return 0; } #endif @@ -244,7 +246,7 @@ static int opFISTil_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); seteal((int32_t)temp64); - CLOCK_CYCLES(28); + CLOCK_CYCLES(x87_timings.fist_32); return cpu_state.abrt; } #ifndef FPU_8087 @@ -256,7 +258,7 @@ static int opFISTil_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); seteal((int32_t)temp64); - CLOCK_CYCLES(28); + CLOCK_CYCLES(x87_timings.fist_32); return cpu_state.abrt; } #endif @@ -270,7 +272,7 @@ static int opFISTPil_a16(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteal((int32_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(28); + CLOCK_CYCLES(x87_timings.fist_32); return 0; } #ifndef FPU_8087 @@ -283,7 +285,7 @@ static int opFISTPil_a32(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteal((int32_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(28); + CLOCK_CYCLES(x87_timings.fist_32); return 0; } #endif @@ -296,7 +298,7 @@ static int opFLDe_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t=x87_ld80(); if (cpu_state.abrt) return 1; x87_push(t); - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fld_80); return 0; } #ifndef FPU_8087 @@ -308,7 +310,7 @@ static int opFLDe_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t=x87_ld80(); if (cpu_state.abrt) return 1; x87_push(t); - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fld_80); return 0; } #endif @@ -320,7 +322,7 @@ static int opFSTPe_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fld_80); return 0; } #ifndef FPU_8087 @@ -331,7 +333,7 @@ static int opFSTPe_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fld_80); return 0; } #endif @@ -344,7 +346,7 @@ static int opFLDd_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t.i = geteaq(); if (cpu_state.abrt) return 1; x87_push(t.d); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fld_64); return 0; } #ifndef FPU_8087 @@ -356,7 +358,7 @@ static int opFLDd_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t.i = geteaq(); if (cpu_state.abrt) return 1; x87_push(t.d); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fld_64); return 0; } #endif @@ -369,7 +371,7 @@ static int opFSTd_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fst_64); return cpu_state.abrt; } #ifndef FPU_8087 @@ -381,7 +383,7 @@ static int opFSTd_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fst_64); return cpu_state.abrt; } #endif @@ -395,7 +397,7 @@ static int opFSTPd_a16(uint32_t fetchdat) t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fst_64); return 0; } #ifndef FPU_8087 @@ -408,7 +410,7 @@ static int opFSTPd_a32(uint32_t fetchdat) t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fst_64); return 0; } #endif @@ -421,7 +423,7 @@ static int opFLDs_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); ts.i = geteal(); if (cpu_state.abrt) return 1; x87_push((double)ts.s); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fld_32); return 0; } #ifndef FPU_8087 @@ -433,7 +435,7 @@ static int opFLDs_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); ts.i = geteal(); if (cpu_state.abrt) return 1; x87_push((double)ts.s); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fld_32); return 0; } #endif @@ -446,7 +448,7 @@ static int opFSTs_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); - CLOCK_CYCLES(7); + CLOCK_CYCLES(x87_timings.fst_32); return cpu_state.abrt; } #ifndef FPU_8087 @@ -458,7 +460,7 @@ static int opFSTs_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); - CLOCK_CYCLES(7); + CLOCK_CYCLES(x87_timings.fst_32); return cpu_state.abrt; } #endif @@ -472,7 +474,7 @@ static int opFSTPs_a16(uint32_t fetchdat) ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(7); + CLOCK_CYCLES(x87_timings.fst_32); return 0; } #ifndef FPU_8087 @@ -485,7 +487,7 @@ static int opFSTPs_a32(uint32_t fetchdat) ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(7); + CLOCK_CYCLES(x87_timings.fst_32); return 0; } #endif diff --git a/src/cpu_common/x87_ops_misc.h b/src/cpu/x87_ops_misc.h similarity index 93% rename from src/cpu_common/x87_ops_misc.h rename to src/cpu/x87_ops_misc.h index 1856a00e8..af7be0527 100644 --- a/src/cpu_common/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -15,7 +15,7 @@ static int opFSTSW_AX(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; AX = cpu_state.npxs; - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return 0; } #endif @@ -25,7 +25,7 @@ static int opFNOP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fnop); return 0; } @@ -34,7 +34,7 @@ static int opFCLEX(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; cpu_state.npxs &= 0xff00; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fnop); return 0; } @@ -58,7 +58,7 @@ static int opFINIT(uint32_t fetchdat) #endif cpu_state.TOP = 0; cpu_state.ismmx = 0; - CLOCK_CYCLES(17); + CLOCK_CYCLES(x87_timings.finit); CPU_BLOCK_END(); return 0; } @@ -73,7 +73,7 @@ static int opFFREE(uint32_t fetchdat) #else cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; #endif - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.ffree); return 0; } @@ -83,7 +83,7 @@ static int opFFREEP(uint32_t fetchdat) cpu_state.pc++; cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.ffree); return 0; } @@ -93,7 +93,7 @@ static int opFST(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fst); return 0; } @@ -104,7 +104,7 @@ static int opFSTP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; x87_pop(); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fst); return 0; } @@ -160,7 +160,7 @@ static int FSTOR() #endif cpu_state.ismmx = 1; - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + CLOCK_CYCLES(x87_timings.frstor); return cpu_state.abrt; } static int opFSTOR_a16(uint32_t fetchdat) @@ -330,7 +330,7 @@ static int FSAVE() cpu_state.TOP = 0; cpu_state.ismmx = 0; - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + CLOCK_CYCLES(x87_timings.fsave); return cpu_state.abrt; } static int opFSAVE_a16(uint32_t fetchdat) @@ -358,7 +358,7 @@ static int opFSTSW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return cpu_state.abrt; } #ifndef FPU_8087 @@ -368,7 +368,7 @@ static int opFSTSW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return cpu_state.abrt; } #endif @@ -386,7 +386,7 @@ static int opFLD(uint32_t fetchdat) x87_push(ST(fetchdat&7)); cpu_state.tag[cpu_state.TOP&7] = old_tag; cpu_state.MM[cpu_state.TOP&7].q = old_i64; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fld); return 0; } @@ -407,7 +407,7 @@ static int opFXCH(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fxch); return 0; } @@ -417,7 +417,7 @@ static int opFCHS(uint32_t fetchdat) cpu_state.pc++; ST(0) = -ST(0); FP_TAG_VALID; - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fchs); return 0; } @@ -427,7 +427,7 @@ static int opFABS(uint32_t fetchdat) cpu_state.pc++; ST(0) = fabs(ST(0)); FP_TAG_VALID; - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fabs); return 0; } @@ -438,7 +438,7 @@ static int opFTST(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); if (ST(0) == 0.0) cpu_state.npxs |= C3; else if (ST(0) < 0.0) cpu_state.npxs |= C0; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.ftst); return 0; } @@ -455,7 +455,7 @@ static int opFXAM(uint32_t fetchdat) else if (ST(0) == 0.0) cpu_state.npxs |= C3; else cpu_state.npxs |= C2; if (ST(0) < 0.0) cpu_state.npxs |= C1; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fxam); return 0; } @@ -464,7 +464,7 @@ static int opFLD1(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(1.0); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fld_z1); return 0; } @@ -473,7 +473,7 @@ static int opFLDL2T(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(3.3219280948873623); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -482,7 +482,7 @@ static int opFLDL2E(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(1.4426950408889634); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -491,7 +491,7 @@ static int opFLDPI(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(3.141592653589793); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -500,7 +500,7 @@ static int opFLDEG2(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(0.3010299956639812); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -509,7 +509,7 @@ static int opFLDLN2(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push_u64(0x3fe62e42fefa39f0ull); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -519,7 +519,7 @@ static int opFLDZ(uint32_t fetchdat) cpu_state.pc++; x87_push(0.0); FP_TAG_VALID; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fld_z1); return 0; } @@ -529,7 +529,7 @@ static int opF2XM1(uint32_t fetchdat) cpu_state.pc++; ST(0) = pow(2.0, ST(0)) - 1.0; FP_TAG_VALID; - CLOCK_CYCLES(200); + CLOCK_CYCLES(x87_timings.f2xm1); return 0; } @@ -540,7 +540,7 @@ static int opFYL2X(uint32_t fetchdat) ST(1) = ST(1) * (log(ST(0)) / log(2.0)); FP_TAG_VALID_N; x87_pop(); - CLOCK_CYCLES(250); + CLOCK_CYCLES(x87_timings.fyl2x); return 0; } @@ -551,7 +551,7 @@ static int opFYL2XP1(uint32_t fetchdat) ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); FP_TAG_VALID_N; x87_pop(); - CLOCK_CYCLES(250); + CLOCK_CYCLES(x87_timings.fyl2xp1); return 0; } @@ -563,7 +563,7 @@ static int opFPTAN(uint32_t fetchdat) FP_TAG_VALID; x87_push(1.0); cpu_state.npxs &= ~C2; - CLOCK_CYCLES(235); + CLOCK_CYCLES(x87_timings.fptan); return 0; } @@ -574,7 +574,7 @@ static int opFPATAN(uint32_t fetchdat) ST(1) = atan2(ST(1), ST(0)); FP_TAG_VALID_N; x87_pop(); - CLOCK_CYCLES(250); + CLOCK_CYCLES(x87_timings.fpatan); return 0; } @@ -587,7 +587,7 @@ static int opFDECSTP(uint32_t fetchdat) #else cpu_state.TOP = (cpu_state.TOP - 1) & 7; #endif - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fincdecstp); return 0; } @@ -600,7 +600,7 @@ static int opFINCSTP(uint32_t fetchdat) #else cpu_state.TOP = (cpu_state.TOP + 1) & 7; #endif - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fincdecstp); return 0; } @@ -616,7 +616,7 @@ static int opFPREM(uint32_t fetchdat) if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES(100); + CLOCK_CYCLES(x87_timings.fprem); return 0; } #ifndef FPU_8087 @@ -632,7 +632,7 @@ static int opFPREM1(uint32_t fetchdat) if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES(100); + CLOCK_CYCLES(x87_timings.fprem1); return 0; } #endif @@ -643,7 +643,7 @@ static int opFSQRT(uint32_t fetchdat) cpu_state.pc++; ST(0) = sqrt(ST(0)); FP_TAG_VALID; - CLOCK_CYCLES(83); + CLOCK_CYCLES(x87_timings.fsqrt); return 0; } @@ -658,7 +658,7 @@ static int opFSINCOS(uint32_t fetchdat) FP_TAG_VALID; x87_push(cos(td)); cpu_state.npxs &= ~C2; - CLOCK_CYCLES(330); + CLOCK_CYCLES(x87_timings.fsincos); return 0; } #endif @@ -669,7 +669,7 @@ static int opFRNDINT(uint32_t fetchdat) cpu_state.pc++; ST(0) = (double)x87_fround(ST(0)); FP_TAG_VALID; - CLOCK_CYCLES(21); + CLOCK_CYCLES(x87_timings.frndint); return 0; } @@ -681,7 +681,7 @@ static int opFSCALE(uint32_t fetchdat) temp64 = (int64_t)ST(1); ST(0) = ST(0) * pow(2.0, (double)temp64); FP_TAG_VALID; - CLOCK_CYCLES(30); + CLOCK_CYCLES(x87_timings.fscale); return 0; } @@ -693,7 +693,7 @@ static int opFSIN(uint32_t fetchdat) ST(0) = sin(ST(0)); FP_TAG_VALID; cpu_state.npxs &= ~C2; - CLOCK_CYCLES(300); + CLOCK_CYCLES(x87_timings.fsin_cos); return 0; } @@ -704,7 +704,7 @@ static int opFCOS(uint32_t fetchdat) ST(0) = cos(ST(0)); FP_TAG_VALID; cpu_state.npxs &= ~C2; - CLOCK_CYCLES(300); + CLOCK_CYCLES(x87_timings.fsin_cos); return 0; } #endif @@ -732,7 +732,7 @@ static int FLDENV() cpu_state.TOP = (cpu_state.npxs >> 11) & 7; break; } - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + CLOCK_CYCLES(x87_timings.fldenv); return cpu_state.abrt; } @@ -765,7 +765,7 @@ static int opFLDCW_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fldcw); return 0; } #ifndef FPU_8087 @@ -779,7 +779,7 @@ static int opFLDCW_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fldcw); return 0; } #endif @@ -823,7 +823,7 @@ static int FSTENV() writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); break; } - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + CLOCK_CYCLES(x87_timings.fstenv); return cpu_state.abrt; } @@ -852,7 +852,7 @@ static int opFSTCW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(cpu_state.npxc); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return cpu_state.abrt; } #ifndef FPU_8087 @@ -862,7 +862,7 @@ static int opFSTCW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(cpu_state.npxc); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return cpu_state.abrt; } #endif diff --git a/src/cpu/x87_timings.c b/src/cpu/x87_timings.c new file mode 100644 index 000000000..7443aae72 --- /dev/null +++ b/src/cpu/x87_timings.c @@ -0,0 +1,315 @@ +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/machine.h> +#include "x87_timings.h" + +x87_timings_t x87_timings; + +const x87_timings_t x87_timings_8087 = +{ + .f2xm1 = (310 + 630) / 2, + .fabs = (10 + 17) / 2, + .fadd = (70 + 100) / 2, + .fadd_32 = (90 + 120) / 2, + .fadd_64 = (95 + 125) / 2, + .fbld = (290 + 310) / 2, + .fbstp = (520 + 540) / 2, + .fchs = (10 + 17) / 2, + .fclex = (2 + 8) / 2, + .fcom = (40 + 50) / 2, + .fcom_32 = (60 + 70) / 2, + .fcom_64 = (65 + 75) / 2, + .fcos = 0, /*387+*/ + .fincdecstp = (6 + 12) / 2, + .fdisi_eni = (6 + 12) / 2, + .fdiv = (193 + 203) / 2, + .fdiv_32 = (215 + 225) / 2, + .fdiv_64 = (220 + 230) / 2, + .ffree = (9 + 16) / 2, + .fadd_i16 = (102 + 137) / 2, + .fadd_i32 = (108 + 143) / 2, + .fcom_i16 = (72 + 86) / 2, + .fcom_i32 = (78 + 91) / 2, + .fdiv_i16 = (224 + 238) / 2, + .fdiv_i32 = (230 + 243) / 2, + .fild_16 = (46 + 54) / 2, + .fild_32 = (50 + 60) / 2, + .fild_64 = (60 + 68) / 2, + .fmul_i16 = (124 + 138) / 2, + .fmul_i32 = (130 + 144) / 2, + .finit = (2 + 8) / 2, + .fist_16 = (80 + 90) / 2, + .fist_32 = (82 + 92) / 2, + .fist_64 = (94 + 105) / 2, + .fld = (17 + 22) / 2, + .fld_32 = (38 + 56) / 2, + .fld_64 = (40 + 60) / 2, + .fld_80 = (53 + 65) / 2, + .fld_z1 = (11 + 21) / 2, + .fld_const = (15 + 24) / 2, + .fldcw = (7 + 14) / 2, + .fldenv = (35 + 45) / 2, + .fmul = (90 + 145) / 2, + .fmul_32 = (110 + 125) / 2, + .fmul_64 = (154 + 168) / 2, + .fnop = (10 + 16) / 2, + .fpatan = (250 + 800) / 2, + .fprem = (15 + 190) / 2, + .fprem1 = 0, /*387+*/ + .fptan = (30 + 540) / 2, + .frndint = (16 + 50) / 2, + .frstor = (197 + 207) / 2, + .fsave = (197 + 207) / 2, + .fscale = (32 + 38) / 2, + .fsetpm = 0, /*287+*/ + .fsin_cos = 0, /*387+*/ + .fsincos = 0, /*387+*/ + .fsqrt = (180 + 186) / 2, + .fst = (15 + 22) / 2, + .fst_32 = (84 + 90) / 2, + .fst_64 = (96 + 104) / 2, + .fst_80 = (52 + 58) / 2, + .fstcw_sw = (12 + 18) / 2, + .fstenv = (40 + 50) / 2, + .ftst = (38 + 48) / 2, + .fucom = 0, /*387+*/ + .fwait = 4, + .fxam = (12 + 23) / 2, + .fxch = (10 + 15) / 2, + .fxtract = (27 + 55) / 2, + .fyl2x = (900 + 1100) / 2, + .fyl2xp1 = (700 + 1000) / 2 +}; + +/*Mostly the same as 8087*/ +const x87_timings_t x87_timings_287 = +{ + .f2xm1 = (310 + 630) / 2, + .fabs = (10 + 17) / 2, + .fadd = (70 + 100) / 2, + .fadd_32 = (90 + 120) / 2, + .fadd_64 = (95 + 125) / 2, + .fbld = (290 + 310) / 2, + .fbstp = (520 + 540) / 2, + .fchs = (10 + 17) / 2, + .fclex = (2 + 8) / 2, + .fcom = (40 + 50) / 2, + .fcom_32 = (60 + 70) / 2, + .fcom_64 = (65 + 75) / 2, + .fcos = 0, /*387+*/ + .fincdecstp = (6 + 12) / 2, + .fdisi_eni = 2, + .fdiv = (193 + 203) / 2, + .fdiv_32 = (215 + 225) / 2, + .fdiv_64 = (220 + 230) / 2, + .ffree = (9 + 16) / 2, + .fadd_i16 = (102 + 137) / 2, + .fadd_i32 = (108 + 143) / 2, + .fcom_i16 = (72 + 86) / 2, + .fcom_i32 = (78 + 91) / 2, + .fdiv_i16 = (224 + 238) / 2, + .fdiv_i32 = (230 + 243) / 2, + .fild_16 = (46 + 54) / 2, + .fild_32 = (50 + 60) / 2, + .fild_64 = (60 + 68) / 2, + .fmul_i16 = (124 + 138) / 2, + .fmul_i32 = (130 + 144) / 2, + .finit = (2 + 8) / 2, + .fist_16 = (80 + 90) / 2, + .fist_32 = (82 + 92) / 2, + .fist_64 = (94 + 105) / 2, + .fld = (17 + 22) / 2, + .fld_32 = (38 + 56) / 2, + .fld_64 = (40 + 60) / 2, + .fld_80 = (53 + 65) / 2, + .fld_z1 = (11 + 21) / 2, + .fld_const = (15 + 24) / 2, + .fldcw = (7 + 14) / 2, + .fldenv = (35 + 45) / 2, + .fmul = (90 + 145) / 2, + .fmul_32 = (110 + 125) / 2, + .fmul_64 = (154 + 168) / 2, + .fnop = (10 + 16) / 2, + .fpatan = (250 + 800) / 2, + .fprem = (15 + 190) / 2, + .fprem1 = 0, /*387+*/ + .fptan = (30 + 540) / 2, + .frndint = (16 + 50) / 2, + .frstor = (197 + 207) / 2, + .fsave = (197 + 207) / 2, + .fscale = (32 + 38) / 2, + .fsetpm = (2 + 8) / 2, /*287+*/ + .fsin_cos = 0, /*387+*/ + .fsincos = 0, /*387+*/ + .fsqrt = (180 + 186) / 2, + .fst = (15 + 22) / 2, + .fst_32 = (84 + 90) / 2, + .fst_64 = (96 + 104) / 2, + .fst_80 = (52 + 58) / 2, + .fstcw_sw = (12 + 18) / 2, + .fstenv = (40 + 50) / 2, + .ftst = (38 + 48) / 2, + .fucom = 0, /*387+*/ + .fwait = 3, + .fxam = (12 + 23) / 2, + .fxch = (10 + 15) / 2, + .fxtract = (27 + 55) / 2, + .fyl2x = (900 + 1100) / 2, + .fyl2xp1 = (700 + 1000) / 2 +}; + +const x87_timings_t x87_timings_387 = +{ + .f2xm1 = (211 + 476) / 2, + .fabs = 22, + .fadd = (23 + 34) / 2, + .fadd_32 = (24 + 32) / 2, + .fadd_64 = (29 + 37) / 2, + .fbld = (266 + 275) / 2, + .fbstp = (512 + 534) / 2, + .fchs = (24 + 25) / 2, + .fclex = 11, + .fcom = 24, + .fcom_32 = 26, + .fcom_64 = 31, + .fcos = (122 + 772) / 2, + .fincdecstp = 22, + .fdisi_eni = 2, + .fdiv = (88 + 91) / 2, + .fdiv_32 = 89, + .fdiv_64 = 94, + .ffree = 18, + .fadd_i16 = (71 + 85) / 2, + .fadd_i32 = (57 + 72) / 2, + .fcom_i16 = (71 + 75) / 2, + .fcom_i32 = (56 + 63) / 2, + .fdiv_i16 = (136 + 140) / 2, + .fdiv_i32 = (120 + 127) / 2, + .fild_16 = (61 + 65) / 2, + .fild_32 = (45 + 52) / 2, + .fild_64 = (56 + 67) / 2, + .fmul_i16 = (76 + 87) / 2, + .fmul_i32 = (61 + 82) / 2, + .finit = 33, + .fist_16 = (82 + 95) / 2, + .fist_32 = (79 + 93) / 2, + .fist_64 = (80 + 97) / 2, + .fld = 14, + .fld_32 = 20, + .fld_64 = 25, + .fld_80 = 44, + .fld_z1 = (20 + 24) / 2, + .fld_const = 40, + .fldcw = 19, + .fldenv = 71, + .fmul = (29 + 57) / 2, + .fmul_32 = (27 + 35) / 2, + .fmul_64 = (32 + 57) / 2, + .fnop = 12, + .fpatan = (314 + 487) / 2, + .fprem = (74 + 155) / 2, + .fprem1 = (95 + 185) / 2, + .fptan = (191 + 497) / 2, + .frndint = (66 + 80) / 2, + .frstor = 308, + .fsave = 375, + .fscale = (67 + 86) / 2, + .fsetpm = 12, + .fsin_cos = (122 + 771) / 2, + .fsincos = (194 + 809) / 2, + .fsqrt = (122 + 129) / 2, + .fst = 11, + .fst_32 = 44, + .fst_64 = 45, + .fst_80 = 53, + .fstcw_sw = 15, + .fstenv = 103, + .ftst = 28, + .fucom = 24, + .fwait = 6, + .fxam = (30 + 38) / 2, + .fxch = 18, + .fxtract = (70 + 76) / 2, + .fyl2x = (120 + 538) / 2, + .fyl2xp1 = (257 + 547) / 2 +}; + +const x87_timings_t x87_timings_486 = +{ + .f2xm1 = (140 + 270) / 2, + .fabs = 3, + .fadd = (8 + 20) / 2, + .fadd_32 = (8 + 20) / 2, + .fadd_64 = (8 + 20) / 2, + .fbld = (70 + 103) / 2, + .fbstp = (172 + 176) / 2, + .fchs = 6, + .fclex = 7, + .fcom = 4, + .fcom_32 = 4, + .fcom_64 = 4, + .fcos = (257 + 354) / 2, + .fincdecstp = 3, + .fdisi_eni = 3, + .fdiv = 73, + .fdiv_32 = 73, + .fdiv_64 = 73, + .ffree = 3, + .fadd_i16 = (20 + 35) / 2, + .fadd_i32 = (19 + 32) / 2, + .fcom_i16 = (16 + 20) / 2, + .fcom_i32 = (15 + 17) / 2, + .fdiv_i16 = (85 + 89) / 2, + .fdiv_i32 = (84 + 86) / 2, + .fild_16 = (13 + 16) / 2, + .fild_32 = (9 + 12) / 2, + .fild_64 = (10 + 18) / 2, + .fmul_i16 = (23 + 27) / 2, + .fmul_i32 = (22 + 24) / 2, + .finit = 17, + .fist_16 = (29 + 34) / 2, + .fist_32 = (28 + 34) / 2, + .fist_64 = (29 + 34) / 2, + .fld = 4, + .fld_32 = 3, + .fld_64 = 3, + .fld_80 = 6, + .fld_z1 = 4, + .fld_const = 8, + .fldcw = 4, + .fldenv = 34, + .fmul = 16, + .fmul_32 = 11, + .fmul_64 = 14, + .fnop = 3, + .fpatan = (218 + 303) / 2, + .fprem = (70 + 138) / 2, + .fprem1 = (72 + 167) / 2, + .fptan = (200 + 273) / 2, + .frndint = (21 + 30) / 2, + .frstor = 120, + .fsave = 143, + .fscale = (30 + 32) / 2, + .fsetpm = 3, + .fsin_cos = (257 + 354) / 2, + .fsincos = (292 + 365) / 2, + .fsqrt = (83 + 87) / 2, + .fst = 3, + .fst_32 = 7, + .fst_64 = 8, + .fst_80 = 6, + .fstcw_sw = 3, + .fstenv = 56, + .ftst = 4, + .fucom = 4, + .fwait = (1 + 3) / 2, + .fxam = 8, + .fxch = 4, + .fxtract = (16 + 20) / 2, + .fyl2x = (196 + 329) / 2, + .fyl2xp1 = (171 + 326) / 2 +}; diff --git a/src/cpu/x87_timings.h b/src/cpu/x87_timings.h new file mode 100644 index 000000000..ec4f8ceca --- /dev/null +++ b/src/cpu/x87_timings.h @@ -0,0 +1,56 @@ +typedef struct +{ + int f2xm1; + int fabs; + int fadd, fadd_32, fadd_64; + int fbld; + int fbstp; + int fchs; + int fclex; + int fcom, fcom_32, fcom_64; + int fcos; + int fincdecstp; + int fdisi_eni; + int fdiv, fdiv_32, fdiv_64; + int ffree; + int fadd_i16, fadd_i32; + int fcom_i16, fcom_i32; + int fdiv_i16, fdiv_i32; + int fild_16, fild_32, fild_64; + int fmul_i16, fmul_i32; + int finit; + int fist_16, fist_32, fist_64; + int fld, fld_32, fld_64, fld_80; + int fld_z1, fld_const; + int fldcw; + int fldenv; + int fmul, fmul_32, fmul_64; + int fnop; + int fpatan; + int fprem, fprem1; + int fptan; + int frndint; + int frstor; + int fsave; + int fscale; + int fsetpm; + int fsin_cos, fsincos; + int fsqrt; + int fst, fst_32, fst_64, fst_80; + int fstcw_sw; + int fstenv; + int ftst; + int fucom; + int fwait; + int fxam; + int fxch; + int fxtract; + int fyl2x, fyl2xp1; +} x87_timings_t; + +extern const x87_timings_t x87_timings_8087; +extern const x87_timings_t x87_timings_287; +extern const x87_timings_t x87_timings_387; +extern const x87_timings_t x87_timings_486; + +extern x87_timings_t x87_timings; \ No newline at end of file diff --git a/src/cpu_common/cpu_table.c b/src/cpu_common/cpu_table.c deleted file mode 100644 index 41cea5233..000000000 --- a/src/cpu_common/cpu_table.c +++ /dev/null @@ -1,779 +0,0 @@ -/* - * 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. - * - * Define all known processor types. - * - * Available cpuspeeds: - * - * 0 = 16 MHz - * 1 = 20 MHz - * 2 = 25 MHz - * 3 = 33 MHz - * 4 = 40 MHz - * 5 = 50 MHz - * 6 = 66 MHz - * 7 = 75 MHz - * 8 = 80 MHz - * 9 = 90 MHz - * 10 = 100 MHz - * 11 = 120 MHz - * 12 = 133 MHz - * 13 = 150 MHz - * 14 = 160 MHz - * 15 = 166 MHz - * 16 = 180 MHz - * 17 = 200 MHz - * - * - * - * Authors: Sarah Walker, - * leilei, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 leilei. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/machine.h> - - -CPU cpus_8088[] = { - /*8088 standard*/ - {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_pcjr[] = { - /*8088 PCjr*/ - {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_europc[] = { - /*8088 EuroPC*/ - {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8088/9.54", CPU_8088, 9545456, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_8086[] = { - /*8086 standard*/ - {"8086/7.16", CPU_8086, 7159092, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/9.54", CPU_8086, 9545456, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8086/10", CPU_8086, 10000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/12", CPU_8086, 12000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/16", CPU_8086, 16000000, 1, 0, 0, 0, 0, 0,0,0,0, 2}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_pc1512[] = { - /*8086 Amstrad*/ - {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_286[] = { - /*286*/ - {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, - {"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_ibmat[] = { - /*286*/ - {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 3,3,3,3, 1}, - {"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 3,3,3,3, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_ibmxt286[] = { - /*286*/ - {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_ps1_m2011[] = { - /*286*/ - {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 9} -}; - -CPU cpus_ps2_m30_286[] = { - /*286*/ - {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, - {"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_i386SX[] = { - /*i386SX*/ - {"i386SX/16", CPU_386SX, 16000000, 1, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"i386SX/20", CPU_386SX, 20000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"i386SX/25", CPU_386SX, 25000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"i386SX/33", CPU_386SX, 33333333, 1, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"i386SX/40", CPU_386SX, 40000000, 1, 0x2308, 0, 0, 0, 7,7,3,3, 5}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_i386DX[] = { - /*i386DX/RapidCAD*/ - {"i386DX/16", CPU_386DX, 16000000, 1, 0x0308, 0, 0, 0, 3,3,3,3, 2}, - {"i386DX/20", CPU_386DX, 20000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"i386DX/25", CPU_386DX, 25000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"i386DX/33", CPU_386DX, 33333333, 1, 0x0308, 0, 0, 0, 6,6,3,3, 4}, - {"i386DX/40", CPU_386DX, 40000000, 1, 0x0308, 0, 0, 0, 7,7,3,3, 5}, - {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0x0340, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_Am386SX[] = { - /*Am386SX*/ - {"Am386SX/16", CPU_386SX, 16000000, 1, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"Am386SX/20", CPU_386SX, 20000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386SX/25", CPU_386SX, 25000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386SX/33", CPU_386SX, 33333333, 1, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"Am386SX/40", CPU_386SX, 40000000, 1, 0x2308, 0, 0, 0, 7,7,3,3, 5}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_Am386DX[] = { - /*Am386DX*/ - {"Am386DX/25", CPU_386DX, 25000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386DX/33", CPU_386DX, 33333333, 1, 0x0308, 0, 0, 0, 6,6,3,3, 4}, - {"Am386DX/40", CPU_386DX, 40000000, 1, 0x0308, 0, 0, 0, 7,7,3,3, 5}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_486SLC[] = { - /*Cx486SLC*/ - {"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, - {"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0x406, 0, 0x0006, 0, 6,6,6,6, 4}, - {"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, - {"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_IBM386SLC[] = { - /*IBM 386SLC*/ - {"386SLC/16", CPU_IBM386SLC, 16000000, 1, 0xA301, 0, 0, 0, 3,3,3,3, 2}, - {"386SLC/20", CPU_IBM386SLC, 20000000, 1, 0xA301, 0, 0, 0, 4,4,3,3, 3}, - {"386SLC/25", CPU_IBM386SLC, 25000000, 1, 0xA301, 0, 0, 0, 4,4,3,3, 3}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_IBM486SLC[] = { - /*IBM 486SLC*/ - {"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0xA401, 0, 0, 0, 6,6,3,3, 4}, - {"486SLC2/40", CPU_IBM486SLC, 40000000, 2, 0xA421, 0, 0, 0, 7,7,6,6, 5}, - {"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0xA421, 0, 0, 0, 8,8,6,6, 6}, - {"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0xA421, 0, 0, 0, 12,12,6,6, 8}, - {"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0xA439, 0, 0, 0, 12,12,9,9, 7}, - {"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0xA439, 0, 0, 0, 12,12,9,9, 9}, - {"486SLC3/100", CPU_IBM486SLC, 100000000, 3, 0xA439, 0, 0, 0, 18,18,9,9, 12}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_IBM486BL[] = { - /*IBM Blue Lightning*/ - {"486BL2/50", CPU_IBM486BL, 50000000, 2, 0xA439, 0, 0, 0, 8,8,6,6, 6}, - {"486BL2/66", CPU_IBM486BL, 66666666, 2, 0xA439, 0, 0, 0, 12,12,6,6, 8}, - {"486BL3/75", CPU_IBM486BL, 75000000, 3, 0xA439, 0, 0, 0, 12,12,9,9, 9}, - {"486BL3/100", CPU_IBM486BL, 100000000, 3, 0xA439, 0, 0, 0, 18,18,9,9, 12}, - {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; - -CPU cpus_486DLC[] = { - /*Cx486DLC*/ - {"Cx486DLC/25", CPU_486DLC, 25000000, 1, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3}, - {"Cx486DLC/33", CPU_486DLC, 33333333, 1, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4}, - {"Cx486DLC/40", CPU_486DLC, 40000000, 1, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5}, - {"Cx486DRx2/32", CPU_486DLC, 32000000, 2, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4}, - {"Cx486DRx2/40", CPU_486DLC, 40000000, 2, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, - {"Cx486DRx2/50", CPU_486DLC, 50000000, 2, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, - {"Cx486DRx2/66", CPU_486DLC, 66666666, 2, 0x407, 0, 0x0007, 0, 12,12,6,6, 8}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} -}; - -CPU cpus_i486S1[] = { - /*i486*/ - {"i486SX/16", CPU_i486SX, 16000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, - {"i486SX/20", CPU_i486SX, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, - {"i486SX/25", CPU_i486SX, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, - {"i486SX/33", CPU_i486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, - {"i486SX2/50", CPU_i486SX2, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, - {"i486SX2/66 (Q0569)", CPU_i486SX2, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, - {"i486DX/25", CPU_i486DX, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, - {"i486DX/33", CPU_i486DX, 33333333, 1, 0x414, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, - {"i486DX/50", CPU_i486DX, 50000000, 1, 0x411, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, - {"i486DX2/40", CPU_i486DX2, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, - {"i486DX2/50", CPU_i486DX2, 50000000, 2, 0x433, 0x433, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, - {"i486DX2/66", CPU_i486DX2, 66666666, 2, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, - {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*Only added the DX4 OverDrive as the others would be redundant*/ - {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} -}; -CPU cpus_Am486S1[] = { - /*Am486*/ - {"Am486SX/33", CPU_Am486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Am486SX/40", CPU_Am486SX, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Am486SX2/50", CPU_Am486SX2, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX2, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ - {"Am486DX/33", CPU_Am486DX, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Am486DX/40", CPU_Am486DX, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Am486DX2/50", CPU_Am486DX2, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, - {"Am486DX2/66", CPU_Am486DX2, 66666666, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, - {"Am486DX2/80", CPU_Am486DX2, 80000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; -CPU cpus_Cx486S1[] = { - /*Cyrix 486*/ - {"Cx486S/25", CPU_Cx486S, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"Cx486S/33", CPU_Cx486S, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Cx486S/40", CPU_Cx486S, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Cx486DX/33", CPU_Cx486DX, 33333333, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Cx486DX/40", CPU_Cx486DX, 40000000, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Cx486DX2/50", CPU_Cx486DX2, 50000000, 2.0, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, - {"Cx486DX2/66", CPU_Cx486DX2, 66666666, 2.0, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, - {"Cx486DX2/80", CPU_Cx486DX2, 80000000, 2.0, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, - {"", -1, 0, 0.0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_i486[] = { - /*i486/P24T*/ - {"i486SX/16", CPU_i486SX, 16000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 3, 3, 3, 3, 2}, - {"i486SX/20", CPU_i486SX, 20000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"i486SX/25", CPU_i486SX, 25000000, 1.0, 0x422, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"i486SX/33", CPU_i486SX, 33333333, 1.0, 0x42a, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"i486SX2/50", CPU_i486SX2, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, - {"i486SX2/66 (Q0569)", CPU_i486SX2, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8}, - {"i486DX/25", CPU_i486DX, 25000000, 1.0, 0x404, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"i486DX/33", CPU_i486DX, 33333333, 1.0, 0x414, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"i486DX/50", CPU_i486DX, 50000000, 1.0, 0x411, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 6}, - {"i486DX2/40", CPU_i486DX2, 40000000, 2.0, 0x430, 0x430, 0x0000, CPU_SUPPORTS_DYNAREC, 7, 7, 6, 6, 5}, - {"i486DX2/50", CPU_i486DX2, 50000000, 2.0, 0x433, 0x433, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, - {"i486DX2/66", CPU_i486DX2, 66666666, 2.0, 0x435, 0x435, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, - {"iDX4/75", CPU_iDX4, 75000000, 3.0, 0x480, 0x480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, /*CPUID available on DX4, >= 75 MHz*/ - {"iDX4/100", CPU_iDX4, 100000000, 3.0, 0x483, 0x483, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ - {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, - {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, - {"Pentium OverDrive 63", CPU_P24T, 62500000, 2.5, 0x1531, 0x1531, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, - {"Pentium OverDrive 83", CPU_P24T, 83333333, 2.5, 0x1532, 0x1532, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10}, - {"", -1, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_Am486[] = { - /*Am486/5x86*/ - {"Am486SX/33", CPU_Am486SX, 33333333, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Am486SX/40", CPU_Am486SX, 40000000, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Am486SX2/50", CPU_Am486SX2, 50000000, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX2, 66666666, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, - {"Am486DX/33", CPU_Am486DX, 33333333, 1.0, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Am486DX/40", CPU_Am486DX, 40000000, 1.0, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Am486DX2/50", CPU_Am486DX2, 50000000, 2.0, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, - {"Am486DX2/66", CPU_Am486DX2, 66666666, 2.0, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, - {"Am486DX2/80", CPU_Am486DX2, 80000000, 2.0, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, - {"Am486DX4/75", CPU_Am486DX4, 75000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, - {"Am486DX4/90", CPU_Am486DX4, 90000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, - {"Am486DX4/100", CPU_Am486DX4, 100000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, - {"Am486DX4/120", CPU_Am486DX4, 120000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, - {"Am5x86/P75", CPU_Am5x86, 133333333, 4.0, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, - {"Am5x86/P75+", CPU_Am5x86, 150000000, 3.0, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ - {"Am5x86/P90", CPU_Am5x86, 160000000, 4.0, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_Cx486[] = { - /*Cyrix 486*/ - {"Cx486S/25", CPU_Cx486S, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"Cx486S/33", CPU_Cx486S, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Cx486S/40", CPU_Cx486S, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Cx486DX/33", CPU_Cx486DX, 33333333, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Cx486DX/40", CPU_Cx486DX, 40000000, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Cx486DX2/50", CPU_Cx486DX2, 50000000, 2.0, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, - {"Cx486DX2/66", CPU_Cx486DX2, 66666666, 2.0, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, - {"Cx486DX2/80", CPU_Cx486DX2, 80000000, 2.0, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, - {"Cx486DX4/75", CPU_Cx486DX4, 75000000, 3.0, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, - {"Cx486DX4/100", CPU_Cx486DX4, 100000000, 3.0, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, - - /*Cyrix 5x86*/ - {"Cx5x86/80", CPU_Cx5x86, 80000000, 2.0, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, /*If we're including the Pentium 50, might as well include this*/ - {"Cx5x86/100", CPU_Cx5x86, 100000000, 3.0, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, - {"Cx5x86/120", CPU_Cx5x86, 120000000, 3.0, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, - {"Cx5x86/133", CPU_Cx5x86, 133333333, 4.0, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) -CPU cpus_6x863V[] = { - /*Cyrix 6x86*/ - {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, - {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_6x86[] = { - /*Cyrix 6x86*/ - {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, - {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, - - /*Cyrix 6x86L*/ - {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, - - /*Cyrix 6x86MX/MII*/ - {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2.0, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, - {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, - {"MII/PR300", CPU_Cx6x86MX, 233333333, 3.5, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, - {"MII/PR333", CPU_Cx6x86MX, 250000000, 3.0, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - }; - - CPU cpus_6x86SS7[] = { - /*Cyrix 6x86*/ - {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, - {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2.0, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, - - /*Cyrix 6x86L*/ - {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, - {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2.0, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, - - /*Cyrix 6x86MX/MII*/ - {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2.0, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, - {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 2.5, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, - {"MII/PR300", CPU_Cx6x86MX, 233333333, 3.5, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, - {"MII/PR333", CPU_Cx6x86MX, 250000000, 3.0, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, - {"MII/PR366", CPU_Cx6x86MX, 250000000, 2.5, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, - {"MII/PR400", CPU_Cx6x86MX, 285000000, 3.0, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, - {"MII/PR433", CPU_Cx6x86MX, 300000000, 3.0, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - }; -#endif - -CPU cpus_WinChip[] = { - /*IDT WinChip*/ - {"WinChip 75", CPU_WINCHIP, 75000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, - {"WinChip 90", CPU_WINCHIP, 90000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, - {"WinChip 100", CPU_WINCHIP, 100000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, - {"WinChip 120", CPU_WINCHIP, 120000000, 2.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, - {"WinChip 133", CPU_WINCHIP, 133333333, 2.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, - {"WinChip 150", CPU_WINCHIP, 150000000, 2.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, - {"WinChip 166", CPU_WINCHIP, 166666666, 2.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, - {"WinChip 180", CPU_WINCHIP, 180000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, - {"WinChip 200", CPU_WINCHIP, 200000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, - {"WinChip 225", CPU_WINCHIP, 225000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, - {"WinChip 240", CPU_WINCHIP, 240000000, 4.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, - {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, - {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, - {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, - {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, - {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3.0, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, - {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 3.5, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_WinChip_SS7[] = { - /*IDT WinChip*/ - {"WinChip 75", CPU_WINCHIP, 75000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, - {"WinChip 90", CPU_WINCHIP, 90000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, - {"WinChip 100", CPU_WINCHIP, 100000000, 1.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, - {"WinChip 120", CPU_WINCHIP, 120000000, 2.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, - {"WinChip 133", CPU_WINCHIP, 133333333, 2.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, - {"WinChip 150", CPU_WINCHIP, 150000000, 2.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, - {"WinChip 166", CPU_WINCHIP, 166666666, 2.5, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, - {"WinChip 180", CPU_WINCHIP, 180000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, - {"WinChip 200", CPU_WINCHIP, 200000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, - {"WinChip 225", CPU_WINCHIP, 225000000, 3.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, - {"WinChip 240", CPU_WINCHIP, 240000000, 4.0, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, - {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, - {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*9}, - {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, - {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, - {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3.0, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, - {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 3.5, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, (7*8)/2}, - {"WinChip 2A/266", CPU_WINCHIP2, 233333333, 7.0/3.0, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 7, 7, 28}, - {"WinChip 2A/300", CPU_WINCHIP2, 250000000, 2.5, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_Pentium5V[] = { - /*Intel Pentium (5V, socket 4)*/ - {"Pentium 60", CPU_PENTIUM, 60000000, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, - {"Pentium 66", CPU_PENTIUM, 66666666, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8}, - {"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_Pentium5V50[] = { - /*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/ - {"Pentium 50 (Q0399)", CPU_PENTIUM, 50000000, 1, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4,3,3, 6}, - {"Pentium 60", CPU_PENTIUM, 60000000, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, - {"Pentium 66", CPU_PENTIUM, 66666666, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8}, - {"Pentium OverDrive 100", CPU_PENTIUM, 100000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8,6,6, 12}, - {"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_PentiumS5[] = { - /*Intel Pentium (Socket 5)*/ - {"Pentium 75", CPU_PENTIUM, 75000000, 1.5, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, - {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 1.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, - {"Pentium 90", CPU_PENTIUM, 90000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, - {"Pentium 100/50", CPU_PENTIUM, 100000000, 2.0, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12}, - {"Pentium 100/66", CPU_PENTIUM, 100000000, 1.5, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, - {"Pentium 120", CPU_PENTIUM, 120000000, 2.0, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - - /*Intel Pentium OverDrive*/ - {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 3.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16}, - {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"", -1, 0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_Pentium3V[] = { - /*Intel Pentium*/ - {"Pentium 75", CPU_PENTIUM, 75000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 1.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium 90", CPU_PENTIUM, 90000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, - {"Pentium 100/50", CPU_PENTIUM, 100000000, 2.0, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"Pentium 100/66", CPU_PENTIUM, 100000000, 1.5, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, - {"Pentium 120", CPU_PENTIUM, 120000000, 2.0, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"Pentium 133", CPU_PENTIUM, 133333333, 2.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Pentium 150", CPU_PENTIUM, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"Pentium 166", CPU_PENTIUM, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Pentium 200", CPU_PENTIUM, 200000000, 3.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - - /*Intel Pentium OverDrive*/ - {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, - {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_Pentium[] = { - /*Intel Pentium*/ - {"Pentium 75", CPU_PENTIUM, 75000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 1.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium 90", CPU_PENTIUM, 90000000, 1.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, - {"Pentium 100/50", CPU_PENTIUM, 100000000, 2.0, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"Pentium 100/66", CPU_PENTIUM, 100000000, 1.5, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, - {"Pentium 120", CPU_PENTIUM, 120000000, 2.0, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"Pentium 133", CPU_PENTIUM, 133333333, 2.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Pentium 150", CPU_PENTIUM, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"Pentium 166", CPU_PENTIUM, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Pentium 200", CPU_PENTIUM, 200000000, 3.0, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - - /*Intel Pentium MMX*/ - {"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 2.5, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3.0, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - {"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 3.5, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - - /*Mobile Pentium*/ - {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 120000000, 2.0, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 133333333, 2.0, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 150000000, 2.5, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 2.5, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3.0, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 3.5, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 266666666, 4.0, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 300000000, 4.5, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - - /*Intel Pentium OverDrive*/ - {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, - {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 2.5, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 2.5, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3.0, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - {"", -1, 0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) -CPU cpus_K5[] = { - /*AMD K5 (Socket 5)*/ - {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, - {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, - {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, - {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, - {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, - {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, - {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2.0, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, - {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2.0, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, - {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, - {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3.0, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"", -1, 0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; -#endif - -CPU cpus_K56[] = { -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - /*AMD K5 (Socket 7)*/ - {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, - {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, - {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, - {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, - {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2.0, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2.0, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3.0, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, -#endif - - /*AMD K6 (Socket 7*/ - {"K6 (Model 6) 166", CPU_K6, 166666666, 2.5, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"K6 (Model 6) 200", CPU_K6, 200000000, 3.0, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - {"K6 (Model 6) 233", CPU_K6, 233333333, 3.5, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, - {"K6 (Model 7) 200", CPU_K6, 200000000, 3.0, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - {"K6 (Model 7) 233", CPU_K6, 233333333, 3.5, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, - {"K6 (Model 7) 266", CPU_K6, 266666666, 4.0, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, - {"K6 (Model 7) 300", CPU_K6, 300000000, 4.5, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, - - /*AMD K6-2 (Socket 7)*/ - {"K6-2/233", CPU_K6_2, 233333333, 3.5, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, - {"K6-2/266", CPU_K6_2, 266666666, 4.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, - {"K6-2/300 AFR-66", CPU_K6_2, 300000000, 4.5, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, - {"K6-2/366", CPU_K6_2, 366666666, 5.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_K56_SS7[] = { -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - /*AMD K5 (Socket 7)*/ - {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, - {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, - {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 1.5, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, - {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 1.5, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, - {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2.0, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, - {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2.0, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 2.5, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3.0, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, -#endif - - /*AMD K6 (Socket 7)*/ - {"K6 (Model 6) 166", CPU_K6, 166666666, 2.5, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"K6 (Model 6) 200", CPU_K6, 200000000, 3.0, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - {"K6 (Model 6) 233", CPU_K6, 233333333, 3.5, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6 (Model 7) 200", CPU_K6, 200000000, 3.0, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - {"K6 (Model 7) 233", CPU_K6, 233333333, 3.5, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6 (Model 7) 266", CPU_K6, 266666666, 4.0, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6 (Model 7) 300", CPU_K6, 300000000, 4.5, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - - /*AMD K6-2 (Socket 7/Super Socket 7)*/ - {"K6-2/233", CPU_K6_2, 233333333, 3.5, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, - {"K6-2/266", CPU_K6_2, 266666666, 4.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, - {"K6-2/300", CPU_K6_2, 300000000, 3.0, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36}, - {"K6-2/333", CPU_K6_2, 332500000, 3.5, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40}, - {"K6-2/350", CPU_K6_2C, 350000000, 3.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42}, - {"K6-2/366", CPU_K6_2C, 366666666, 5.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44}, - {"K6-2/380", CPU_K6_2C, 380000000, 4.0, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46}, - {"K6-2/400", CPU_K6_2C, 400000000, 4.0, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, - {"K6-2/450", CPU_K6_2C, 450000000, 4.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, - {"K6-2/475", CPU_K6_2C, 475000000, 5.0, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, - {"K6-2/500", CPU_K6_2C, 500000000, 5.0, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, - {"K6-2/533", CPU_K6_2C, 533333333, 5.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, - {"K6-2/550", CPU_K6_2C, 550000000, 5.5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, - - /*AMD K6-2+/K6-3/K6-3+ (Super Socket 7)*/ - {"K6-2+/450", CPU_K6_2P, 450000000, 4.5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, - {"K6-2+/475", CPU_K6_2P, 475000000, 5.0, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, - {"K6-2+/500", CPU_K6_2P, 500000000, 5.0, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, - {"K6-2+/533", CPU_K6_2P, 533333333, 5.5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, - {"K6-2+/550", CPU_K6_2P, 550000000, 5.5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, - {"K6-III/400", CPU_K6_3, 400000000, 4.0, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, - {"K6-III/450", CPU_K6_3, 450000000, 4.5, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, - {"K6-III+/75", CPU_K6_3P, 75000000, 1.5, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"K6-III+/400", CPU_K6_3P, 400000000, 4.0, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, - {"K6-III+/450", CPU_K6_3P, 450000000, 4.5, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, - {"K6-III+/475", CPU_K6_3P, 475000000, 5.0, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, - {"K6-III+/500", CPU_K6_3P, 500000000, 5.0, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_PentiumPro[] = { - /*Intel Pentium Pro*/ - {"Pentium Pro 50", CPU_PENTIUMPRO, 50000000, 1.0, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"Pentium Pro 60" , CPU_PENTIUMPRO, 60000000, 1.0, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"Pentium Pro 66" , CPU_PENTIUMPRO, 66666666, 1.0, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"Pentium Pro 75", CPU_PENTIUMPRO, 75000000, 1.5, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium Pro 150", CPU_PENTIUMPRO, 150000000, 2.5, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, - {"Pentium Pro 166", CPU_PENTIUMPRO, 166666666, 2.5, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Pentium Pro 180", CPU_PENTIUMPRO, 180000000, 3.0, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, - {"Pentium Pro 200", CPU_PENTIUMPRO, 200000000, 3.0, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, - - /*Intel Pentium II OverDrive*/ - {"Pentium II Overdrive 50", CPU_PENTIUM2D, 50000000, 1.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"Pentium II Overdrive 60", CPU_PENTIUM2D, 60000000, 1.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"Pentium II Overdrive 66", CPU_PENTIUM2D, 66666666, 1.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"Pentium II Overdrive 75", CPU_PENTIUM2D, 75000000, 1.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium II Overdrive 210", CPU_PENTIUM2D, 210000000, 3.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, - {"Pentium II Overdrive 233", CPU_PENTIUM2D, 233333333, 3.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"Pentium II Overdrive 240", CPU_PENTIUM2D, 240000000, 4.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29}, - {"Pentium II Overdrive 266", CPU_PENTIUM2D, 266666666, 4.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"Pentium II Overdrive 270", CPU_PENTIUM2D, 270000000, 4.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33}, - {"Pentium II Overdrive 300/66", CPU_PENTIUM2D, 300000000, 4.5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, - {"Pentium II Overdrive 300/60", CPU_PENTIUM2D, 300000000, 5.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"Pentium II Overdrive 333", CPU_PENTIUM2D, 333333333, 5.0, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_PentiumII66[] = { - /*Intel Pentium II Klamath*/ - {"Pentium II Klamath 50", CPU_PENTIUM2, 50000000, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"Pentium II Klamath 60", CPU_PENTIUM2, 60000000, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"Pentium II Klamath 66", CPU_PENTIUM2, 66666666, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"Pentium II Klamath 75", CPU_PENTIUM2, 75000000, 1.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium II Klamath 233", CPU_PENTIUM2, 233333333, 3.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"Pentium II Klamath 266", CPU_PENTIUM2, 266666666, 4.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"Pentium II Klamath 300/66", CPU_PENTIUM2, 300000000, 4.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, - - /*Intel Pentium II Deschutes*/ - {"Pentium II Deschutes 50", CPU_PENTIUM2D, 50000000, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"Pentium II Deschutes 60", CPU_PENTIUM2D, 60000000, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"Pentium II Deschutes 66", CPU_PENTIUM2D, 66666666, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"Pentium II Deschutes 75", CPU_PENTIUM2D, 75000000, 1.5, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium II Deschutes 266", CPU_PENTIUM2D, 266666666, 4.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"Pentium II Deschutes 300/66", CPU_PENTIUM2D, 300000000, 4.5, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, - {"Pentium II Deschutes 333", CPU_PENTIUM2D, 333333333, 5.0, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - -}; - -CPU cpus_PentiumII[] = { - /*Intel Pentium II Klamath*/ - {"Pentium II Klamath 50", CPU_PENTIUM2, 50000000, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"Pentium II Klamath 60", CPU_PENTIUM2, 60000000, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"Pentium II Klamath 66", CPU_PENTIUM2, 66666666, 1.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"Pentium II Klamath 75", CPU_PENTIUM2, 75000000, 1.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium II Klamath 233", CPU_PENTIUM2, 233333333, 3.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"Pentium II Klamath 266", CPU_PENTIUM2, 266666666, 4.0, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"Pentium II Klamath 300/66", CPU_PENTIUM2, 300000000, 4.5, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, - - /*Intel Pentium II Deschutes*/ - {"Pentium II Deschutes 50", CPU_PENTIUM2D, 50000000, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"Pentium II Deschutes 60", CPU_PENTIUM2D, 60000000, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"Pentium II Deschutes 66", CPU_PENTIUM2D, 66666666, 1.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"Pentium II Deschutes 75", CPU_PENTIUM2D, 75000000, 1.5, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"Pentium II Deschutes 266", CPU_PENTIUM2D, 266666666, 4.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"Pentium II Deschutes 300/66", CPU_PENTIUM2D, 300000000, 4.5, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, - {"Pentium II Deschutes 333", CPU_PENTIUM2D, 333333333, 5.0, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, - {"Pentium II Deschutes 350", CPU_PENTIUM2D, 350000000, 3.5, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32,32,11,11, 42}, - {"Pentium II Deschutes 400", CPU_PENTIUM2D, 400000000, 4.0, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, - {"Pentium II Deschutes 450", CPU_PENTIUM2D, 450000000, 4.5, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41,41,14,14, 54}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - -}; - -CPU cpus_Xeon[] = { - /* Slot 2 Xeons. Literal P2D's with more cache */ - {"Pentium II Xeon 166", CPU_PENTIUM2D, 166666666, 2.5, 0x653, 0x653, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Pentium II Xeon 400", CPU_PENTIUM2D, 400000000, 4.0, 0x653, 0x653, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_Celeron[] = { - /* Mendocino Celerons. Exact architecture as the P2D series with their L2 cache on-dye. - Intended for the PGA370 boards but they were capable to fit on a PGA 370 to Slot 1 - adaptor card so they work on Slot 1 motherboards too!. - - The 100Mhz & 166Mhz Mendocino is only meant to not cause any struggle - to the recompiler. */ - {"Celeron Mendocino 100", CPU_PENTIUM2D, 100000000, 1.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"Celeron Mendocino 166", CPU_PENTIUM2D, 166666666, 2.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, - {"Celeron Mendocino 300/66", CPU_PENTIUM2D, 300000000, 4.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, - {"Celeron Mendocino 333", CPU_PENTIUM2D, 333333333, 5.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, - {"Celeron Mendocino 366", CPU_PENTIUM2D, 366666666, 5.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33,17,17, 44}, - {"Celeron Mendocino 400", CPU_PENTIUM2D, 400000000, 6.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, - {"Celeron Mendocino 433", CPU_PENTIUM2D, 433333333, 6.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 39,39,13,13, 51}, - {"Celeron Mendocino 500", CPU_PENTIUM2D, 500000000, 7.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45,45,15,15, 60}, - {"Celeron Mendocino 533", CPU_PENTIUM2D, 533333333, 8.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48,48,17,17, 64}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; - -CPU cpus_Cyrix3[] = { - /*VIA Cyrix III (Samuel)*/ - {"Cyrix III 66", CPU_CYRIX3S, 66666666, 1.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 8}, /*66 MHz version*/ - {"Cyrix III 233", CPU_CYRIX3S, 233333333, 3.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, 28}, - {"Cyrix III 266", CPU_CYRIX3S, 266666666, 4.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 32}, - {"Cyrix III 300", CPU_CYRIX3S, 300000000, 4.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 27, 27, 13, 13, 36}, - {"Cyrix III 333", CPU_CYRIX3S, 333333333, 5.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 30, 30, 15, 15, 40}, - {"Cyrix III 350", CPU_CYRIX3S, 350000000, 3.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 32, 32, 11, 11, 42}, - {"Cyrix III 400", CPU_CYRIX3S, 400000000, 4.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 36, 36, 12, 12, 48}, - {"Cyrix III 450", CPU_CYRIX3S, 450000000, 4.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 41, 41, 14, 14, 54}, /*^ is lower P2 speeds to allow emulation below 466 mhz*/ - {"Cyrix III 500", CPU_CYRIX3S, 500000000, 5.0, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 45, 45, 15, 15, 60}, - {"Cyrix III 550", CPU_CYRIX3S, 550000000, 5.5, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 50, 50, 17, 17, 66}, - {"Cyrix III 600", CPU_CYRIX3S, 600000000, 6.0, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 54, 54, 18, 18, 72}, - {"Cyrix III 650", CPU_CYRIX3S, 650000000, 6.5, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 58, 58, 20, 20, 78}, - {"Cyrix III 700", CPU_CYRIX3S, 700000000, 7.0, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 62, 62, 21, 21, 84}, - {"", -1, 0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -}; diff --git a/src/cpu_new/codegen_timing_486.c b/src/cpu_new/codegen_timing_486.c deleted file mode 100644 index 14bbf34c6..000000000 --- a/src/cpu_new/codegen_timing_486.c +++ /dev/null @@ -1,424 +0,0 @@ -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> - -#include "x86.h" -#include "x86_ops.h" -#include "x87.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)) - -static int *opcode_timings[256] = -{ -/*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), -/*30*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), - -/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, - -/*80*/ &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm, &timing_rm, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0), -/*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 -}; - -static int *opcode_timings_mod3[256] = -{ -/*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), -/*30*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), - -/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, - -/*80*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0), -/*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 -}; - -static int *opcode_timings_0f[256] = -{ -/*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, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, -/*70*/ NULL, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rm, &timing_rm, - -/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*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, -}; -static int *opcode_timings_0f_mod3[256] = -{ -/*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, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, -/*70*/ NULL, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rr, &timing_rr, - -/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*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, -}; - -static int *opcode_timings_shift[8] = -{ - CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) -}; -static int *opcode_timings_shift_mod3[8] = -{ - CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) -}; - -static int *opcode_timings_f6[8] = -{ - &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static int *opcode_timings_f6_mod3[8] = -{ - &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static int *opcode_timings_f7[8] = -{ - &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static int *opcode_timings_f7_mod3[8] = -{ - &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static int *opcode_timings_ff[8] = -{ - &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL -}; -static int *opcode_timings_ff_mod3[8] = -{ - &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL -}; - -static int *opcode_timings_d8[8] = -{ -/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; -static int *opcode_timings_d8_mod3[8] = -{ -/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ - CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; - -static int *opcode_timings_d9[8] = -{ -/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ - CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) -}; -static int *opcode_timings_d9_mod3[64] = -{ - /*FLD*/ - CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), - /*FXCH*/ - CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), - /*FNOP*/ - CYCLES(3), NULL, NULL, NULL, NULL, NULL, NULL, NULL, - /*FSTP*/ - CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/* opFCHS opFABS opFTST opFXAM*/ - CYCLES(6), CYCLES(3), NULL, NULL, CYCLES(4), CYCLES(8), NULL, NULL, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI opFLDEG2 opFLDLN2 opFLDZ*/ - CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(8), CYCLES(8), CYCLES(8), CYCLES(4), NULL, -/* opF2XM1 opFYL2X opFPTAN opFPATAN opFDECSTP opFINCSTP,*/ - 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) -}; - -static int *opcode_timings_da[8] = -{ -/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; -static int *opcode_timings_da_mod3[8] = -{ - NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL -}; - - -static int *opcode_timings_db[8] = -{ -/* FLDil FSTil FSTPil FLDe FSTPe*/ - CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6) -}; -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, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/* opFNOP opFCLEX opFINIT opFNOP opFNOP*/ - NULL, CYCLES(3), CYCLES(7), CYCLES(17), CYCLES(3), CYCLES(3), NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -static int *opcode_timings_dc[8] = -{ -/* 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) -}; -static int *opcode_timings_dc_mod3[8] = -{ -/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; - -static int *opcode_timings_dd[8] = -{ -/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ - CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3) -}; -static int *opcode_timings_dd_mod3[8] = -{ -/* FFFREE FST FSTP FUCOM FUCOMP*/ - CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL -}; - -static int *opcode_timings_de[8] = -{ -/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; -static int *opcode_timings_de_mod3[8] = -{ -/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ - CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) -}; - -static int *opcode_timings_df[8] = -{ -/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ - CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28) -}; -static int *opcode_timings_df_mod3[8] = -{ -/* FFREE FST FSTP FUCOM FUCOMP*/ - CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL -}; - -static int *opcode_timings_8x[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_8x_mod3[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_81[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_81_mod3[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; - -static int timing_count; -static uint8_t last_prefix; -static uint32_t regmask_modified; - -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; -} - -void codegen_timing_486_block_start() -{ - regmask_modified = 0; -} - -void codegen_timing_486_start() -{ - timing_count = 0; - last_prefix = 0; -} - -void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) -{ - 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) -{ - int **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; - - 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: - 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); -} - -void codegen_timing_486_block_end() -{ -} - -int codegen_timing_486_jump_cycles() -{ - return 0; -} - -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, - codegen_timing_486_jump_cycles -}; diff --git a/src/cpu_new/codegen_timing_686.c b/src/cpu_new/codegen_timing_686.c deleted file mode 100644 index 6e221de27..000000000 --- a/src/cpu_new/codegen_timing_686.c +++ /dev/null @@ -1,1061 +0,0 @@ -/*Elements taken into account : - - X/Y pairing - - FPU/FXCH pairing - - Prefix decode delay - - AGI stalls - Elements not taken into account : - - Branch prediction (beyond most simplistic approximation) - - FPU queue - - Out of order execution (beyond most simplistic approximation) -*/ - -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> - -#include "x86.h" -#include "x86_ops.h" -#include "x87.h" -#include "codegen.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 << 31) - -#define CYCLES_MULTI(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) - -/*Instruction lasts given number of cycles. Does not pair*/ -#define CYCLES(c) (c) - -/*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_BRANCH (1 << 0) - -#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) -/*Instruction pairs in X pipe only, and can not pair with a following instruction*/ -#define PAIR_X_BRANCH (2 << 29) -/*Instruction pairs in both X and Y pipes*/ -#define PAIR_XY (3 << 29) - -#define PAIR_MASK (3 << 29) - -#define INVALID 0 - -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 uint64_t *prev_deps; -static uint32_t prev_fetchdat; - -static uint32_t last_regmask_modified; -static uint32_t regmask_modified; - -static uint32_t opcode_timings[256] = -{ -/* 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*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* OR OR PUSH CS */ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* ADC ADC PUSH SS POP SS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* SBB SBB PUSH DS POP DS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), - -/* AND AND AND AND*/ -/*20*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* AND AND DAA*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* SUB SUB SUB SUB*/ - PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* SUB SUB DAS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), - -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* XOR XOR AAA*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* CMP CMP CMP CMP*/ - PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, -/* CMP CMP AAS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(10), PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), - -/* Jxx*/ -/*70*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* MOV MOV MOV MOV*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG, CYCLES(3), PAIR_XY | CYCLES(1), - -/* NOP XCHG XCHG XCHG*/ -/*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* XCHG XCHG XCHG XCHG*/ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* CBW CWD CALL far WAIT*/ - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), -/* PUSHF POPF SAHF LAHF*/ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2), - -/* MOV MOV MOV MOV*/ -/*a0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* MOVSB MOVSW CMPSB CMPSW*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* TEST TEST STOSB STOSW*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* LODSB LODSW SCASB SCASW*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/* MOV*/ -/*b0*/ 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, - 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, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, PAIR_X_BRANCH | CYCLES(3), PAIR_X_BRANCH | CYCLES(2), -/* LES LDS MOV MOV*/ - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* ENTER LEAVE RETF RETF*/ - PAIR_XY | CYCLES(10), PAIR_XY | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), -/* INT3 INT INTO IRET*/ - PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(16), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(10), - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - PAIR_XY | CYCLES(18), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(4), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), -/* CALL JMP JMP JMP*/ - PAIR_X_BRANCH | CYCLES_REG, PAIR_X_BRANCH | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_X_BRANCH | CYCLES_REG, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* HLT CMC*/ - PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(2), INVALID, INVALID, -/* CLC STC CLI STI*/ - 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 -}; - -static uint32_t opcode_timings_mod3[256] = -{ -/* 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*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* OR OR PUSH CS */ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* ADC ADC PUSH SS POP SS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* SBB SBB PUSH DS POP DS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), - -/* AND AND AND AND*/ -/*20*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* AND AND DAA*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* SUB SUB SUB SUB*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* SUB SUB DAS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), - -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* XOR XOR AAA*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* CMP CMP CMP CMP*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* CMP CMP AAS*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(10), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), - -/* Jxx*/ -/*70*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - -/*80*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* TEST TEST XCHG XCHG*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* MOV MOV MOV MOV*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_XY | CYCLES(1), - -/* NOP XCHG XCHG XCHG*/ -/*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* XCHG XCHG XCHG XCHG*/ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* CBW CWD CALL far WAIT*/ - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), -/* PUSHF POPF SAHF LAHF*/ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2), - -/* MOV MOV MOV MOV*/ -/*a0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* MOVSB MOVSW CMPSB CMPSW*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* TEST TEST STOSB STOSW*/ - PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* LODSB LODSW SCASB SCASW*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/* MOV*/ -/*b0*/ 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, - 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, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, PAIR_X_BRANCH | CYCLES(3), PAIR_X_BRANCH | CYCLES(2), -/* LES LDS MOV MOV*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* ENTER LEAVE RETF RETF*/ - PAIR_XY | CYCLES(13), PAIR_XY | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), -/* INT3 INT INTO IRET*/ - PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(16), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(10), - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - PAIR_XY | CYCLES(18), PAIR_XY | CYCLES(7), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(4), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), -/* CALL JMP JMP JMP*/ - PAIR_X_BRANCH | CYCLES_REG, PAIR_X_BRANCH | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_X_BRANCH | CYCLES_REG, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* HLT CMC*/ - PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(2), INVALID, INVALID, -/* CLC STC CLI STI*/ - 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 -}; - -static uint32_t opcode_timings_0f[256] = -{ -/*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, - INVALID, INVALID, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ PAIR_NP | CYCLES(9), CYCLES(1), PAIR_NP | CYCLES(9), INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - -/*70*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES(1), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - -/*80*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - -/*90*/ PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - -/*a0*/ PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(12), PAIR_XY | CYCLES(5), - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(5), INVALID, INVALID, - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), INVALID, PAIR_XY | CYCLES(5), - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), INVALID, PAIR_NP | CYCLES(10), - -/*b0*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(5), - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - INVALID, INVALID, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(5), - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), INVALID, - -/*c0*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), - -/*d0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - -/*e0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, - INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - -/*f0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - 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, -}; -static uint32_t opcode_timings_0f_mod3[256] = -{ -/*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, - INVALID, INVALID, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ PAIR_NP | CYCLES(9), CYCLES(1), PAIR_NP | CYCLES(9), INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - -/*70*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES(1), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - -/*80*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, - -/*90*/ PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - -/*a0*/ PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(12), PAIR_XY | CYCLES(5), - PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(5), INVALID, INVALID, - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), INVALID, PAIR_XY | CYCLES(5), - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), INVALID, PAIR_NP | CYCLES(10), - -/*b0*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(5), - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), - INVALID, INVALID, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(5), - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(1), INVALID, -/*c0*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - -/*d0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - -/*e0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, - INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - -/*f0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - 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, -}; - -static uint32_t opcode_timings_shift[8] = -{ - 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, -}; -static uint32_t opcode_timings_shift_mod3[8] = -{ - 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, -}; -static uint32_t opcode_timings_shift_imm[8] = -{ - 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, -}; -static uint32_t opcode_timings_shift_imm_mod3[8] = -{ - 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, -}; -static uint32_t opcode_timings_shift_cl[8] = -{ - 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), -}; -static uint32_t opcode_timings_shift_cl_mod3[8] = -{ - 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), -}; - -static uint32_t opcode_timings_f6[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_f6_mod3[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_f7[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_f7_mod3[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_ff[8] = -{ -/* 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 -}; -static uint32_t opcode_timings_ff_mod3[8] = -{ -/* 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 -}; - -static uint32_t opcode_timings_d8[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_d8_mod3[8] = -{ -/* 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) -}; - -static uint32_t opcode_timings_d9[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_d9_mod3[64] = -{ - /*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), - /*FXCH*/ - PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), - PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), PAIR_X | CYCLES(3), - /*FNOP*/ - PAIR_X | CYCLES(2), INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - 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), -/* opFCHS opFABS*/ - PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), INVALID, INVALID, -/* opFTST opFXAM (oddly low) */ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), -/* opFLDEG2 opFLDLN2 opFLDZ*/ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - PAIR_X | CYCLES(92), PAIR_X | CYCLES(170), PAIR_X | CYCLES(129), PAIR_X | CYCLES(161), -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, PAIR_X | CYCLES(4), PAIR_X | CYCLES(2), -/* opFPREM opFSQRT opFSINCOS*/ - 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) -}; - -static uint32_t opcode_timings_da[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_da_mod3[8] = -{ - PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), - INVALID, PAIR_X | CYCLES(5), INVALID, INVALID -}; - - -static uint32_t opcode_timings_db[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_db_mod3[64] = -{ - 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), - - 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), - - 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), - - 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), - -/* opFNOP opFCLEX opFINIT*/ - INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(5), PAIR_X | CYCLES(8), -/* opFNOP opFNOP*/ - PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -}; - -static uint32_t opcode_timings_dc[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_dc_mod3[8] = -{ -/* 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) -}; - -static uint32_t opcode_timings_dd[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_dd_mod3[8] = -{ -/* 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 -}; - -static uint32_t opcode_timings_de[8] = -{ -/* 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] = -{ -/* 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) -}; - -static uint32_t opcode_timings_df[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_df_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - PAIR_X | CYCLES(6), INVALID, INVALID, INVALID -}; - -static uint32_t opcode_timings_8x[8] = -{ - 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 -}; -static uint32_t opcode_timings_8x_mod3[8] = -{ - 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 -}; -static uint32_t opcode_timings_81[8] = -{ - 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 -}; -static uint32_t opcode_timings_81_mod3[8] = -{ - 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 -}; - -static int decode_delay; -static uint8_t last_prefix; - -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; - - return c & CYCLES_MASK; -} - -void codegen_timing_686_block_start() -{ - prev_full = decode_delay = 0; - regmask_modified = last_regmask_modified = 0; -} - -void codegen_timing_686_start() -{ - decode_delay = 0; - last_prefix = 0; -} - -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++; - last_prefix = prefix; -} - -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); - - if (addr_regmask & IMPL_ESP) - addr_regmask |= (1 << REG_ESP); - - if (regmask_modified & addr_regmask) - { - regmask_modified = 0; - return 2; - } - - if (last_regmask_modified & addr_regmask) - return 1; - - return 0; -} - -void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) -{ - 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; - - 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: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } - - /*One prefix per instruction is free*/ - decode_delay--; - if (decode_delay < 0) - decode_delay = 0; - - if (prev_full) - { - uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32); - int agi_stall = 0; - - 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; - } - } -} - -void codegen_timing_686_block_end() -{ - if (prev_full) - { - /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; - prev_full = 0; - } -} - -int codegen_timing_686_jump_cycles() -{ - return 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, - codegen_timing_686_jump_cycles -}; diff --git a/src/cpu_new/codegen_timing_common.c b/src/cpu_new/codegen_timing_common.c deleted file mode 100644 index 926690814..000000000 --- a/src/cpu_new/codegen_timing_common.c +++ /dev/null @@ -1,847 +0,0 @@ -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> - -#include "codegen_timing_common.h" - -uint64_t opcode_deps[256] = -{ -/* 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*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* OR OR OR OR*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* OR OR PUSH CS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0, - -/* ADC ADC ADC ADC*/ -/*10*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* ADC ADC PUSH SS POP SS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* SBB SBB SBB SBB*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* SBB SBB PUSH DS POP DS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, - -/* AND AND AND AND*/ -/*20*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* AND AND DAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* SUB SUB SUB SUB*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* SUB SUB DAS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, - -/* XOR XOR XOR XOR*/ -/*30*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* XOR XOR AAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* CMP CMP CMP CMP*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, -/* CMP CMP AAS*/ - SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, -/* INC ESP INC EBP INC ESI INC EDI*/ - SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP, -/* POP EAX POP ECX POP EDX POP EBX*/ - DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP, -/* POP ESP POP EBP POP ESI POP EDI*/ - DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ IMPL_ESP, IMPL_ESP, 0, 0, - 0, 0, 0, 0, -/* PUSH imm IMUL PUSH imm IMUL*/ - IMPL_ESP, DSTDEP_REG | MODRM, IMPL_ESP, DSTDEP_REG | MODRM, -/* INSB INSW OUTSB OUTSW*/ - 0, 0, 0, 0, - -/* Jxx*/ -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, -/* TEST TEST XCHG XCHG*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* MOV MOV MOV MOV*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, -/* MOV from seg LEA MOV to seg POP*/ - MODRM, DSTDEP_REG | MODRM, MODRM, IMPL_ESP | MODRM, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX, -/* XCHG XCHG XCHG XCHG*/ - SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI, -/* CBW CWD CALL far WAIT*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0, -/* PUSHF POPF SAHF LAHF*/ - IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX, - -/* MOV MOV MOV MOV*/ -/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, -/* MOVSB MOVSW CMPSB CMPSW*/ - 0, 0, 0, 0, -/* TEST TEST STOSB STOSW*/ - SRCDEP_EAX, SRCDEP_EAX, 0, 0, -/* LODSB LODSW SCASB SCASW*/ - 0, 0, 0, 0, - -/* MOV*/ -/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI, - -/* RET imm RET*/ -/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, -/* LES LDS MOV MOV*/ - DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, MODRM, MODRM, -/* ENTER LEAVE RETF RETF*/ - IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP, -/* INT3 INT INTO IRET*/ - 0, 0, 0, 0, - - -/*d0*/ 0, 0, 0, 0, -/* AAM AAD SETALC XLAT*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX, -/* IN AL IN AX OUT_AL OUT_AX*/ - DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, -/* CALL JMP JMP JMP*/ - IMPL_ESP, 0, 0, 0, -/* IN AL IN AX OUT_AL OUT_AX*/ - SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, - -/* REPNE REPE*/ -/*f0*/ 0, 0, 0, 0, -/* HLT CMC*/ - 0, 0, 0, 0, -/* CLC STC CLI STI*/ - 0, 0, 0, 0, -/* CLD STD INCDEC*/ - 0, 0, MODRM, 0 -}; - -uint64_t opcode_deps_mod3[256] = -{ -/* 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*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* OR OR OR OR*/ - 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, -/* OR OR PUSH CS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0, - -/* ADC ADC ADC ADC*/ -/*10*/ 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, -/* ADC ADC PUSH SS POP SS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* SBB SBB SBB SBB*/ - 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, -/* SBB SBB PUSH DS POP DS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, - -/* AND AND AND AND*/ -/*20*/ 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, -/* AND AND DAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* SUB SUB SUB SUB*/ - 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, -/* SUB SUB DAS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, - -/* XOR XOR XOR XOR*/ -/*30*/ 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, -/* XOR XOR AAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* CMP CMP CMP CMP*/ - SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, -/* CMP CMP AAS*/ - SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, -/* INC ESP INC EBP INC ESI INC EDI*/ - SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP, -/* POP EAX POP ECX POP EDX POP EBX*/ - DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP, -/* POP ESP POP EBP POP ESI POP EDI*/ - DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ IMPL_ESP, IMPL_ESP, 0, 0, - 0, 0, 0, 0, -/* PUSH imm IMUL PUSH imm IMUL*/ - IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, -/* INSB INSW OUTSB OUTSW*/ - 0, 0, 0, 0, - -/* Jxx*/ -/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, -/* TEST TEST XCHG XCHG*/ - SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, -/* MOV MOV MOV MOV*/ - SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM, -/* MOV from seg LEA MOV to seg POP*/ - DSTDEP_RM | MODRM, DSTDEP_REG | MODRM, SRCDEP_RM | MODRM, IMPL_ESP | DSTDEP_RM | MODRM, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX, -/* XCHG XCHG XCHG XCHG*/ - SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI, -/* CBW CWD CALL far WAIT*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0, -/* PUSHF POPF SAHF LAHF*/ - IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX, - -/* MOV MOV MOV MOV*/ -/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, -/* MOVSB MOVSW CMPSB CMPSW*/ - 0, 0, 0, 0, -/* TEST TEST STOSB STOSW*/ - SRCDEP_EAX, SRCDEP_EAX, 0, 0, -/* LODSB LODSW SCASB SCASW*/ - 0, 0, 0, 0, - -/* MOV*/ -/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI, - -/* RET imm RET*/ -/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, -/* LES LDS MOV MOV*/ - DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_RM | MODRM, DSTDEP_RM | MODRM, -/* ENTER LEAVE RETF RETF*/ - IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP, -/* INT3 INT INTO IRET*/ - 0, 0, 0, 0, - - -/*d0*/ 0, 0, 0, 0, -/* AAM AAD SETALC XLAT*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX, -/* IN AL IN AX OUT_AL OUT_AX*/ - DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, -/* CALL JMP JMP JMP*/ - IMPL_ESP, 0, 0, 0, -/* IN AL IN AX OUT_AL OUT_AX*/ - SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, - -/* REPNE REPE*/ -/*f0*/ 0, 0, 0, 0, -/* HLT CMC*/ - 0, 0, 0, 0, -/* CLC STC CLI STI*/ - 0, 0, 0, 0, -/* CLD STD INCDEC*/ - 0, 0, SRCDEP_RM | DSTDEP_RM | MODRM, 0 -}; - -uint64_t opcode_deps_0f[256] = -{ -/*00*/ MODRM, MODRM, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, MODRM, - -/*10*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*20*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*30*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*40*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*50*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*60*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - MODRM, MODRM, MODRM, MODRM, - MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, 0, MODRM, MODRM, - -/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - MODRM, MODRM, MODRM, 0, - 0, 0, 0, 0, - 0, 0, MODRM, MODRM, - -/*80*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*90*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - -/*a0*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*b0*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - 0, 0, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - -/*c0*/ MODRM, MODRM, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, MODRM, 0, - MODRM, MODRM, MODRM, 0, -}; -uint64_t opcode_deps_0f_mod3[256] = -{ -/*00*/ MODRM, MODRM, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, MODRM, - -/*10*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*20*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*30*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*40*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*50*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*60*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - MODRM, MODRM, MODRM, MODRM, - MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, 0, MODRM, MODRM, - -/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - MODRM, MODRM, MODRM, 0, - 0, 0, 0, 0, - 0, 0, MODRM, MODRM, - -/*80*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*90*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - -/*a0*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*b0*/ MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - 0, 0, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, - -/*c0*/ MODRM, MODRM, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, 0, MODRM, - MODRM, MODRM, 0, MODRM, - -/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, - 0, MODRM | MMX_MULTIPLY, 0, 0, - MODRM, MODRM, MODRM, 0, - MODRM, MODRM, MODRM, 0, -}; - -uint64_t opcode_deps_0f0f[256] = -{ -/*00*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, 0, - -/*10*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, 0, - -/*20*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*30*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*40*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*50*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*60*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*70*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*90*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, MODRM, 0, - 0, 0, MODRM, 0, - -/*a0*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*b0*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, MODRM, - -/*c0*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*d0*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*e0*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*f0*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; -uint64_t opcode_deps_0f0f_mod3[256] = -{ -/*00*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, 0, - -/*10*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, 0, - -/*20*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*30*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*40*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*50*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*60*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*70*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*80*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*90*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, MODRM, 0, - 0, 0, MODRM, 0, - -/*a0*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*b0*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, MODRM, - -/*c0*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*d0*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*e0*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*f0*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, -}; - -uint64_t opcode_deps_shift[8] = -{ - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM, -}; -uint64_t opcode_deps_shift_mod3[8] = -{ - 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, -}; - -uint64_t opcode_deps_shift_cl[8] = -{ - MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, - MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, -}; -uint64_t opcode_deps_shift_cl_mod3[8] = -{ - 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, -}; - -uint64_t opcode_deps_f6[8] = -{ -/* 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 -}; -uint64_t opcode_deps_f6_mod3[8] = -{ -/* 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 -}; -uint64_t opcode_deps_f7[8] = -{ -/* 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 -}; -uint64_t opcode_deps_f7_mod3[8] = -{ -/* 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 -}; -uint64_t opcode_deps_ff[8] = -{ -/* INC DEC CALL CALL far*/ - MODRM, MODRM, MODRM | IMPL_ESP, MODRM, -/* JMP JMP far PUSH*/ - MODRM, MODRM, MODRM | IMPL_ESP, 0 -}; -uint64_t opcode_deps_ff_mod3[8] = -{ -/* 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 -}; - -uint64_t opcode_deps_d8[8] = -{ -/* 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 -}; -uint64_t opcode_deps_d8_mod3[8] = -{ -/* 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 -}; - -uint64_t opcode_deps_d9[8] = -{ -/* FLDs FSTs FSTPs*/ - FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_POP | MODRM, -/* FLDENV FLDCW FSTENV FSTCW*/ - MODRM, MODRM, MODRM, MODRM -}; -uint64_t opcode_deps_d9_mod3[64] = -{ - /*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, - /*FXCH*/ - FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH, - FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH, - /*FNOP*/ - 0, 0, 0, 0, 0, 0, 0, 0, - /*FSTP*/ - FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, - FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, -/* opFCHS opFABS*/ - 0, 0, 0, 0, -/* opFTST opFXAM*/ - 0, 0, 0, 0, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - FPU_PUSH, FPU_PUSH, FPU_PUSH, FPU_PUSH, -/* opFLDEG2 opFLDLN2 opFLDZ*/ - FPU_PUSH, FPU_PUSH, FPU_PUSH, 0, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - 0, 0, 0, 0, -/* opFDECSTP opFINCSTP,*/ - 0, 0, 0, 0, -/* opFPREM opFSQRT opFSINCOS*/ - 0, 0, 0, 0, -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - 0, 0, 0, 0 -}; - -uint64_t opcode_deps_da[8] = -{ -/* 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 -}; -uint64_t opcode_deps_da_mod3[8] = -{ - 0, 0, 0, 0, -/* FCOMPP*/ - 0, FPU_POP2, 0, 0 -}; - - -uint64_t opcode_deps_db[8] = -{ -/* 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 -}; -uint64_t opcode_deps_db_mod3[64] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - - - 0, 0, 0, 0, 0, 0, 0, 0, - -/* opFNOP opFCLEX opFINIT*/ - 0, 0, 0, 0, -/* opFNOP opFNOP*/ - 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -uint64_t opcode_deps_dc[8] = -{ -/* 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 -}; -uint64_t opcode_deps_dc_mod3[8] = -{ -/* 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 -}; - -uint64_t opcode_deps_dd[8] = -{ -/* FLDd FSTd FSTPd*/ - FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, -/* FRSTOR FSAVE FSTSW*/ - MODRM, 0, MODRM, MODRM -}; -uint64_t opcode_deps_dd_mod3[8] = -{ -/* 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 -}; - -uint64_t opcode_deps_de[8] = -{ -/* 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 -}; -uint64_t opcode_deps_de_mod3[8] = -{ -/* 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 -}; - -uint64_t opcode_deps_df[8] = -{ -/* 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 -}; -uint64_t opcode_deps_df_mod3[8] = -{ - 0, 0, 0, 0, -/* FSTSW AX*/ - 0, 0, 0, 0 -}; - -uint64_t opcode_deps_81[8] = -{ - MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, - MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632 -}; -uint64_t opcode_deps_81_mod3[8] = -{ - 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 -}; -uint64_t opcode_deps_8x[8] = -{ - MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, - MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8 -}; -uint64_t opcode_deps_8x_mod3[8] = -{ - 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 -}; diff --git a/src/cpu_new/codegen_timing_common.h b/src/cpu_new/codegen_timing_common.h deleted file mode 100644 index 19c28b998..000000000 --- a/src/cpu_new/codegen_timing_common.h +++ /dev/null @@ -1,231 +0,0 @@ -#include "codegen_ops.h" - -/*Instruction has input dependency on register in REG field*/ -#define SRCDEP_REG (1ull << 0) -/*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1ull << 1) -/*Instruction modifies register in REG field*/ -#define DSTDEP_REG (1ull << 2) -/*Instruction modifies register in R/M field*/ -#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) - -/*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) - -/*Instruction has ModR/M byte*/ -#define MODRM (1ull << 20) -/*Instruction implicitly uses ESP*/ -#define IMPL_ESP (1ull << 21) - -/*Instruction is MMX shift or pack/unpack instruction*/ -#define MMX_SHIFTPACK (1ull << 22) -/*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1ull << 23) - -/*Instruction pops the FPU stack*/ -#define FPU_POP (1ull << 24) -/*Instruction pops the FPU stack twice*/ -#define FPU_POP2 (1ull << 25) -/*Instruction pushes onto the FPU stack*/ -#define FPU_PUSH (1ull << 26) - -/*Instruction writes to ST(0)*/ -#define FPU_WRITE_ST0 (1ull << 27) -/*Instruction reads from ST(0)*/ -#define FPU_READ_ST0 (1ull << 28) -/*Instruction reads from and writes to ST(0)*/ -#define FPU_RW_ST0 (3ull << 27) - -/*Instruction reads from ST(1)*/ -#define FPU_READ_ST1 (1ull << 29) -/*Instruction writes to ST(1)*/ -#define FPU_WRITE_ST1 (1ull << 30) -/*Instruction reads from and writes to ST(1)*/ -#define FPU_RW_ST1 (3ull << 29) - -/*Instruction reads from ST(reg)*/ -#define FPU_READ_STREG (1ull << 31) -/*Instruction writes to ST(reg)*/ -#define FPU_WRITE_STREG (1ull << 32) -/*Instruction reads from and writes to ST(reg)*/ -#define FPU_RW_STREG (3ull << 30) - -#define FPU_FXCH (1ull << 33) - -#define HAS_IMM8 (1ull << 34) -#define HAS_IMM1632 (1ull << 35) - - -#define REGMASK_IMPL_ESP (1 << 8) -#define REGMASK_SHIFTPACK (1 << 9) -#define REGMASK_MULTIPLY (1 << 9) - - -extern uint64_t opcode_deps[256]; -extern uint64_t opcode_deps_mod3[256]; -extern uint64_t opcode_deps_0f[256]; -extern uint64_t opcode_deps_0f_mod3[256]; -extern uint64_t opcode_deps_0f0f[256]; -extern uint64_t opcode_deps_0f0f_mod3[256]; -extern uint64_t opcode_deps_shift[8]; -extern uint64_t opcode_deps_shift_mod3[8]; -extern uint64_t opcode_deps_shift_cl[8]; -extern uint64_t opcode_deps_shift_cl_mod3[8]; -extern uint64_t opcode_deps_f6[8]; -extern uint64_t opcode_deps_f6_mod3[8]; -extern uint64_t opcode_deps_f7[8]; -extern uint64_t opcode_deps_f7_mod3[8]; -extern uint64_t opcode_deps_ff[8]; -extern uint64_t opcode_deps_ff_mod3[8]; -extern uint64_t opcode_deps_d8[8]; -extern uint64_t opcode_deps_d8_mod3[8]; -extern uint64_t opcode_deps_d9[8]; -extern uint64_t opcode_deps_d9_mod3[64]; -extern uint64_t opcode_deps_da[8]; -extern uint64_t opcode_deps_da_mod3[8]; -extern uint64_t opcode_deps_db[8]; -extern uint64_t opcode_deps_db_mod3[64]; -extern uint64_t opcode_deps_dc[8]; -extern uint64_t opcode_deps_dc_mod3[8]; -extern uint64_t opcode_deps_dd[8]; -extern uint64_t opcode_deps_dd_mod3[8]; -extern uint64_t opcode_deps_de[8]; -extern uint64_t opcode_deps_de_mod3[8]; -extern uint64_t opcode_deps_df[8]; -extern uint64_t opcode_deps_df_mod3[8]; -extern uint64_t opcode_deps_81[8]; -extern uint64_t opcode_deps_81_mod3[8]; -extern uint64_t opcode_deps_8x[8]; -extern uint64_t opcode_deps_8x_mod3[8]; - - - -static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) -{ - uint32_t addr_regmask = 0; - - if (data & MODRM) - { - uint8_t modrm = fetchdat & 0xff; - - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 0x7) == 4) - { - uint8_t sib = (fetchdat >> 8) & 0xff; - - if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) - { - addr_regmask = 1 << (sib & 7); - if ((sib & 0x38) != 0x20) - addr_regmask |= 1 << ((sib >> 3) & 7); - } - } - else if ((modrm & 0xc7) != 5) - { - addr_regmask = 1 << (modrm & 7); - } - } - else - { - if ((modrm & 0xc7) != 0x06) - { - switch (modrm & 7) - { - case 0: addr_regmask = REG_BX | REG_SI; break; - case 1: addr_regmask = REG_BX | REG_DI; break; - case 2: addr_regmask = REG_BP | REG_SI; break; - case 3: addr_regmask = REG_BP | REG_DI; break; - case 4: addr_regmask = REG_SI; break; - case 5: addr_regmask = REG_DI; break; - case 6: addr_regmask = REG_BP; break; - case 7: addr_regmask = REG_BX; break; - } - } - } - } - } - - if (data & IMPL_ESP) - addr_regmask |= REGMASK_IMPL_ESP; - - return addr_regmask; -} - -static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32) -{ - uint32_t mask = 0; - if (data & SRCDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & SRCDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> SRCDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; - - mask |= get_addr_regmask(data, fetchdat, op_32); - - return mask; -} - -static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) -{ - uint32_t mask = 0; - if (data & DSTDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & DSTDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> DSTDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; - if (data & IMPL_ESP) - mask |= REGMASK_IMPL_ESP | (1 << REG_ESP); - - return mask; -} diff --git a/src/cpu_new/codegen_timing_k6.c b/src/cpu_new/codegen_timing_k6.c deleted file mode 100644 index dc37bfefe..000000000 --- a/src/cpu_new/codegen_timing_k6.c +++ /dev/null @@ -1,2350 +0,0 @@ -/*Most of the vector instructions here are a total guess. - Some of the timings are based on http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/ -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> -#include <86box/machine.h> - -#include "x86.h" -#include "x86_ops.h" -#include "x87.h" -#include "386_common.h" -#include "codegen.h" -#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*/ -} uop_type_t; - -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; -} risc86_uop_t; - -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 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_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 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 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 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 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 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 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_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_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 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_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_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 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_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 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_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 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 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 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 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_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 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* ADD ADD PUSH ES POP ES*/ - &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, -/* OR OR OR OR*/ - &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* OR OR PUSH CS */ - &alux_op, &alu_op, &push_seg_op, INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, -/* ADC ADC PUSH SS POP SS*/ - &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, -/* SBB SBB SBB SBB*/ -/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, -/* SBB SBB PUSH DS POP DS*/ - &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, - -/* AND AND AND AND*/ -/*20*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* AND AND DAA*/ - &alux_op, &alu_op, INVALID, &vector_alux1_op, -/* SUB SUB SUB SUB*/ - &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* SUB SUB DAS*/ - &alux_op, &alu_op, INVALID, &vector_alux1_op, - -/* XOR XOR XOR XOR*/ -/*30*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* XOR XOR AAA*/ - &alux_op, &alu_op, INVALID, &vector_alux6_op, -/* CMP CMP CMP CMP*/ - &load_alux_op, &load_alu_op, &load_alux_op, &load_alu_op, -/* CMP CMP AAS*/ - &alux_op, &alu_op, INVALID, &vector_alux6_op, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* INC ESP INC EBP INC ESI INC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ &store_op, &store_op, &store_op, &store_op, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - &store_op, &store_op, &store_op, &store_op, -/* POP EAX POP ECX POP EDX POP EBX*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, -/* POP ESP POP EBP POP ESI POP EDI*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, -/* INSB INSW OUTSB OUTSW*/ - &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, - -/* Jxx*/ -/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - &vector_test_mem_b_op, &vector_test_mem_op, &vector_xchg_mem_op, &vector_xchg_mem_op, -/* MOV MOV MOV MOV*/ - &store_op, &store_op, &load_op, &load_op, -/* MOV from seg LEA MOV to seg POP*/ - &vector_mov_mem_seg_op, &store_op, &vector_mov_seg_mem_op, &pop_mem_op, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, -/* XCHG XCHG XCHG XCHG*/ - &xchg_op, &xchg_op, &xchg_op, &xchg_op, -/* CBW CWD CALL far WAIT*/ - &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, -/* PUSHF POPF SAHF LAHF*/ - &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, - -/* MOV MOV MOV MOV*/ -/*a0*/ &load_op, &load_op, &store_op, &store_op, -/* MOVSB MOVSW CMPSB CMPSW*/ - &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, -/* TEST TEST STOSB STOSW*/ - &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, -/* LODSB LODSW SCASB SCASW*/ - &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, - -/* MOV*/ -/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, -/* LES LDS MOV MOV*/ - &vector_lss_op, &vector_lss_op, &store_op, &store_op, -/* ENTER LEAVE RETF RETF*/ - &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, -/* INT3 INT INTO IRET*/ - &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, -/* CALL JMP JMP JMP*/ - &store_op, &branch_op, &vector_jmp_far_op, &branch_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, INVALID, INVALID, -/* HLT CMC*/ - &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, -/* CLC STC CLI STI*/ - &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 -}; - -static const risc86_instruction_t *opcode_timings_mod3[256] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ &alux_op, &alu_op, &alux_op, &alu_op, -/* ADD ADD PUSH ES POP ES*/ - &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, -/* OR OR OR OR*/ - &alux_op, &alu_op, &alux_op, &alu_op, -/* OR OR PUSH CS */ - &alux_op, &alu_op, &push_seg_op, INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, -/* ADC ADC PUSH SS POP SS*/ - &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, -/* SBB SBB SBB SBB*/ - &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, -/* SBB SBB PUSH DS POP DS*/ - &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, - -/* AND AND AND AND*/ -/*20*/ &alux_op, &alu_op, &alux_op, &alu_op, -/* AND AND DAA*/ - &alux_op, &alu_op, INVALID, &vector_alux1_op, -/* SUB SUB SUB SUB*/ - &alux_op, &alu_op, &alux_op, &alu_op, -/* SUB SUB DAS*/ - &alux_op, &alu_op, INVALID, &vector_alux1_op, - -/* XOR XOR XOR XOR*/ -/*30*/ &alux_op, &alu_op, &alux_op, &alu_op, -/* XOR XOR AAA*/ - &alux_op, &alu_op, INVALID, &vector_alux6_op, -/* CMP CMP CMP CMP*/ - &alux_op, &alu_op, &alux_op, &alu_op, -/* CMP CMP AAS*/ - &alux_op, &alu_op, INVALID, &vector_alux6_op, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* INC ESP INC EBP INC ESI INC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ &store_op, &store_op, &store_op, &store_op, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - &store_op, &store_op, &store_op, &store_op, -/* POP EAX POP ECX POP EDX POP EBX*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, -/* POP ESP POP EBP POP ESI POP EDI*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, -/* INSB INSW OUTSB OUTSW*/ - &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, - -/* Jxx*/ -/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - &vector_alu1_op, &vector_alu1_op, &vector_alu3_op, &vector_alu3_op, -/* MOV MOV MOV MOV*/ - &store_op, &store_op, &load_op, &load_op, -/* MOV from seg LEA MOV to seg POP*/ - &mov_reg_seg_op, &store_op, &vector_mov_seg_reg_op, &pop_reg_op, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, -/* XCHG XCHG XCHG XCHG*/ - &xchg_op, &xchg_op, &xchg_op, &xchg_op, -/* CBW CWD CALL far WAIT*/ - &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, -/* PUSHF POPF SAHF LAHF*/ - &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, - -/* MOV MOV MOV MOV*/ -/*a0*/ &load_op, &load_op, &store_op, &store_op, -/* MOVSB MOVSW CMPSB CMPSW*/ - &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, -/* TEST TEST STOSB STOSW*/ - &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, -/* LODSB LODSW SCASB SCASW*/ - &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, - -/* MOV*/ -/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, -/* LES LDS MOV MOV*/ - &vector_lss_op, &vector_lss_op, &store_op, &store_op, -/* ENTER LEAVE RETF RETF*/ - &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, -/* INT3 INT INTO IRET*/ - &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, -/* CALL JMP JMP JMP*/ - &store_op, &branch_op, &vector_jmp_far_op, &branch_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, INVALID, INVALID, -/* HLT CMC*/ - &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, -/* CLC STC CLI STI*/ - &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 -}; - -static const risc86_instruction_t *opcode_timings_0f[256] = -{ -/*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, - INVALID, &load_op, &vector_femms_op, &load_3dn_op, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, - &vector_alu6_op, &vector_alu6_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - INVALID, INVALID, &mload_op, &mload_op, - -/*70*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &vector_emms_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, &mstore_op, &mstore_op, - -/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*90*/ &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, - &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, - &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, - &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, - -/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_load_alu_op, - &vector_alu_store_op, &vector_alu_store_op, INVALID, INVALID, - &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_load_alu_op, - &vector_alu_store_op, &vector_alu_store_op, INVALID, &vector_mul_op, - -/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_load_alu_op, - &vector_lss_op, &vector_lss_op, &load_alux_op, &load_alu_op, - INVALID, INVALID, &vector_load_alu_op, &vector_load_alu_op, - &vector_bsx_op, &vector_bsx_op, &load_alux_op, &load_alu_op, - -/*c0*/ &vector_alux_store_op, &vector_alu_store_op, INVALID, INVALID, - INVALID, INVALID, INVALID, &vector_cmpxchg_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - -/*d0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - INVALID, &load_mmx_mul_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - -/*e0*/ &load_mmx_op, &load_mmx_shift_op, &load_mmx_shift_op, INVALID, - INVALID, &pmul_mem_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - -/*f0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - 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, -}; -static const risc86_instruction_t *opcode_timings_0f_mod3[256] = -{ -/*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, - INVALID, INVALID, &vector_femms_op, &m3dn_op, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, - &vector_alu6_op, &vector_alu6_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ &mmx_op, &mmx_op, &mmx_op, &mmx_op, - &mmx_op, &mmx_op, &mmx_op, &mmx_op, - &mmx_op, &mmx_op, &mmx_op, &mmx_op, - INVALID, INVALID, &mmx_op, &mmx_op, - -/*70*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - &mmx_op, &mmx_op, &mmx_op, &vector_emms_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, &mmx_op, &mmx_op, - -/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*90*/ &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, - &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, - &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, - &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, - -/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_alu1_op, - &vector_alu1_op, &vector_alu1_op, INVALID, INVALID, - &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_alu1_op, - &vector_alu1_op, &vector_alu1_op, INVALID, &vector_mul_op, - -/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_alu1_op, - &vector_lss_op, &vector_lss_op, &alux_op, &alu_op, - INVALID, INVALID, &vector_alu1_op, &vector_alu1_op, - &vector_bsx_op, &vector_bsx_op, &alux_op, &alu_op, - -/*c0*/ &vector_alux1_op, &vector_alu1_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - -/*d0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - INVALID, &mmx_mul_op, INVALID, INVALID, - &mmx_op, &mmx_op, INVALID, &mmx_op, - &mmx_op, &mmx_op, INVALID, &mmx_op, - -/*e0*/ &mmx_op, &mmx_shift_op, &mmx_shift_op, INVALID, - INVALID, &pmul_op, INVALID, INVALID, - &mmx_op, &mmx_op, INVALID, &mmx_op, - &mmx_op, &mmx_op, INVALID, &mmx_op, - -/*f0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - INVALID, &pmul_op, INVALID, INVALID, - &mmx_op, &mmx_op, &mmx_op, INVALID, - &mmx_op, &mmx_op, &mmx_op, INVALID, -}; - -static const risc86_instruction_t *opcode_timings_0f0f[256] = -{ -/*00*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, &load_3dn_op, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, &load_3dn_op, INVALID, INVALID, - -/*20*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*70*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*80*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*90*/ &load_3dn_op, INVALID, INVALID, INVALID, - &load_3dn_op, INVALID, &load_3dn_op, &load_3dn_op, - INVALID, INVALID, &load_3dn_op, INVALID, - INVALID, INVALID, &load_3dn_op, INVALID, - -/*a0*/ &load_3dn_op, INVALID, INVALID, INVALID, - &load_3dn_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op, - INVALID, INVALID, &load_3dn_op, INVALID, - INVALID, INVALID, &load_3dn_op, INVALID, - -/*b0*/ &load_3dn_op, INVALID, INVALID, INVALID, - &load_mmx_mul_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, &load_mmx_op, - -/*c0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*d0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*e0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*f0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -}; -static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = -{ -/*00*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, &m3dn_op, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, &m3dn_op, INVALID, INVALID, - -/*20*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*70*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*80*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*90*/ &m3dn_op, INVALID, INVALID, INVALID, - &m3dn_op, INVALID, &m3dn_op, &m3dn_op, - INVALID, INVALID, &m3dn_op, INVALID, - INVALID, INVALID, &m3dn_op, INVALID, - -/*a0*/ &m3dn_op, INVALID, INVALID, INVALID, - &m3dn_op, INVALID, &mmx_mul_op, &mmx_mul_op, - INVALID, INVALID, &m3dn_op, INVALID, - INVALID, INVALID, &m3dn_op, INVALID, - -/*b0*/ &m3dn_op, INVALID, INVALID, INVALID, - &mmx_mul_op, INVALID, &mmx_mul_op, &mmx_mul_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, &mmx_op, - -/*c0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*d0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*e0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*f0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -}; - -static const risc86_instruction_t *opcode_timings_shift[8] = -{ - &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 -}; -static const risc86_instruction_t *opcode_timings_shift_b[8] = -{ - &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 -}; -static const risc86_instruction_t *opcode_timings_shift_mod3[8] = -{ - &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, - &alu_op, &alu_op, &alu_op, &alu_op -}; -static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = -{ - &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, - &alux_op, &alux_op, &alux_op, &alux_op -}; - -static const risc86_instruction_t *opcode_timings_80[8] = -{ - &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, -}; -static const risc86_instruction_t *opcode_timings_80_mod3[8] = -{ - &alux_op, &alux_op, &alux_store_op, &alux_store_op, - &alux_op, &alux_op, &alux_op, &alux_op, -}; -static const risc86_instruction_t *opcode_timings_8x[8] = -{ - &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, -}; -static const risc86_instruction_t *opcode_timings_8x_mod3[8] = -{ - &alu_op, &alu_op, &alu_store_op, &alu_store_op, - &alu_op, &alu_op, &alu_op, &alu_op, -}; - -static const risc86_instruction_t *opcode_timings_f6[8] = -{ -/* 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, -}; -static const risc86_instruction_t *opcode_timings_f6_mod3[8] = -{ -/* 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, -}; -static const risc86_instruction_t *opcode_timings_f7[8] = -{ -/* 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, -}; -static const risc86_instruction_t *opcode_timings_f7_mod3[8] = -{ -/* 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, -}; -static const risc86_instruction_t *opcode_timings_ff[8] = -{ -/* 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 -}; -static const risc86_instruction_t *opcode_timings_ff_mod3[8] = -{ -/* 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 -}; - -static const risc86_instruction_t *opcode_timings_d8[8] = -{ -/* 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, -}; -static const risc86_instruction_t *opcode_timings_d8_mod3[8] = -{ -/* FADD FMUL FCOM FCOMP*/ - &float_op, &float_op, &float_op, &float_op, -/* FSUB FSUBR FDIV FDIVR*/ - &float_op, &float_op, &fdiv_op, &fdiv_op, -}; - -static const risc86_instruction_t *opcode_timings_d9[8] = -{ -/* 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 -}; -static const risc86_instruction_t *opcode_timings_d9_mod3[64] = -{ - /*FLD*/ - &float_op, &float_op, &float_op, &float_op, - &float_op, &float_op, &float_op, &float_op, - /*FXCH*/ - &float_op, &float_op, &float_op, &float_op, - &float_op, &float_op, &float_op, &float_op, - /*FNOP*/ - &float_op, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - &float_op, &float_op, &float_op, &float_op, - &float_op, &float_op, &float_op, &float_op, -/* opFCHS opFABS*/ - &float_op, &float_op, INVALID, INVALID, -/* opFTST opFXAM*/ - &float_op, &float_op, INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - &float_op, &float_op, &float_op, &float_op, -/* opFLDEG2 opFLDLN2 opFLDZ*/ - &float_op, &float_op, &float_op, INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - &fsin_op, &fsin_op, &fsin_op, &fsin_op, -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, &float_op, &float_op, -/* opFPREM opFSQRT opFSINCOS*/ - &fdiv_op, INVALID, &fsqrt_op, &fsin_op, -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - &float_op, &fdiv_op, &fsin_op, &fsin_op -}; - -static const risc86_instruction_t *opcode_timings_da[8] = -{ -/* 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, -}; -static const risc86_instruction_t *opcode_timings_da_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FCOMPP*/ - INVALID, &float_op, INVALID, INVALID -}; - -static const risc86_instruction_t *opcode_timings_db[8] = -{ -/* FLDil FSTil FSTPil*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, -/* FLDe FSTPe*/ - INVALID, &vector_flde_op, INVALID, &vector_fste_op -}; -static const risc86_instruction_t *opcode_timings_db_mod3[64] = -{ - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* opFNOP opFCLEX opFINIT*/ - INVALID, &float_op, &float_op, &float_op, -/* opFNOP opFNOP*/ - &float_op, &float_op, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -}; - -static const risc86_instruction_t *opcode_timings_dc[8] = -{ -/* 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, -}; -static const risc86_instruction_t *opcode_timings_dc_mod3[8] = -{ -/* opFADDr opFMULr*/ - &float_op, &float_op, INVALID, INVALID, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - &float_op, &float_op, &fdiv_op, &fdiv_op -}; - -static const risc86_instruction_t *opcode_timings_dd[8] = -{ -/* 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 -}; -static const risc86_instruction_t *opcode_timings_dd_mod3[8] = -{ -/* FFFREE FST FSTP*/ - &float_op, INVALID, &float_op, &float_op, -/* FUCOM FUCOMP*/ - &float_op, &float_op, INVALID, INVALID -}; - -static const risc86_instruction_t *opcode_timings_de[8] = -{ -/* 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, -}; -static const risc86_instruction_t *opcode_timings_de_mod3[8] = -{ -/* FADDP FMULP FCOMPP*/ - &float_op, &float_op, INVALID, &float_op, -/* FSUBP FSUBRP FDIVP FDIVRP*/ - &float_op, &float_op, &fdiv_op, &fdiv_op, -}; - -static const risc86_instruction_t *opcode_timings_df[8] = -{ -/* FILDiw FISTiw FISTPiw*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, -/* FILDiq FBSTP FISTPiq*/ - INVALID, &load_float_op, &vector_float_l_op, &fstore_op, -}; -static const risc86_instruction_t *opcode_timings_df_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - &float_op, INVALID, INVALID, INVALID -}; - - -static uint8_t last_prefix; -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; -} k6_unit_t; - -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*/ -}; -#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*/ -}; -#define NR_K6_2_UNITS (sizeof(k6_2_units) / sizeof(k6_unit_t)) - -/*First available cycles of shared execution units. Each of these can be submitted - to by ALU X and Y*/ -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) -{ - int c; - 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; - - /*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 (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 (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; -} - -/*The K6 decoder can decode, per clock : - - 1 or 2 'short' instructions, each up to 2 uOPs and 7 bytes long - - 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]; -} decode_buffer; - -#define NR_OPQUADS 6 -/*Timestamps of when the last six opquads completed. The K6 scheduler retires - opquads in order, so this is needed to determine when the next can be scheduled*/ -static int opquad_completion_timestamp[NR_OPQUADS]; -static int next_opquad = 0; - -#define NR_REGS 8 -/*Timestamp of when last operation on an integer register completed*/ -static int reg_available_timestamp[NR_REGS]; -/*Timestamp of when last operation on an FPU register completed*/ -static int fpu_st_timestamp[8]; -/*Completion time of the last uop to be processed. Used to calculate timing of - dependent uop chains*/ -static int last_uop_timestamp = 0; - -void decode_flush() -{ - int c; - 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]; - - /*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; - - 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; - 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) -{ - 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; - } - } - - return len; -} - -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); - - /*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 (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; - - 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(); - } - 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; - - 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(); - } - } - 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() -{ - 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() -{ - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].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; - } - 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: - 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); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); -} - -void codegen_timing_k6_block_end() -{ - 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); - } -} - -int codegen_timing_k6_jump_cycles() -{ - 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 -}; diff --git a/src/cpu_new/codegen_timing_p6.c b/src/cpu_new/codegen_timing_p6.c deleted file mode 100644 index 3cb15bf68..000000000 --- a/src/cpu_new/codegen_timing_p6.c +++ /dev/null @@ -1,2105 +0,0 @@ -/*Basic P6 timing model by plant/nerd73. Based on the K6 timing model*/ -/*Some cycle timings come from https://www.agner.org/optimize/instruction_tables.pdf*/ -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> -#include <86box/machine.h> - -#include "x86.h" -#include "x86_ops.h" -#include "x87.h" -#include "386_common.h" -#include "codegen.h" -#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*/ -} uop_type_t; - -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; -} p6_uop_t; - -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 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_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 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 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 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 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 loop_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .latency = 2} -}; -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 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 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_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 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_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 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_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 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_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 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_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 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 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 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_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 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_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 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 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 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 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 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 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_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 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 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 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 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 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 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 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 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 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 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 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 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 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_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_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_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 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 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 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 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 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_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_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 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} -}; -#define INVALID NULL - -static const macro_op_t *opcode_timings[256] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, -/* ADD ADD PUSH ES POP ES*/ - &alup0_op, &alu_op, &push_seg_op, &mov_seg_mem_op, -/* OR OR OR OR*/ - &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, -/* OR OR PUSH CS */ - &alup0_op, &alu_op, &push_seg_op, INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, -/* ADC ADC PUSH SS POP SS*/ - &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, -/* SBB SBB SBB SBB*/ -/*10*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, -/* SBB SBB PUSH DS POP DS*/ - &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, - -/* AND AND AND AND*/ -/*20*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, -/* AND AND DAA*/ - &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, -/* SUB SUB SUB SUB*/ - &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, -/* SUB SUB DAS*/ - &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, - -/* XOR XOR XOR XOR*/ -/*30*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, -/* XOR XOR AAA*/ - &alup0_op, &alu_op, INVALID, &alup0_6_op, -/* CMP CMP CMP CMP*/ - &load_alup0_op, &load_alu_op, &load_alup0_op, &load_alu_op, -/* CMP CMP AAS*/ - &alup0_op, &alu_op, INVALID, &alup0_6_op, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* INC ESP INC EBP INC ESI INC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ &store_op, &store_op, &store_op, &store_op, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - &store_op, &store_op, &store_op, &store_op, -/* POP EAX POP ECX POP EDX POP EBX*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, -/* POP ESP POP EBP POP ESI POP EDI*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &mul_op, &push_imm_op, &mul_op, -/* INSB INSW OUTSB OUTSW*/ - &ins_op, &ins_op, &outs_op, &outs_op, - -/* Jxx*/ -/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - &test_mem_b_op, &test_mem_op, &xchg_mem_op, &xchg_mem_op, -/* MOV MOV MOV MOV*/ - &store_op, &store_op, &load_op, &load_op, -/* MOV from seg LEA MOV to seg POP*/ - &mov_mem_seg_op, &store_op, &mov_seg_mem_op, &pop_mem_op, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ &fxch_op, &xchg_op, &xchg_op, &xchg_op, -/* XCHG XCHG XCHG XCHG*/ - &xchg_op, &xchg_op, &xchg_op, &xchg_op, -/* CBW CWD CALL far WAIT*/ - &complex_alu1_op, &complex_alu1_op, &call_far_op, &fxch_op, -/* PUSHF POPF SAHF LAHF*/ - &pushf_op, &popf_op, &complex_alup0_1_op, &complex_alup0_1_op, - -/* MOV MOV MOV MOV*/ -/*a0*/ &load_op, &load_op, &store_op, &store_op, -/* MOVSB MOVSW CMPSB CMPSW*/ - &movs_op, &movs_op, &cmpsb_op, &cmps_op, -/* TEST TEST STOSB STOSW*/ - &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, -/* LODSB LODSW SCASB SCASW*/ - &lods_op, &lods_op, &scasb_op, &scas_op, - -/* MOV*/ -/*b0*/ &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, &ret_op, &ret_op, -/* LES LDS MOV MOV*/ - &lss_op, &lss_op, &store_op, &store_op, -/* ENTER LEAVE RETF RETF*/ - &enter_op, &leave_op, &retf_op, &retf_op, -/* INT3 INT INTO IRET*/ - &int_op, &int_op, &int_op, &iret_op, - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - &alup0_6_op, &alup0_3_op, &complex_alup0_1_op, &xlat_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &in_op, &in_op, &out_op, &out_op, -/* CALL JMP JMP JMP*/ - &store_op, &branch_op, &jmp_far_op, &branch_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &in_op, &in_op, &out_op, &out_op, - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, INVALID, INVALID, -/* HLT CMC*/ - &complex_alup0_1_op, &alu2_op, INVALID, INVALID, -/* CLC STC CLI STI*/ - &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 -}; - -static const macro_op_t *opcode_timings_mod3[256] = -{ -/* ADD ADD ADD ADD*/ -/*00*/ &alup0_op, &alu_op, &alup0_op, &alu_op, -/* ADD ADD PUSH ES POP ES*/ - &alup0_op, &alu_op, &push_seg_op, &mov_seg_mem_op, -/* OR OR OR OR*/ - &alup0_op, &alu_op, &alup0_op, &alu_op, -/* OR OR PUSH CS */ - &alup0_op, &alu_op, &push_seg_op, INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ &complex_alup0_1_op, &complex_alu1_op, &complex_alup0_1_op, &complex_alu1_op, -/* ADC ADC PUSH SS POP SS*/ - &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, -/* SBB SBB SBB SBB*/ - &complex_alup0_1_op, &complex_alu1_op, &complex_alup0_1_op, &complex_alu1_op, -/* SBB SBB PUSH DS POP DS*/ - &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, - -/* AND AND AND AND*/ -/*20*/ &alup0_op, &alu_op, &alup0_op, &alu_op, -/* AND AND DAA*/ - &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, -/* SUB SUB SUB SUB*/ - &alup0_op, &alu_op, &alup0_op, &alu_op, -/* SUB SUB DAS*/ - &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, - -/* XOR XOR XOR XOR*/ -/*30*/ &alup0_op, &alu_op, &alup0_op, &alu_op, -/* XOR XOR AAA*/ - &alup0_op, &alu_op, INVALID, &alup0_6_op, -/* CMP CMP CMP CMP*/ - &alup0_op, &alu_op, &alup0_op, &alu_op, -/* CMP CMP AAS*/ - &alup0_op, &alu_op, INVALID, &alup0_6_op, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* INC ESP INC EBP INC ESI INC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ &store_op, &store_op, &store_op, &store_op, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - &store_op, &store_op, &store_op, &store_op, -/* POP EAX POP ECX POP EDX POP EBX*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, -/* POP ESP POP EBP POP ESI POP EDI*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &mul_op, &push_imm_op, &mul_op, -/* INSB INSW OUTSB OUTSW*/ - &ins_op, &ins_op, &outs_op, &outs_op, - -/* Jxx*/ -/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - &complex_alu1_op, &complex_alu1_op, &alu3_op, &alu3_op, -/* MOV MOV MOV MOV*/ - &store_op, &store_op, &load_op, &load_op, -/* MOV from seg LEA MOV to seg POP*/ - &mov_reg_seg_op, &store_op, &mov_seg_reg_op, &pop_reg_op, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ &fxch_op, &xchg_op, &xchg_op, &xchg_op, -/* XCHG XCHG XCHG XCHG*/ - &xchg_op, &xchg_op, &xchg_op, &xchg_op, -/* CBW CWD CALL far WAIT*/ - &complex_alu1_op, &complex_alu1_op, &call_far_op, &fxch_op, -/* PUSHF POPF SAHF LAHF*/ - &pushf_op, &popf_op, &complex_alup0_1_op, &complex_alup0_1_op, - -/* MOV MOV MOV MOV*/ -/*a0*/ &load_op, &load_op, &store_op, &store_op, -/* MOVSB MOVSW CMPSB CMPSW*/ - &movs_op, &movs_op, &cmpsb_op, &cmps_op, -/* TEST TEST STOSB STOSW*/ - &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, -/* LODSB LODSW SCASB SCASW*/ - &lods_op, &lods_op, &scasb_op, &scas_op, - -/* MOV*/ -/*b0*/ &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, &ret_op, &ret_op, -/* LES LDS MOV MOV*/ - &lss_op, &lss_op, &store_op, &store_op, -/* ENTER LEAVE RETF RETF*/ - &enter_op, &leave_op, &retf_op, &retf_op, -/* INT3 INT INTO IRET*/ - &int_op, &int_op, &int_op, &iret_op, - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - &alup0_6_op, &alup0_3_op, &complex_alup0_1_op, &xlat_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &in_op, &in_op, &out_op, &out_op, -/* CALL JMP JMP JMP*/ - &store_op, &branch_op, &jmp_far_op, &branch_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &in_op, &in_op, &out_op, &out_op, - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, INVALID, INVALID, -/* HLT CMC*/ - &complex_alup0_1_op, &alu2_op, INVALID, INVALID, -/* CLC STC CLI STI*/ - &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 -}; - -static const macro_op_t *opcode_timings_0f[256] = -{ -/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, - INVALID, &alu6_op, &alu6_op, INVALID, - &invd_op, &wbinvd_op, INVALID, INVALID, - INVALID, &load_op, &femms_op, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, - &alu6_op, &alu6_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ &alu6_op, &alu6_op, &alu6_op, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - INVALID, INVALID, &mload_op, &mload_op, - -/*70*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &emms_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, &mstore_op, &mstore_op, - -/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*90*/ &setcc_reg_op, &setcc_reg_op, &setcc_reg_op, &setcc_reg_op, - &setcc_reg_op, &setcc_reg_op, &setcc_reg_op, &setcc_reg_op, - &setcc_reg_op, &setcc_reg_op, &setcc_reg_op, &setcc_reg_op, - &setcc_reg_op, &setcc_reg_op, &setcc_reg_op, &setcc_reg_op, - -/*a0*/ &push_seg_op, &mov_seg_mem_op, &cpuid_op, &load_alu_op, - &alu_store_op, &alu_store_op, INVALID, INVALID, - &push_seg_op, &mov_seg_mem_op, INVALID, &load_alu_op, - &alu_store_op, &alu_store_op, INVALID, &mul_op, - -/*b0*/ &cmpxchg_b_op, &cmpxchg_op, &lss_op, &load_alu_op, - &lss_op, &lss_op, &load_alup0_op, &load_alu_op, - INVALID, INVALID, &load_alu_op, &load_alu_op, - &bsx_op, &bsx_op, &load_alup0_op, &load_alu_op, - -/*c0*/ &alup0_store_op, &alu_store_op, INVALID, INVALID, - INVALID, INVALID, INVALID, &cmpxchg_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - -/*d0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - INVALID, &load_mmx_mul_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - -/*e0*/ &load_mmx_op, &load_mmx_shift_op, &load_mmx_shift_op, INVALID, - INVALID, &pmul_mem_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - -/*f0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - 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, -}; -static const macro_op_t *opcode_timings_0f_mod3[256] = -{ -/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, - INVALID, &alu6_op, &alu6_op, INVALID, - &invd_op, &wbinvd_op, INVALID, INVALID, - INVALID, INVALID, &femms_op, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, - &alu6_op, &alu6_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ &alu6_op, &alu6_op, &alu6_op, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ &mmx_op, &mmx_op, &mmx_op, &mmx_op, - &mmx_op, &mmx_op, &mmx_op, &mmx_op, - &mmx_op, &mmx_op, &mmx_op, &mmx_op, - INVALID, INVALID, &mmx_op, &mmx_op, - -/*70*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - &mmx_op, &mmx_op, &mmx_op, &emms_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, &mmx_op, &mmx_op, - -/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*90*/ &setcc_mem_op, &setcc_mem_op, &setcc_mem_op, &setcc_mem_op, - &setcc_mem_op, &setcc_mem_op, &setcc_mem_op, &setcc_mem_op, - &setcc_mem_op, &setcc_mem_op, &setcc_mem_op, &setcc_mem_op, - &setcc_mem_op, &setcc_mem_op, &setcc_mem_op, &setcc_mem_op, - -/*a0*/ &push_seg_op, &mov_seg_mem_op, &cpuid_op, &complex_alu1_op, - &complex_alu1_op, &complex_alu1_op, INVALID, INVALID, - &push_seg_op, &mov_seg_mem_op, INVALID, &complex_alu1_op, - &complex_alu1_op, &complex_alu1_op, INVALID, &mul_op, - -/*b0*/ &cmpxchg_b_op, &cmpxchg_op, &lss_op, &complex_alu1_op, - &lss_op, &lss_op, &alup0_op, &alu_op, - INVALID, INVALID, &complex_alu1_op, &complex_alu1_op, - &bsx_op, &bsx_op, &alup0_op, &alu_op, - -/*c0*/ &complex_alup0_1_op, &complex_alu1_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - -/*d0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - INVALID, &mmx_mul_op, INVALID, INVALID, - &mmx_op, &mmx_op, INVALID, &mmx_op, - &mmx_op, &mmx_op, INVALID, &mmx_op, - -/*e0*/ &mmx_op, &mmx_shift_op, &mmx_shift_op, INVALID, - INVALID, &pmul_op, INVALID, INVALID, - &mmx_op, &mmx_op, INVALID, &mmx_op, - &mmx_op, &mmx_op, INVALID, &mmx_op, - -/*f0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - INVALID, &pmul_op, INVALID, INVALID, - &mmx_op, &mmx_op, &mmx_op, INVALID, - &mmx_op, &mmx_op, &mmx_op, INVALID, -}; - -static const macro_op_t *opcode_timings_shift[8] = -{ - &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, - &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op -}; -static const macro_op_t *opcode_timings_shift_b[8] = -{ - &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, - &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op -}; -static const macro_op_t *opcode_timings_shift_mod3[8] = -{ - &complex_alu1_op, &complex_alu1_op, &complex_alu1_op, &complex_alu1_op, - &alu_op, &alu_op, &alu_op, &alu_op -}; -static const macro_op_t *opcode_timings_shift_b_mod3[8] = -{ - &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, - &alup0_op, &alup0_op, &alup0_op, &alup0_op -}; - -static const macro_op_t *opcode_timings_80[8] = -{ - &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, - &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, -}; -static const macro_op_t *opcode_timings_80_mod3[8] = -{ - &alup0_op, &alup0_op, &alup0_store_op, &alup0_store_op, - &alup0_op, &alup0_op, &alup0_op, &alup0_op, -}; -static const macro_op_t *opcode_timings_8x[8] = -{ - &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, - &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, -}; -static const macro_op_t *opcode_timings_8x_mod3[8] = -{ - &alu_op, &alu_op, &alu_store_op, &alu_store_op, - &alu_op, &alu_op, &alu_op, &alu_op, -}; - -static const macro_op_t *opcode_timings_f6[8] = -{ -/* 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, -}; -static const macro_op_t *opcode_timings_f6_mod3[8] = -{ -/* TST NOT NEG*/ - &test_reg_b_op, INVALID, &alup0_op, &alup0_op, -/* MUL IMUL DIV IDIV*/ - &mul_op, &mul_op, &div16_op, &div16_op, -}; -static const macro_op_t *opcode_timings_f7[8] = -{ -/* 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, -}; -static const macro_op_t *opcode_timings_f7_mod3[8] = -{ -/* TST NOT NEG*/ - &test_reg_op, INVALID, &alu_op, &alu_op, -/* MUL IMUL DIV IDIV*/ - &mul64_op, &mul64_op, &div32_op, &div32_op, -}; -static const macro_op_t *opcode_timings_ff[8] = -{ -/* 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 -}; -static const macro_op_t *opcode_timings_ff_mod3[8] = -{ -/* 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 -}; - -static const macro_op_t *opcode_timings_d8[8] = -{ -/* 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, -}; -static const macro_op_t *opcode_timings_d8_mod3[8] = -{ -/* FADD FMUL FCOM FCOMP*/ - &fadd_op, &fmul_op, &float_op, &float_op, -/* FSUB FSUBR FDIV FDIVR*/ - &float_op, &float_op, &fdiv_op, &fdiv_op, -}; - -static const macro_op_t *opcode_timings_d9[8] = -{ -/* 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 -}; -static const macro_op_t *opcode_timings_d9_mod3[64] = -{ - /*FLD*/ - &float_op, &float_op, &float_op, &float_op, - &float_op, &float_op, &float_op, &float_op, - /*FXCH*/ - &fxch_op, &fxch_op, &fxch_op, &fxch_op, - &fxch_op, &fxch_op, &fxch_op, &fxch_op, - /*FNOP*/ - &float_op, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - &float2_op, &float2_op, &float2_op, &float2_op, - &float2_op, &float2_op, &float2_op, &float2_op, -/* opFCHS opFABS*/ - &fchs_op, &float_op, INVALID, INVALID, -/* opFTST opFXAM*/ - &float_op, &float_op, INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - &float_op, &float_op, &float_op, &float_op, -/* opFLDEG2 opFLDLN2 opFLDZ*/ - &float_op, &float_op, &float_op, INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - &fsin_op, &fsin_op, &fsin_op, &fsin_op, -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, &float_op, &float_op, -/* opFPREM opFSQRT opFSINCOS*/ - &fdiv_op, INVALID, &fsqrt_op, &fsin_op, -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - &float_op, &fdiv_op, &fsin_op, &fsin_op -}; - -static const macro_op_t *opcode_timings_da[8] = -{ -/* 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, -}; -static const macro_op_t *opcode_timings_da_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FCOMPP*/ - INVALID, &float_op, INVALID, INVALID -}; - -static const macro_op_t *opcode_timings_db[8] = -{ -/* FLDil FSTil FSTPil*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, -/* FLDe FSTPe*/ - INVALID, &flde_op, INVALID, &fste_op -}; -static const macro_op_t *opcode_timings_db_mod3[64] = -{ - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* opFNOP opFCLEX opFINIT*/ - INVALID, &float_op, &float_op, &float_op, -/* opFNOP opFNOP*/ - &float_op, &float_op, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -}; - -static const macro_op_t *opcode_timings_dc[8] = -{ -/* 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, -}; -static const macro_op_t *opcode_timings_dc_mod3[8] = -{ -/* opFADDr opFMULr*/ - &fadd_op, &fmul_op, INVALID, INVALID, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - &float_op, &float_op, &fdiv_op, &fdiv_op -}; - -static const macro_op_t *opcode_timings_dd[8] = -{ -/* 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 -}; -static const macro_op_t *opcode_timings_dd_mod3[8] = -{ -/* FFFREE FST FSTP*/ - &float_op, INVALID, &float_op, &float_op, -/* FUCOM FUCOMP*/ - &float_op, &float_op, INVALID, INVALID -}; - -static const macro_op_t *opcode_timings_de[8] = -{ -/* 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, -}; -static const macro_op_t *opcode_timings_de_mod3[8] = -{ -/* FADDP FMULP FCOMPP*/ - &fadd_op, &fmul_op, INVALID, &float_op, -/* FSUBP FSUBRP FDIVP FDIVRP*/ - &float_op, &float_op, &fdiv_op, &fdiv_op, -}; - -static const macro_op_t *opcode_timings_df[8] = -{ -/* FILDiw FISTiw FISTPiw*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, -/* FILDiq FBSTP FISTPiq*/ - INVALID, &load_float_op, &complex_float_l_op, &fstore_op, -}; -static const macro_op_t *opcode_timings_df_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - &float_op, INVALID, INVALID, INVALID -}; - - -static uint8_t last_prefix; -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; -} p6_unit_t; - -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*/ -}; -#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*/ -}; -#define NR_P2_UNITS (sizeof(p2_units) / sizeof(p6_unit_t)) - -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; - - /*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; - } - } - } - 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; - - - - 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]; -} decode_buffer; - -#define NR_OPSEQS 3 -/*Timestamps of when the last three op sequences completed. Technically this is incorrect, -as the actual size of the opseq buffer is 20 bytes and not 18, but I'm restricted to multiples of 6*/ -static int opseq_completion_timestamp[NR_OPSEQS]; -static int next_opseq = 0; - -#define NR_REGS 8 -/*Timestamp of when last operation on an integer register completed*/ -static int reg_available_timestamp[NR_REGS]; -/*Timestamp of when last operation on an FPU register completed*/ -static int fpu_st_timestamp[8]; -/*Completion time of the last uop to be processed. Used to calculate timing of - dependent uop chains*/ -static int last_uop_timestamp = 0; - -void decode_flush_p6() -{ - int c; - int start_timestamp, 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]; - - /*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; - 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) -{ - 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; - } - } - - return len; -} - -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); - - /*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 (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; - - 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*/ - } - } - 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; - } - 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_p6_block_start() -{ - int c; - - for (c = 0; c < nr_units; c++) - units[c].first_available_cycle = 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_REGS; c++) - reg_available_timestamp[c] = 0; - for (c = 0; c < 8; c++) - fpu_st_timestamp[c] = 0; -} - -void codegen_timing_p6_start() -{ - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].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) -{ - if (prefix != 0x0f) - decode_timestamp++; - - last_prefix = prefix; - prefixes++; -} - -void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, 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); - - 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; - - 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: - 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); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); -} - -void codegen_timing_p6_block_end() -{ - 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); - } -} - -int codegen_timing_p6_jump_cycles() -{ - 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 -}; diff --git a/src/cpu_new/codegen_timing_pentium.c b/src/cpu_new/codegen_timing_pentium.c deleted file mode 100644 index 3daa7cb65..000000000 --- a/src/cpu_new/codegen_timing_pentium.c +++ /dev/null @@ -1,1327 +0,0 @@ -/*Elements taken into account : - - U/V integer pairing - - FPU/FXCH pairing - - Prefix decode delay (including shadowing) - - FPU latencies - - AGI stalls - Elements not taken into account : - - Branch prediction (beyond most simplistic approximation) - - PMMX decode queue - - MMX latencies -*/ - -#include -#include <86box/86box.h> -#include "cpu.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" - - - -/*Instruction has different execution time for 16 and 32 bit data. Does not pair */ -#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} -}; - -/*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_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_IMM8 (1ull << 2) -#define CYCLES_IMM1632 (2ull << 2) - -#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) -/*Instruction pairs in V pipe only*/ -#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*/ -#define PAIR_FX (5ull << 29) -/*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_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_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_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) - -#define FPU_RESULT_LATENCY(timing) ((timing >> 41) & 0xff) - - -#define INVALID 0 - -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 uint64_t *u_pipe_deps; - -static uint32_t regmask_modified; - -static uint32_t addr_regmask; - -static int fpu_latency; -static int fpu_st_latency[8]; - -static uint64_t opcode_timings[256] = -{ -/* 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*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* OR OR PUSH CS */ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, -/* ADC ADC PUSH SS POP SS*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, -/* SBB SBB PUSH DS POP DS*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), - -/* AND AND AND AND*/ -/*20*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* AND AND DAA*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), -/* SUB SUB SUB SUB*/ - PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* SUB SUB DAS*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), - -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* XOR XOR AAA*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), -/* CMP CMP CMP CMP*/ - PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, -/* CMP CMP AAS*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(8), PAIR_NP | CYCLES(7), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(10), PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(13), - -/* Jxx*/ -/*70*/ PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MOV MOV MOV MOV*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_NP | CYCLES(1), PAIR_UV | CYCLES_REG, CYCLES(3), PAIR_NP | CYCLES(3), - -/* NOP XCHG XCHG XCHG*/ -/*90*/ PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* XCHG XCHG XCHG XCHG*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* CBW CWD CALL far WAIT*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(1), -/* PUSHF POPF SAHF LAHF*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/* MOV MOV MOV MOV*/ -/*a0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* MOVSB MOVSW CMPSB CMPSW*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* TEST TEST STOSB STOSW*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* LODSB LODSW SCASB SCASW*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), - -/* MOV*/ -/*b0*/ 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, - 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, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), -/* LES LDS MOV MOV*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* ENTER LEAVE RETF RETF*/ - PAIR_NP | CYCLES(15), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* INT3 INT INTO IRET*/ - PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), -/* CALL JMP JMP JMP*/ - PAIR_V | CYCLES_REG, PAIR_V | CYCLES_REG, PAIR_NP | CYCLES(0), PAIR_V | CYCLES_REG, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* HLT CMC*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), INVALID, INVALID, -/* CLC STC CLI STI*/ - 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 -}; - -static uint64_t opcode_timings_mod3[256] = -{ -/* 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*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* OR OR PUSH CS */ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, -/* ADC ADC PUSH SS POP SS*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, -/* SBB SBB PUSH DS POP DS*/ - PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), - -/* AND AND AND AND*/ -/*20*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* AND AND DAA*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), -/* SUB SUB SUB SUB*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* SUB SUB DAS*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), - -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* XOR XOR AAA*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), -/* CMP CMP CMP CMP*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* CMP CMP AAS*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(8), PAIR_NP | CYCLES(7), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(10), PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(13), - -/* Jxx*/ -/*70*/ PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, - -/*80*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* TEST TEST XCHG XCHG*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MOV MOV MOV MOV*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_NP | CYCLES(1), PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/* NOP XCHG XCHG XCHG*/ -/*90*/ PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* XCHG XCHG XCHG XCHG*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* CBW CWD CALL far WAIT*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(1), -/* PUSHF POPF SAHF LAHF*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/* MOV MOV MOV MOV*/ -/*a0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* MOVSB MOVSW CMPSB CMPSW*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* TEST TEST STOSB STOSW*/ - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* LODSB LODSW SCASB SCASW*/ - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), - -/* MOV*/ -/*b0*/ 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, - 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, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), -/* LES LDS MOV MOV*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* ENTER LEAVE RETF RETF*/ - PAIR_NP | CYCLES(15), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* INT3 INT INTO IRET*/ - PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), -/* CALL JMP JMP JMP*/ - PAIR_V | CYCLES_REG, PAIR_V | CYCLES_REG, PAIR_NP | CYCLES(0), PAIR_V | CYCLES_REG, -/* IN AL IN AX OUT_AL OUT_AX*/ - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0), -/* HLT CMC*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), INVALID, INVALID, -/* CLC STC CLI STI*/ - 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 -}; - -static uint64_t opcode_timings_0f[256] = -{ -/*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, - INVALID, INVALID, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ PAIR_NP | CYCLES(9), CYCLES(1), PAIR_NP | CYCLES(9), INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - -/*70*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_NP | CYCLES(100), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - -/*80*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/*90*/ PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/*a0*/ PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(8), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), INVALID, INVALID, - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(10), - -/*b0*/ PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - INVALID, INVALID, PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/*c0*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - -/*d0*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - -/*e0*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, - INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - -/*f0*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - 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, -}; -static uint64_t opcode_timings_0f_mod3[256] = -{ -/*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, - INVALID, INVALID, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(9), INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*50*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*60*/ 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, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/*70*/ INVALID, 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_NP | CYCLES(100), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - -/*80*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), - -/*90*/ PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/*a0*/ PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(8), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), INVALID, INVALID, - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(10), - -/*b0*/ PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(10), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - INVALID, INVALID, PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(13), - PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), - -/*c0*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - -/*d0*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - -/*e0*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, - INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - -/*f0*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - 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, -}; - -static uint64_t opcode_timings_shift[8] = -{ - 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, -}; -static uint64_t opcode_timings_shift_mod3[8] = -{ - 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, -}; - -static uint64_t opcode_timings_f6[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_f6_mod3[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_f7[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_f7_mod3[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_ff[8] = -{ -/* 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 -}; -static uint64_t opcode_timings_ff_mod3[8] = -{ -/* 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 -}; - -static uint64_t opcode_timings_d8[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_d8_mod3[8] = -{ -/* 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) -}; - -static uint64_t opcode_timings_d9[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_d9_mod3[64] = -{ - /*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), - /*FXCH*/ - PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), - PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), - /*FNOP*/ - PAIR_NP | FPU_CYCLES(3,0,0), INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), - PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), -/* opFCHS opFABS*/ - PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), INVALID, INVALID, -/* opFTST opFXAM*/ - PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(21,4,0), INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(5,2,2), -/* opFLDEG2 opFLDLN2 opFLDZ*/ - PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(2,0,0), INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - PAIR_NP | FPU_CYCLES(53,2,2), PAIR_NP | FPU_CYCLES(103,2,2), PAIR_NP | FPU_CYCLES(120,36,0), PAIR_NP | FPU_CYCLES(112,2,2), -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), -/* opFPREM opFSQRT opFSINCOS*/ - 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) -}; - -static uint64_t opcode_timings_da[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_da_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FCOMPP*/ - INVALID, PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID -}; - - -static uint64_t opcode_timings_db[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_db_mod3[64] = -{ - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* opFNOP opFCLEX opFINIT*/ - INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(7,0,0), PAIR_NP | FPU_CYCLES(17,0,0), -/* opFNOP opFNOP*/ - PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -}; - -static uint64_t opcode_timings_dc[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_dc_mod3[8] = -{ -/* 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) -}; - -static uint64_t opcode_timings_dd[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_dd_mod3[8] = -{ -/* 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 -}; - -static uint64_t opcode_timings_de[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_de_mod3[8] = -{ -/* 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) -}; - -static uint64_t opcode_timings_df[8] = -{ -/* 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) -}; -static uint64_t opcode_timings_df_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - PAIR_NP | FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID -}; - -static uint64_t opcode_timings_81[8] = -{ - 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 -}; -static uint64_t opcode_timings_81_mod3[8] = -{ - 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 -}; -static uint64_t opcode_timings_8x[8] = -{ - 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 -}; -static uint64_t opcode_timings_8x_mod3[8] = -{ - 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 -}; - -static int decode_delay, decode_delay_offset; -static uint8_t last_prefix; -static int prefixes; - -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: - 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; -} - -/*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) -{ - 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; - } - } - - return len; -} - -void codegen_timing_pentium_block_start() -{ - u_pipe_full = decode_delay = decode_delay_offset = 0; -} - -void codegen_timing_pentium_start() -{ -// decode_delay = 0; - last_prefix = 0; - prefixes = 0; -} - -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++; - last_prefix = prefix; -} - -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); - - /*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; -} - -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; - - 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 ((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; - - 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)) - { - /* 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))) - { - 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) -{ - 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; - - 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: - 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 ((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)) - 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() -{ - 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; - } -} - -int codegen_timing_pentium_jump_cycles() -{ - return 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, - codegen_timing_pentium_jump_cycles -}; diff --git a/src/cpu_new/codegen_timing_winchip.c b/src/cpu_new/codegen_timing_winchip.c deleted file mode 100644 index bc48023ea..000000000 --- a/src/cpu_new/codegen_timing_winchip.c +++ /dev/null @@ -1,424 +0,0 @@ -#include -#include <86box/86box.h> -#include "cpu.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)) - -static int *opcode_timings[256] = -{ -/*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), -/*30*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), - -/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, - -/*80*/ &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm, &timing_rm, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0), -/*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 -}; - -static int *opcode_timings_mod3[256] = -{ -/*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), -/*30*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(4), CYCLES(2), - -/*40*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, - -/*80*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0), -/*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 -}; - -static int *opcode_timings_0f[256] = -{ -/*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, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, -/*70*/ NULL, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, &timing_rm, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rm, &timing_rm, - -/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*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, -}; -static int *opcode_timings_0f_mod3[256] = -{ -/*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, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, -/*70*/ NULL, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(100), NULL, NULL, NULL, NULL, NULL, NULL, &timing_rr, &timing_rr, - -/*80*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*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, -}; - -static int *opcode_timings_shift[8] = -{ - CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) -}; -static int *opcode_timings_shift_mod3[8] = -{ - CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) -}; - -static int *opcode_timings_f6[8] = -{ - &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static int *opcode_timings_f6_mod3[8] = -{ - &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static int *opcode_timings_f7[8] = -{ - &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static int *opcode_timings_f7_mod3[8] = -{ - &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static int *opcode_timings_ff[8] = -{ - &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL -}; -static int *opcode_timings_ff_mod3[8] = -{ - &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL -}; - -static int *opcode_timings_d8[8] = -{ -/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) -}; -static int *opcode_timings_d8_mod3[8] = -{ -/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ - CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) -}; - -static int *opcode_timings_d9[8] = -{ -/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ - CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) -}; -static int *opcode_timings_d9_mod3[64] = -{ - /*FLD*/ - CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), - /*FXCH*/ - CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), - /*FNOP*/ - CYCLES(7), NULL, NULL, NULL, NULL, NULL, NULL, NULL, - /*FSTP*/ - CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/* opFCHS opFABS opFTST opFXAM*/ - CYCLES(2), CYCLES(2), NULL, NULL, CYCLES(5), CYCLES(7), NULL, NULL, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI opFLDEG2 opFLDLN2 opFLDZ*/ - CYCLES(5), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(5), NULL, -/* opF2XM1 opFYL2X opFPTAN opFPATAN opFDECSTP opFINCSTP,*/ - 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) -}; - -static int *opcode_timings_da[8] = -{ -/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) -}; -static int *opcode_timings_da_mod3[8] = -{ - NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL -}; - - -static int *opcode_timings_db[8] = -{ -/* FLDil FSTil FSTPil FLDe FSTPe*/ - CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8) -}; -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, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/* opFNOP opFCLEX opFINIT opFNOP opFNOP*/ - NULL, CYCLES(7), CYCLES(18), CYCLES(27), CYCLES(7), CYCLES(7), NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -static int *opcode_timings_dc[8] = -{ -/* 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) -}; -static int *opcode_timings_dc_mod3[8] = -{ -/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) -}; - -static int *opcode_timings_dd[8] = -{ -/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ - CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5) -}; -static int *opcode_timings_dd_mod3[8] = -{ -/* FFFREE FST FSTP FUCOM FUCOMP*/ - CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL -}; - -static int *opcode_timings_de[8] = -{ -/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ - CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) -}; -static int *opcode_timings_de_mod3[8] = -{ -/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ - CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) -}; - -static int *opcode_timings_df[8] = -{ -/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ - CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8) -}; -static int *opcode_timings_df_mod3[8] = -{ -/* FFREE FST FSTP FUCOM FUCOMP*/ - CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL -}; - -static int *opcode_timings_8x[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_8x_mod3[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_81[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; -static int *opcode_timings_81_mod3[8] = -{ - &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm -}; - -static int timing_count; -static uint8_t last_prefix; -static uint32_t regmask_modified; - -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; -} - -void codegen_timing_winchip_block_start() -{ - regmask_modified = 0; -} - -void codegen_timing_winchip_start() -{ - timing_count = 0; - last_prefix = 0; -} - -void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) -{ - 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) -{ - int **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; - - 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: - 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); -} - -void codegen_timing_winchip_block_end() -{ -} - -int codegen_timing_winchip_jump_cycles() -{ - return 0; -} - -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, - codegen_timing_winchip_jump_cycles -}; diff --git a/src/cpu_new/codegen_timing_winchip2.c b/src/cpu_new/codegen_timing_winchip2.c deleted file mode 100644 index 0e9226960..000000000 --- a/src/cpu_new/codegen_timing_winchip2.c +++ /dev/null @@ -1,745 +0,0 @@ -/*Since IDT/Centaur didn't document cycle timings in the WinChip datasheets, and - I don't currently own a WinChip 2 to test against, most of the timing here is - a guess. This code makes the current (probably wrong) assumptions : - - FPU uses same timings as a Pentium, except for FXCH (which doesn't pair) - - 3DNow! instructions perfectly pair - - MMX follows mostly Pentium rules - one pipeline has shift/pack, one has - multiply, and other instructions can execute in either pipeline - - Instructions with prefixes can pair if both instructions are fully decoded - when the first instruction starts execution.*/ -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> - -#include "x86.h" -#include "x86_ops.h" -#include "x87.h" -#include "codegen.h" -#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 << 31) - -#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_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_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 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_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_RESULT_LATENCY(timing) ((timing >> 8) & 0xff) - -#define INVALID 0 - -static uint32_t opcode_timings[256] = -{ -/*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), -/*30*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), - -/*40*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), - -/*80*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), -/*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 -}; - -static uint32_t opcode_timings_mod3[256] = -{ -/*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), -/*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), - -/*40*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), - -/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1), -/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), -/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), -/*b0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), - -/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), -/*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, -}; - -static uint32_t opcode_timings_0f[256] = -{ -/*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, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*50*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*60*/ CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), -/*70*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), - -/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*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, -}; -static uint32_t opcode_timings_0f_mod3[256] = -{ -/*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, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, - -/*40*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*50*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*60*/ CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), -/*70*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), - -/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), -/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18,30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), - -/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*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, -}; - -static uint32_t opcode_timings_shift[8] = -{ - CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) -}; -static uint32_t opcode_timings_shift_mod3[8] = -{ - CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) -}; - -static uint32_t opcode_timings_f6[8] = -{ - CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static uint32_t opcode_timings_f6_mod3[8] = -{ - CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) -}; -static uint32_t opcode_timings_f7[8] = -{ - CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static uint32_t opcode_timings_f7_mod3[8] = -{ - CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) -}; -static uint32_t opcode_timings_ff[8] = -{ - CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID -}; -static uint32_t opcode_timings_ff_mod3[8] = -{ - CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID -}; - -static uint32_t opcode_timings_d8[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_d8_mod3[8] = -{ -/* 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) -}; - -static uint32_t opcode_timings_d9[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_d9_mod3[64] = -{ - /*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), - /*FXCH*/ - 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), - /*FNOP*/ - FPU_CYCLES(3,0,0), INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - 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), -/* opFCHS opFABS*/ - FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), INVALID, INVALID, -/* opFTST opFXAM*/ - FPU_CYCLES(1,0,0), FPU_CYCLES(21,4,0), INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - FPU_CYCLES(2,0,0), FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), -/* opFLDEG2 opFLDLN2 opFLDZ*/ - FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), FPU_CYCLES(2,0,0), INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - FPU_CYCLES(53,2,2), FPU_CYCLES(103,2,2),FPU_CYCLES(120,36,0),FPU_CYCLES(112,2,2), -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), -/* opFPREM opFSQRT opFSINCOS*/ - 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) -}; - -static uint32_t opcode_timings_da[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_da_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FCOMPP*/ - INVALID, FPU_CYCLES(1,0,0), INVALID, INVALID -}; - - -static uint32_t opcode_timings_db[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_db_mod3[64] = -{ - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/* opFNOP opFCLEX opFINIT*/ - INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(7,0,0), FPU_CYCLES(17,0,0), -/* opFNOP opFNOP*/ - FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -}; - -static uint32_t opcode_timings_dc[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_dc_mod3[8] = -{ -/* 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) -}; - -static uint32_t opcode_timings_dd[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_dd_mod3[8] = -{ -/* 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 -}; - -static uint32_t opcode_timings_de[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_de_mod3[8] = -{ -/* 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) -}; - -static uint32_t opcode_timings_df[8] = -{ -/* 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) -}; -static uint32_t opcode_timings_df_mod3[8] = -{ - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID -}; - -static uint32_t opcode_timings_8x[8] = -{ - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) -}; -static uint32_t opcode_timings_8x_mod3[8] = -{ - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) -}; -static uint32_t opcode_timings_81[8] = -{ - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) -}; -static uint32_t opcode_timings_81_mod3[8] = -{ - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) -}; - -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 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 uint64_t *u_pipe_deps; - -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; - - return 1; -} - -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); -} - -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); - - /*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; -} - -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 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; - - 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 (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]); - } - } -} - -static void codegen_timing_winchip2_block_start() -{ - regmask_modified = 0; - decode_delay = decode_delay_offset = 0; - u_pipe_full = 0; -} - -static void codegen_timing_winchip2_start() -{ - timing_count = 0; - last_prefix = 0; -} - -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++; - last_prefix = prefix; -} - -static void codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) -{ - 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; - - 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: - 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)) - 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() -{ - 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; - } -} - -int codegen_timing_winchip2_jump_cycles() -{ - return 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, - codegen_timing_winchip2_jump_cycles -}; diff --git a/src/bugger.c b/src/device/bugger.c similarity index 100% rename from src/bugger.c rename to src/device/bugger.c diff --git a/src/hwm.c b/src/device/hwm.c similarity index 100% rename from src/hwm.c rename to src/device/hwm.c diff --git a/src/hwm_lm75.c b/src/device/hwm_lm75.c similarity index 100% rename from src/hwm_lm75.c rename to src/device/hwm_lm75.c diff --git a/src/hwm_lm78.c b/src/device/hwm_lm78.c similarity index 100% rename from src/hwm_lm78.c rename to src/device/hwm_lm78.c diff --git a/src/ibm_5161.c b/src/device/ibm_5161.c similarity index 98% rename from src/ibm_5161.c rename to src/device/ibm_5161.c index f7658a7f5..3e7d4845f 100644 --- a/src/ibm_5161.c +++ b/src/device/ibm_5161.c @@ -28,7 +28,6 @@ #include <86box/pit.h> #include <86box/port_92.h> #include <86box/machine.h> -#include <86box/intel_sio.h> typedef struct diff --git a/src/isamem.c b/src/device/isamem.c similarity index 100% rename from src/isamem.c rename to src/device/isamem.c diff --git a/src/isartc.c b/src/device/isartc.c similarity index 100% rename from src/isartc.c rename to src/device/isartc.c diff --git a/src/keyboard.c b/src/device/keyboard.c similarity index 100% rename from src/keyboard.c rename to src/device/keyboard.c diff --git a/src/keyboard_at.c b/src/device/keyboard_at.c similarity index 99% rename from src/keyboard_at.c rename to src/device/keyboard_at.c index 662f20373..8976ef771 100644 --- a/src/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -1228,8 +1228,9 @@ write64_generic(void *priv, uint8_t val) (dev->input_port & 0xfc) | (fdd_is_525(current_drive) ? 0x40 : 0x00); } else { - if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) - add_data(dev, (dev->input_port | fixed_bits) & 0xef); + if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) && + ((dev->flags & KBC_VEN_MASK) != KBC_VEN_INTEL_AMI)) + add_data(dev, (dev->input_port | fixed_bits) & (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0xeb : 0xef)); else add_data(dev, dev->input_port | fixed_bits); dev->input_port = ((dev->input_port + 1) & 3) | @@ -1276,40 +1277,6 @@ write64_generic(void *priv, uint8_t val) } -static uint8_t -write60_acer(void *priv, uint8_t val) -{ -#if 0 - atkbd_t *dev = (atkbd_t *)priv; - - switch(dev->command) { - case 0xc0: /* sent by Acer V30 BIOS */ - return 0; - } -#endif - - return 1; -} - - -static uint8_t -write64_acer(void *priv, uint8_t val) -{ - atkbd_t *dev = (atkbd_t *)priv; - - kbd_log("ACER: write64(%02x, %02x)\n", dev->command, val); - -#if 0 - switch (val) { - case 0xc0: /* sent by Acer V30 BIOS */ - return 0; - } -#endif - - return write64_generic(dev, val); -} - - static uint8_t write60_ami(void *priv, uint8_t val) { @@ -2343,7 +2310,7 @@ kbd_reset(void *priv) dev->key_wantdata = 0; /* Set up the correct Video Type bits. */ - if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_XI8088) + if (((dev->flags & KBC_VEN_MASK) == KBC_VEN_XI8088) || ((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER)) dev->input_port = video_is_mda() ? 0xb0 : 0xf0; else dev->input_port = video_is_mda() ? 0xf0 : 0xb0; @@ -2422,6 +2389,7 @@ kbd_init(const device_t *info) dev->write64_ven = NULL; switch(dev->flags & KBC_VEN_MASK) { + case KBC_VEN_ACER: case KBC_VEN_GENERIC: case KBC_VEN_IBM_PS1: case KBC_VEN_XI8088: @@ -2447,11 +2415,6 @@ kbd_init(const device_t *info) dev->write60_ven = write60_toshiba; dev->write64_ven = write64_toshiba; break; - - case KBC_VEN_ACER: - dev->write60_ven = write60_acer; - dev->write64_ven = write64_acer; - break; } /* We need this, sadly. */ @@ -2601,14 +2564,10 @@ const device_t keyboard_ps2_intel_ami_pci_device = { NULL, NULL, NULL }; -const device_t keyboard_ps2_acer_device = { +const device_t keyboard_ps2_acer_pci_device = { "PS/2 Keyboard (Acer 90M002A)", DEVICE_PCI, -#ifdef KBC_VEN_ACER KBC_TYPE_PS2_NOREF | KBC_VEN_ACER, -#else - KBC_TYPE_PS2_NOREF | KBC_VEN_GENERIC, -#endif kbd_init, kbd_close, kbd_reset, diff --git a/src/keyboard_xt.c b/src/device/keyboard_xt.c similarity index 100% rename from src/keyboard_xt.c rename to src/device/keyboard_xt.c diff --git a/src/mouse.c b/src/device/mouse.c similarity index 100% rename from src/mouse.c rename to src/device/mouse.c diff --git a/src/mouse_bus.c b/src/device/mouse_bus.c similarity index 100% rename from src/mouse_bus.c rename to src/device/mouse_bus.c diff --git a/src/mouse_ps2.c b/src/device/mouse_ps2.c similarity index 100% rename from src/mouse_ps2.c rename to src/device/mouse_ps2.c diff --git a/src/mouse_serial.c b/src/device/mouse_serial.c similarity index 100% rename from src/mouse_serial.c rename to src/device/mouse_serial.c diff --git a/src/postcard.c b/src/device/postcard.c similarity index 98% rename from src/postcard.c rename to src/device/postcard.c index 683abb13b..91eb29fcd 100644 --- a/src/postcard.c +++ b/src/device/postcard.c @@ -11,6 +11,7 @@ * * * Author: RichardG, + * * Copyright 2020 RichardG. */ #include @@ -78,6 +79,7 @@ postcard_setui(void) int len = strlen(postcard_str); postcard_str[len + 1] = '\0'; postcard_str[len] = '\n'; + postcard_log("[%04X:%08X] ", CS, cpu_state.pc); postcard_log(postcard_str); } } diff --git a/src/serial.c b/src/device/serial.c similarity index 99% rename from src/serial.c rename to src/device/serial.c index f86375bdb..50a74d46c 100644 --- a/src/serial.c +++ b/src/device/serial.c @@ -606,6 +606,9 @@ serial_read(uint16_t addr, void *p) void serial_remove(serial_t *dev) { + if (dev == NULL) + return; + if (!serial_enabled[dev->inst]) return; @@ -625,6 +628,9 @@ serial_setup(serial_t *dev, uint16_t addr, int irq) { serial_log("Adding serial port %i at %04X...\n", dev->inst, addr); + if (dev == NULL) + return; + if (!serial_enabled[dev->inst]) return; if (dev->base_address != 0x0000) diff --git a/src/smbus.c b/src/device/smbus.c similarity index 100% rename from src/smbus.c rename to src/device/smbus.c diff --git a/src/smbus_piix4.c b/src/device/smbus_piix4.c similarity index 100% rename from src/smbus_piix4.c rename to src/device/smbus_piix4.c diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 4312bf54e..5c40d1b69 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -118,6 +118,7 @@ typedef struct { diag, force_ata3; uint16_t base_main, side_main; pc_timer_t timer; + ide_t *ide[2]; } ide_board_t; typedef struct { @@ -129,7 +130,7 @@ typedef struct { static ide_board_t *ide_boards[4] = { NULL, NULL, NULL, NULL }; static ide_bm_t *ide_bm[4] = { NULL, NULL, NULL, NULL }; -static ide_t *ide_drives[IDE_NUM]; +ide_t *ide_drives[IDE_NUM]; int ide_ter_enabled = 0, ide_qua_enabled = 0; static void ide_atapi_callback(ide_t *ide); @@ -280,7 +281,7 @@ ide_irq_raise(ide_t *ide) ide_log("IDE %i: IRQ raise\n", ide->board); - if (!(ide->fdisk & 2)) { + if (!(ide->fdisk & 2) && ide->selected) { if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); else if (ide_boards[ide->board]->irq != -1) @@ -300,9 +301,9 @@ ide_irq_lower(ide_t *ide) /* ide_log("Lowering IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - ide_log("IDE %i: IRQ lower\n", ide->board); + // ide_log("IDE %i: IRQ lower\n", ide->board); - if (ide->irqstat) { + if (ide->irqstat && ide->selected) { if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); else if (ide_boards[ide->board]->irq != -1) @@ -330,7 +331,7 @@ ide_irq_update(ide_t *ide) picintc(1 << ide_boards[ide->board]->irq); picint(1 << ide_boards[ide->board]->irq); } - } else if (ide->fdisk & 2) { + } else if ((ide->fdisk & 2) || !ide->irqstat) { ide_log("IDE %i: IRQ update lower\n", ide->board); if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); @@ -819,6 +820,9 @@ ide_zero(int d) dev->atastat = DRDY_STAT | DSC_STAT; dev->service = 0; dev->board = d >> 1; + dev->selected = !(d & 1); + ide_boards[dev->board]->ide[d & 1] = dev; + timer_add(&dev->timer, ide_callback, dev, 0); } @@ -847,14 +851,31 @@ ide_atapi_attach(ide_t *ide) void -ide_set_callback(uint8_t board, double callback) +ide_set_callback(ide_t *ide, double callback) +{ + ide_log("ide_set_callback(%i)\n", ide->channel); + + if (!ide) { + ide_log("Set callback failed\n"); + return; + } + + if (callback == 0.0) + timer_stop(&ide->timer); + else + timer_on_auto(&ide->timer, callback); +} + + +void +ide_set_board_callback(uint8_t board, double callback) { ide_board_t *dev = ide_boards[board]; ide_log("ide_set_callback(%i)\n", board); if (!dev) { - ide_log("Set callback failed\n"); + ide_log("Set board callback failed\n"); return; } @@ -872,7 +893,7 @@ ide_atapi_command_bus(ide_t *ide) ide->sc->phase = 1; ide->sc->pos = 0; ide->sc->callback = 1.0 * IDE_TIME; - ide_set_callback(ide->board, ide->sc->callback); + ide_set_callback(ide, ide->sc->callback); } @@ -1008,7 +1029,7 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) dev->status = BSY_STAT; dev->phase = 1; ide_atapi_callback(ide); - ide_set_callback(ide->board >> 1, 0.0); + ide_set_callback(ide, 0.0); dev->request_pos = 0; } @@ -1164,9 +1185,9 @@ ide_write_data(ide_t *ide, uint32_t val, int length) ide->pos=0; ide->atastat = BSY_STAT; if (ide->command == WIN_WRITE_MULTIPLE) - ide_callback(ide_boards[ide->board]); + ide_callback(ide); else - ide_set_callback(ide->board, ide_get_period(ide, 512)); + ide_set_callback(ide, ide_get_period(ide, 512)); } } } @@ -1276,7 +1297,8 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) /* Reset toggled from 0 to 1, initiate reset procedure. */ if (ide->type == IDE_ATAPI) ide->sc->callback = 0.0; - ide_set_callback(ide->board, 0.0); + ide_set_callback(ide, 0.0); + ide_set_callback(ide_other, 0.0); } else if (!(val & 4) && (ide->fdisk & 4)) { /* Reset toggled from 1 to 0. */ if (!(ch & 1)) { @@ -1302,7 +1324,9 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) /* Fire the timer. */ dev->diag = 0; ide->reset = 1; - ide_set_callback(ide->board, 500 * IDE_TIME); + ide_set_callback(ide, 0.0); + ide_set_callback(ide_other, 0.0); + ide_set_board_callback(ide->board, 500 * IDE_TIME); } else { /* Currently active device is 1, simply reset the status and the active device. */ dev_reset(ide); @@ -1313,6 +1337,13 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) ide->sc->error = 1; } dev->cur_dev &= ~1; + ch = dev->cur_dev; + + ide = ide_drives[ch]; + ide->selected = 1; + + ide_other = ide_drives[ch ^ 1]; + ide_other->selected = 0; } } @@ -1418,6 +1449,12 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_boards[ide->board]->cur_dev = ((val >> 4) & 1) + (ide->board << 1); ch = ide_boards[ide->board]->cur_dev; + ide = ide_drives[ch]; + ide->selected = 1; + + ide_other = ide_drives[ch ^ 1]; + ide_other->selected = 0; + if (ide->reset || ide_other->reset) { ide->atastat = ide_other->atastat = DRDY_STAT | DSC_STAT; ide->error = ide_other->error = 1; @@ -1445,11 +1482,11 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_other->cylinder = 0xEB14; } - ide_set_callback(ide->board, 0.0); + ide_set_callback(ide, 0.0); + ide_set_callback(ide_other, 0.0); + ide_set_board_callback(ide->board, 0.0); return; } - - ide = ide_drives[ch]; } ide->head = val & 0xF; @@ -1482,7 +1519,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) if (ide->type == IDE_ATAPI) ide->sc->callback = 100.0 * IDE_TIME; - ide_set_callback(ide->board, 100.0 * IDE_TIME); + ide_set_callback(ide, 100.0 * IDE_TIME); return; } @@ -1494,7 +1531,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) } else ide->atastat = DRDY_STAT; - ide_set_callback(ide->board, 100.0 * IDE_TIME); + ide_set_callback(ide, 100.0 * IDE_TIME); return; case WIN_READ_MULTIPLE: @@ -1522,15 +1559,15 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) if (ide->type == IDE_HDD) { if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { if (ide->secount) - ide_set_callback(ide->board, ide_get_period(ide, (int) ide->secount << 9)); + ide_set_callback(ide, ide_get_period(ide, (int) ide->secount << 9)); else - ide_set_callback(ide->board, ide_get_period(ide, 131072)); + ide_set_callback(ide, ide_get_period(ide, 131072)); } else if (val == WIN_READ_MULTIPLE) - ide_set_callback(ide->board, 200.0 * IDE_TIME); + ide_set_callback(ide, 200.0 * IDE_TIME); else - ide_set_callback(ide->board, ide_get_period(ide, 512)); + ide_set_callback(ide, ide_get_period(ide, 512)); } else - ide_set_callback(ide->board, 200.0 * IDE_TIME); + ide_set_callback(ide, 200.0 * IDE_TIME); ide->do_initial_read = 1; return; @@ -1570,14 +1607,16 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) if ((ide->type == IDE_HDD) && ((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) { if (ide->secount) - ide_set_callback(ide->board, ide_get_period(ide, (int) ide->secount << 9)); + ide_set_callback(ide, ide_get_period(ide, (int) ide->secount << 9)); else - ide_set_callback(ide->board, ide_get_period(ide, 131072)); + ide_set_callback(ide, ide_get_period(ide, 131072)); } else if ((ide->type == IDE_HDD) && ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) - ide_set_callback(ide->board, ide_get_period(ide, 512)); + ide_set_callback(ide, ide_get_period(ide, 512)); + else if (val == WIN_IDENTIFY) + ide_callback(ide); else - ide_set_callback(ide->board, 200.0 * IDE_TIME); + ide_set_callback(ide, 200.0 * IDE_TIME); return; case WIN_FORMAT: @@ -1596,13 +1635,15 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) } else ide->atastat = BSY_STAT; - ide_set_callback(ide->board, 30.0 * IDE_TIME); + ide_set_callback(ide, 30.0 * IDE_TIME); return; case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ dev->cur_dev &= ~1; ide = ide_drives[ch & ~1]; + ide->selected = 1; ide_other = ide_drives[ch | 1]; + ide_other->selected = 0; /* Device 0. */ dev_reset(ide); @@ -1625,7 +1666,9 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) /* Fire the timer. */ dev->diag = 1; ide->reset = 1; - ide_set_callback(ide->board, 200 * IDE_TIME); + ide_set_callback(ide, 0.0); + ide_set_callback(ide_other, 0.0); + ide_set_board_callback(ide->board, 200 * IDE_TIME); return; case WIN_PIDENTIFY: /* Identify Packet Device */ @@ -1640,7 +1683,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->sc->status = BSY_STAT; else ide->atastat = BSY_STAT; - ide_callback(dev); + ide_callback(ide); return; case WIN_PACKETCMD: /* ATAPI Packet */ @@ -1654,7 +1697,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_irq_raise(ide); /* Interrupt DRQ, requires IRQ on any DRQ. */ } else { ide->atastat = BSY_STAT; - ide_set_callback(ide->board, 200.0 * IDE_TIME); + ide_set_callback(ide, 200.0 * IDE_TIME); ide->pos=0; } return; @@ -1738,9 +1781,9 @@ ide_read_data(ide_t *ide, int length) ide_next_sector(ide); ide->atastat = BSY_STAT | READY_STAT | DSC_STAT; if (ide->command == WIN_READ_MULTIPLE) - ide_callback(ide_boards[ide->board]); + ide_callback(ide); else - ide_set_callback(ide->board, ide_get_period(ide, 512)); + ide_set_callback(ide, ide_get_period(ide, 512)); } else if (ide->command != WIN_READ_MULTIPLE) ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } @@ -1946,41 +1989,40 @@ ide_readl(uint16_t addr, void *priv) } +static void +ide_board_callback(void *priv) +{ + ide_board_t *dev = (ide_board_t *) priv; + +#ifdef ENABLE_IDE_LOG + ide_log("CALLBACK RESET\n"); +#endif + + dev->ide[0]->atastat = DRDY_STAT | DSC_STAT; + if (dev->ide[0]->type == IDE_ATAPI) + dev->ide[0]->sc->status = DRDY_STAT | DSC_STAT; + + dev->ide[1]->atastat = DRDY_STAT | DSC_STAT; + if (dev->ide[1]->type == IDE_ATAPI) + dev->ide[1]->sc->status = DRDY_STAT | DSC_STAT; + + dev->cur_dev &= ~1; + + if (dev->diag) { + dev->diag = 0; + ide_irq_raise(dev->ide[0]); + } +} + + static void ide_callback(void *priv) { - ide_t *ide, *ide_other; - int snum, ret = 0, ch; + int snum, ret = 0; - ide_board_t *dev = (ide_board_t *) priv; - ch = dev->cur_dev; + ide_t *ide = (ide_t *) priv; - ide = ide_drives[ch]; - ide_other = ide_drives[ch ^ 1]; - - if (ide->reset) { - ide_log("CALLBACK RESET %i %i\n", ide->reset,ch); - - ide->atastat = DRDY_STAT | DSC_STAT; - if (ide->type == IDE_ATAPI) - ide->sc->status = DRDY_STAT | DSC_STAT; - - ide_other->atastat = DRDY_STAT | DSC_STAT; - if (ide_other->type == IDE_ATAPI) - ide_other->sc->status = DRDY_STAT | DSC_STAT; - - dev->cur_dev &= ~1; - - if (dev->diag) { - dev->diag = 0; - ide_irq_raise(ide); - } - ide->reset = 0; - ide_set_callback(ide->board, 0.0); - return; - } - - ide_log("CALLBACK %02X %i %i\n", ide->command, ide->reset,ch); + ide_log("CALLBACK %02X %i %i\n", ide->command, ide->reset, ide->channel); if (((ide->command >= WIN_RECAL) && (ide->command <= 0x1F)) || ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F))) { @@ -2099,7 +2141,7 @@ ide_callback(void *priv) if (ret == 2) { /* Bus master DMA disabled, simply wait for the host to enable DMA. */ ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide->board, 6.0 * IDE_TIME); + ide_set_callback(ide, 6.0 * IDE_TIME); return; } else if (ret == 1) { /*DMA successful*/ @@ -2198,7 +2240,7 @@ ide_callback(void *priv) if (ret == 2) { /* Bus master DMA disabled, simply wait for the host to enable DMA. */ ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide->board, 6.0 * IDE_TIME); + ide_set_callback(ide, 6.0 * IDE_TIME); return; } else if (ret == 1) { /*DMA successful*/ @@ -2513,6 +2555,9 @@ ide_board_close(int board) /* Close hard disk image files (if previously open) */ for (d = 0; d < 2; d++) { c = (board << 1) + d; + + ide_boards[board]->ide[d] = NULL; + dev = ide_drives[c]; if (dev == NULL) @@ -2623,7 +2668,7 @@ ide_board_init(int board, int irq, int base_main, int side_main, int type) ide_boards[board]->side_main = side_main; ide_set_handlers(board); - timer_add(&ide_boards[board]->timer, ide_callback, ide_boards[board], 0); + timer_add(&ide_boards[board]->timer, ide_board_callback, ide_boards[board], 0); ide_board_setup(board); @@ -2727,6 +2772,8 @@ ide_drive_reset(int d) ide_drives[d]->atastat = DRDY_STAT | DSC_STAT; ide_drives[d]->service = 0; ide_drives[d]->board = d >> 1; + ide_drives[d]->selected = !(d & 1); + timer_stop(&ide_drives[d]->timer); if (ide_boards[d >> 1]) { ide_boards[d >> 1]->cur_dev = d & ~1; diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 7a1a043ad..6af33b4c7 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -36,6 +36,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 15bb5743e..f1c0f1599 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -49,7 +49,7 @@ hdd_string_to_bus(char *str, int cdrom) if (! strcmp(str, "mfm")) { if (cdrom) { no_cdrom: - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4099); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4099); return(0); } @@ -93,9 +93,6 @@ no_cdrom: if (! strcmp(str, "scsi")) return(HDD_BUS_SCSI); - if (! strcmp(str, "usb")) - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4110); - return(0); } diff --git a/src/disk/mo.c b/src/disk/mo.c index 1687d37f3..7df757419 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -12,8 +12,8 @@ * * * Authors: Natalia Portillo - * Fred N. van Kempen, - * Miran Grca, + * Miran Grca, + * Fred N. van Kempen, * * Copyright 2020 Miran Grca. */ @@ -29,7 +29,6 @@ #include <86box/config.h> #include <86box/timer.h> #include <86box/device.h> -#include <86box/piix.h> #include <86box/scsi_device.h> #include <86box/nvr.h> #include <86box/plat.h> @@ -413,7 +412,7 @@ static void mo_set_callback(mo_t *dev) { if (dev->drv->bus_type != MO_BUS_SCSI) - ide_set_callback(dev->drv->ide_channel >> 1, dev->callback); + ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); } @@ -1298,7 +1297,6 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) int ret; int32_t len, max_len; int32_t alloc_length; - uint32_t i = 0; int size_idx, idx = 0; unsigned preamble_len; int32_t blen = 0; @@ -1864,9 +1862,6 @@ mo_phase_data_out(scsi_common_t *sc) uint8_t hdr_len, val, old_val, ch; - uint32_t last_to_write = 0; - uint32_t c, h, s; - int len = 0; switch(dev->current_cdb[0]) { @@ -2144,6 +2139,9 @@ mo_close(void) int c; for (c = 0; c < MO_NUM; c++) { + if (mo_drives[c].bus_type == MO_BUS_SCSI) + memset(&scsi_devices[mo_drives[c].scsi_device_id], 0x00, sizeof(scsi_device_t)); + dev = (mo_t *) mo_drives[c].priv; if (dev) { diff --git a/src/disk/zip.c b/src/disk/zip.c index 8a6253100..d1f89fff6 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -27,7 +27,6 @@ #include <86box/config.h> #include <86box/timer.h> #include <86box/device.h> -#include <86box/piix.h> #include <86box/scsi_device.h> #include <86box/nvr.h> #include <86box/plat.h> @@ -579,7 +578,7 @@ static void zip_set_callback(zip_t *dev) { if (dev->drv->bus_type != ZIP_BUS_SCSI) - ide_set_callback(dev->drv->ide_channel >> 1, dev->callback); + ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); } @@ -2419,6 +2418,9 @@ zip_close(void) int c; for (c = 0; c < ZIP_NUM; c++) { + if (zip_drives[c].bus_type == ZIP_BUS_SCSI) + memset(&scsi_devices[zip_drives[c].scsi_device_id], 0x00, sizeof(scsi_device_t)); + dev = (zip_t *) zip_drives[c].priv; if (dev) { diff --git a/src/dma.c b/src/dma.c index 7a424c50b..bbfdf2118 100644 --- a/src/dma.c +++ b/src/dma.c @@ -23,12 +23,13 @@ #include #include #include <86box/86box.h> -#include "cpu_common/cpu.h" -#include "cpu_common/x86.h" +#include "cpu.h" +#include "x86.h" #include <86box/machine.h> #include <86box/mca.h> #include <86box/mem.h> #include <86box/io.h> +#include <86box/pic.h> #include <86box/dma.h> @@ -36,20 +37,19 @@ dma_t dma[8]; uint8_t dma_e; -static uint8_t dmaregs[16]; -static uint8_t dma16regs[16]; -static uint8_t dmapages[16]; -static int dma_wp, - dma16_wp; +static uint8_t dmaregs[3][16]; +static int dma_wp[2]; static uint8_t dma_m; static uint8_t dma_stat; static uint8_t dma_stat_rq; static uint8_t dma_stat_rq_pc; -static uint8_t dma_command, - dma16_command; +static uint8_t dma_command[2]; static uint8_t dma_req_is_soft; +static uint8_t dma_advanced; static uint8_t dma_buffer[65536]; +static uint16_t dma_sg_base; static uint16_t dma16_buffer[65536]; +static uint32_t dma_mask; static struct { int xfr_command, @@ -68,6 +68,26 @@ static struct { #define DMA_PS2_SIZE16 (1 << 6) +#ifdef ENABLE_DMA_LOG +int dma_do_log = ENABLE_DMA_LOG; + + +static void +dma_log(const char *fmt, ...) +{ + va_list ap; + + if (dma_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define dma_log(fmt, ...) +#endif + + static void dma_ps2_run(int channel); @@ -87,6 +107,37 @@ dma_set_drq(int channel, int set) } +static int +dma_transfer_size(dma_t *dev) +{ + return dev->transfer_mode & 0xff; +} + + +static void +dma_sg_next_addr(dma_t *dev) +{ + int ts = dma_transfer_size(dev); + + dma_bm_read(dev->ptr_cur, (uint8_t *)&(dev->addr), 4, ts); + dma_bm_read(dev->ptr_cur + 4, (uint8_t *)&(dev->count), 4, ts); + dma_log("DMA S/G DWORDs: %08X %08X\n", dev->addr, dev->count); + dev->eot = dev->count >> 31; + dev->count &= 0xfffe; + dev->cb = (uint16_t) dev->count; + dev->cc = (int) dev->count; + if (!dev->count) + dev->count = 65536; + if (ts == 2) + dev->addr &= 0xfffffffe; + dev->ab = dev->addr & dma_mask; + dev->ac = dev->addr & dma_mask; + dev->page = dev->page_l = (dev->ac >> 16) & 0xff; + dev->page_h = (dev->ac >> 24) & 0xff; + dev->ptr_cur += 8; +} + + static void dma_block_transfer(int channel) { @@ -94,6 +145,9 @@ dma_block_transfer(int channel) bit16 = (channel >= 4); + if (dma_advanced) + bit16 = !!(dma_transfer_size(&(dma[channel])) == 2); + dma_req_is_soft = 1; for (i = 0; i <= dma[channel].cb; i++) { if ((dma[channel].mode & 0x8c) == 0x84) { @@ -112,6 +166,270 @@ dma_block_transfer(int channel) } +static void +dma_sg_write(uint16_t port, uint8_t val, void *priv) +{ + dma_t *dev = (dma_t *) priv; + + dma_log("DMA S/G BYTE write: %04X %02X\n", port, val); + + port &= 0xff; + + if (port < 0x20) + port &= 0xf8; + else + port &= 0xe3; + + switch (port) { + case 0x00: + dma_log("DMA S/G Cmd : val = %02X, old = %02X\n", val, dev->sg_command); + if ((val & 1) && !(dev->sg_command & 1)) { /*Start*/ +#ifdef ENABLE_DMA_LOG + dma_log("DMA S/G start\n"); +#endif + dev->ptr_cur = dev->ptr; + dma_sg_next_addr(dev); + dev->sg_status = (dev->sg_status & 0xf7) | 0x01; + } + if (!(val & 1) && (dev->sg_command & 1)) { /*Stop*/ +#ifdef ENABLE_DMA_LOG + dma_log("DMA S/G stop\n"); +#endif + dev->sg_status &= ~0x81; + } + + dev->sg_command = val; + break; + case 0x20: + dev->ptr = (dev->ptr & 0xffffff00) | (val & 0xfc); + dev->ptr %= (mem_size * 1024); + dev->ptr0 = val; + break; + case 0x21: + dev->ptr = (dev->ptr & 0xffff00fc) | (val << 8); + dev->ptr %= (mem_size * 1024); + break; + case 0x22: + dev->ptr = (dev->ptr & 0xff00fffc) | (val << 16); + dev->ptr %= (mem_size * 1024); + break; + case 0x23: + dev->ptr = (dev->ptr & 0x00fffffc) | (val << 24); + dev->ptr %= (mem_size * 1024); + break; + } +} + + +static void +dma_sg_writew(uint16_t port, uint16_t val, void *priv) +{ + dma_t *dev = (dma_t *) priv; + + dma_log("DMA S/G WORD write: %04X %04X\n", port, val); + + port &= 0xff; + + if (port < 0x20) + port &= 0xf8; + else + port &= 0xe3; + + switch (port) { + case 0x00: + dma_sg_write(port, val & 0xff, priv); + break; + case 0x20: + dev->ptr = (dev->ptr & 0xffff0000) | (val & 0xfffc); + dev->ptr %= (mem_size * 1024); + dev->ptr0 = val & 0xff; + break; + case 0x22: + dev->ptr = (dev->ptr & 0x0000fffc) | (val << 16); + dev->ptr %= (mem_size * 1024); + break; + } +} + + +static void +dma_sg_writel(uint16_t port, uint32_t val, void *priv) +{ + dma_t *dev = (dma_t *) priv; + + dma_log("DMA S/G DWORD write: %04X %08X\n", port, val); + + port &= 0xff; + + if (port < 0x20) + port &= 0xf8; + else + port &= 0xe3; + + switch (port) { + case 0x00: + dma_sg_write(port, val & 0xff, priv); + break; + case 0x20: + dev->ptr = (val & 0xfffffffc); + dev->ptr %= (mem_size * 1024); + dev->ptr0 = val & 0xff; + break; + } +} + + +static uint8_t +dma_sg_read(uint16_t port, void *priv) +{ + dma_t *dev = (dma_t *) priv; + + uint8_t ret = 0xff; + + port &= 0xff; + + if (port < 0x20) + port &= 0xf8; + else + port &= 0xe3; + + switch (port) { + case 0x08: + ret = (dev->sg_status & 0x01); + if (dev->eot) + ret |= 0x80; + if ((dev->sg_command & 0xc0) == 0x40) + ret |= 0x20; + if (dev->ab != 0x00000000) + ret |= 0x08; + if (dev->ac != 0x00000000) + ret |= 0x04; + break; + case 0x20: + ret = dev->ptr0; + break; + case 0x21: + ret = dev->ptr >> 8; + break; + case 0x22: + ret = dev->ptr >> 16; + break; + case 0x23: + ret = dev->ptr >> 24; + break; + } + + dma_log("DMA S/G BYTE read : %04X %02X\n", port, ret); + + return ret; +} + + +static uint16_t +dma_sg_readw(uint16_t port, void *priv) +{ + dma_t *dev = (dma_t *) priv; + + uint16_t ret = 0xffff; + + port &= 0xff; + + if (port < 0x20) + port &= 0xf8; + else + port &= 0xe3; + + switch (port) { + case 0x08: + ret = (uint16_t) dma_sg_read(port, priv); + break; + case 0x20: + ret = dev->ptr0 | (dev->ptr & 0xff00); + break; + case 0x22: + ret = dev->ptr >> 16; + break; + } + + dma_log("DMA S/G WORD read : %04X %04X\n", port, ret); + + return ret; +} + + +static uint32_t +dma_sg_readl(uint16_t port, void *priv) +{ + dma_t *dev = (dma_t *) priv; + + uint32_t ret = 0xffffffff; + + port &= 0xff; + + if (port < 0x20) + port &= 0xf8; + else + port &= 0xe3; + + switch (port) { + case 0x08: + ret = (uint32_t) dma_sg_read(port, priv); + break; + case 0x20: + ret = dev->ptr0 | (dev->ptr & 0xffffff00); + break; + } + + dma_log("DMA S/G DWORD read : %04X %08X\n", port, ret); + + return ret; +} + + +static void +dma_ext_mode_write(uint16_t addr, uint8_t val, void *priv) +{ + int channel = (val & 0x03); + + if (addr == 0x4d6) + channel |= 4; + + dma[channel].ext_mode = val & 0x7c; + + switch ((val > 2) & 0x03) { + case 0x00: + dma[channel].transfer_mode = 0x0101; + break; + case 0x01: + dma[channel].transfer_mode = 0x0202; + break; + case 0x02: /* 0x02 is reserved. */ + /* Logic says this should be an undocumented mode that counts by words, + but is 8-bit I/O, thus only transferring every second byte. */ + dma[channel].transfer_mode = 0x0201; + break; + case 0x03: + dma[channel].transfer_mode = 0x0102; + break; + } +} + + +static uint8_t +dma_sg_int_status_read(uint16_t addr, void *priv) +{ + int i; + uint8_t ret = 0x00; + + for (i = 0; i < 8; i++) { + if (i != 4) + ret = (!!(dma[i].sg_status & 8)) << i; + } + + return ret; +} + + static uint8_t dma_read(uint16_t addr, void *priv) { @@ -123,8 +441,8 @@ dma_read(uint16_t addr, void *priv) case 2: case 4: case 6: /*Address registers*/ - dma_wp ^= 1; - if (dma_wp) + dma_wp[0] ^= 1; + if (dma_wp[0]) return(dma[channel].ac & 0xff); return((dma[channel].ac >> 8) & 0xff); @@ -132,8 +450,8 @@ dma_read(uint16_t addr, void *priv) case 3: case 5: case 7: /*Count registers*/ - dma_wp ^= 1; - if (dma_wp) + dma_wp[0] ^= 1; + if (dma_wp[0]) temp = dma[channel].cc & 0xff; else temp = dma[channel].cc >> 8; @@ -150,7 +468,7 @@ dma_read(uint16_t addr, void *priv) return(0); } - return(dmaregs[addr & 0xf]); + return(dmaregs[0][addr & 0xf]); } @@ -159,14 +477,14 @@ dma_write(uint16_t addr, uint8_t val, void *priv) { int channel = (addr >> 1) & 3; - dmaregs[addr & 0xf] = val; + dmaregs[0][addr & 0xf] = val; switch (addr & 0xf) { case 0: case 2: case 4: case 6: /*Address registers*/ - dma_wp ^= 1; - if (dma_wp) + dma_wp[0] ^= 1; + if (dma_wp[0]) dma[channel].ab = (dma[channel].ab & 0xffff00) | val; else dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); @@ -177,8 +495,8 @@ dma_write(uint16_t addr, uint8_t val, void *priv) case 3: case 5: case 7: /*Count registers*/ - dma_wp ^= 1; - if (dma_wp) + dma_wp[0] ^= 1; + if (dma_wp[0]) dma[channel].cb = (dma[channel].cb & 0xff00) | val; else dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8); @@ -186,7 +504,7 @@ dma_write(uint16_t addr, uint8_t val, void *priv) return; case 8: /*Control register*/ - dma_command = val; + dma_command[0] = val; if (val & 0x01) fatal("Memory-to-memory enable\n"); return; @@ -223,11 +541,11 @@ dma_write(uint16_t addr, uint8_t val, void *priv) return; case 0xc: /*Clear FF*/ - dma_wp = 0; + dma_wp[0] = 0; return; case 0xd: /*Master clear*/ - dma_wp = 0; + dma_wp[0] = 0; dma_m |= 0xf; dma_stat_rq_pc &= ~0x0f; return; @@ -413,13 +731,13 @@ dma16_read(uint16_t addr, void *priv) case 2: case 4: case 6: /*Address registers*/ - dma16_wp ^= 1; + dma_wp[1] ^= 1; if (dma_ps2.is_ps2) { - if (dma16_wp) + if (dma_wp[1]) return(dma[channel].ac); return((dma[channel].ac >> 8) & 0xff); } - if (dma16_wp) + if (dma_wp[1]) return((dma[channel].ac >> 1) & 0xff); return((dma[channel].ac >> 9) & 0xff); @@ -427,8 +745,8 @@ dma16_read(uint16_t addr, void *priv) case 3: case 5: case 7: /*Count registers*/ - dma16_wp ^= 1; - if (dma16_wp) + dma_wp[1] ^= 1; + if (dma_wp[1]) temp = dma[channel].cc & 0xff; else temp = dma[channel].cc >> 8; @@ -441,7 +759,7 @@ dma16_read(uint16_t addr, void *priv) return(temp); } - return(dma16regs[addr & 0xf]); + return(dmaregs[1][addr & 0xf]); } @@ -451,20 +769,20 @@ dma16_write(uint16_t addr, uint8_t val, void *priv) int channel = ((addr >> 2) & 3) + 4; addr >>= 1; - dma16regs[addr & 0xf] = val; + dmaregs[1][addr & 0xf] = val; switch (addr & 0xf) { case 0: case 2: case 4: case 6: /*Address registers*/ - dma16_wp ^= 1; + dma_wp[1] ^= 1; if (dma_ps2.is_ps2) { - if (dma16_wp) + if (dma_wp[1]) dma[channel].ab = (dma[channel].ab & 0xffff00) | val; else dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); } else { - if (dma16_wp) + if (dma_wp[1]) dma[channel].ab = (dma[channel].ab & 0xfffe00) | (val << 1); else dma[channel].ab = (dma[channel].ab & 0xfe01ff) | (val << 9); @@ -476,8 +794,8 @@ dma16_write(uint16_t addr, uint8_t val, void *priv) case 3: case 5: case 7: /*Count registers*/ - dma16_wp ^= 1; - if (dma16_wp) + dma_wp[1] ^= 1; + if (dma_wp[1]) dma[channel].cb = (dma[channel].cb & 0xff00) | val; else dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8); @@ -519,11 +837,11 @@ dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 0xc: /*Clear FF*/ - dma16_wp = 0; + dma_wp[1] = 0; return; case 0xd: /*Master clear*/ - dma16_wp = 0; + dma_wp[1] = 0; dma_m |= 0xf0; dma_stat_rq_pc &= ~0xf0; return; @@ -539,59 +857,34 @@ dma16_write(uint16_t addr, uint8_t val, void *priv) } +#define CHANNELS { 8, 2, 3, 1, 8, 8, 8, 0 } + + static void dma_page_write(uint16_t addr, uint8_t val, void *priv) { - dmapages[addr & 0xf] = val; + uint8_t convert[8] = CHANNELS; - switch (addr & 0xf) { - case 1: - dma[2].page = (AT) ? val : val & 0xf; - dma[2].ab = (dma[2].ab & 0xffff) | (dma[2].page << 16); - dma[2].ac = (dma[2].ac & 0xffff) | (dma[2].page << 16); - break; + addr &= 0x0f; + dmaregs[2][addr] = val; - case 2: - dma[3].page = (AT) ? val : val & 0xf; - dma[3].ab = (dma[3].ab & 0xffff) | (dma[3].page << 16); - dma[3].ac = (dma[3].ac & 0xffff) | (dma[3].page << 16); - break; + if (addr >= 8) + addr = convert[addr & 0x07] | 4; + else + addr = convert[addr & 0x07]; - case 3: - dma[1].page = (AT) ? val : val & 0xf; - dma[1].ab = (dma[1].ab & 0xffff) | (dma[1].page << 16); - dma[1].ac = (dma[1].ac & 0xffff) | (dma[1].page << 16); - break; + if (addr < 8) { + dma[addr].page_l = val; - case 7: - dma[0].page = (AT) ? val : val & 0xf; - dma[0].ab = (dma[0].ab & 0xffff) | (dma[0].page << 16); - dma[0].ac = (dma[0].ac & 0xffff) | (dma[0].page << 16); - break; - - case 0x9: - dma[6].page = val & 0xfe; - dma[6].ab = (dma[6].ab & 0x1ffff) | (dma[6].page << 16); - dma[6].ac = (dma[6].ac & 0x1ffff) | (dma[6].page << 16); - break; - - case 0xa: - dma[7].page = val & 0xfe; - dma[7].ab = (dma[7].ab & 0x1ffff) | (dma[7].page << 16); - dma[7].ac = (dma[7].ac & 0x1ffff) | (dma[7].page << 16); - break; - - case 0xb: - dma[5].page = val & 0xfe; - dma[5].ab = (dma[5].ab & 0x1ffff) | (dma[5].page << 16); - dma[5].ac = (dma[5].ac & 0x1ffff) | (dma[5].page << 16); - break; - - case 0xf: - dma[4].page = val & 0xfe; - dma[4].ab = (dma[4].ab & 0x1ffff) | (dma[4].page << 16); - dma[4].ac = (dma[4].ac & 0x1ffff) | (dma[4].page << 16); - break; + if (addr > 4) { + dma[addr].page = val & 0xfe; + dma[addr].ab = (dma[addr].ab & 0x1ffff) | (dma[addr].page << 16); + dma[addr].ac = (dma[addr].ac & 0x1ffff) | (dma[addr].page << 16); + } else { + dma[addr].page = (AT) ? val : val & 0xf; + dma[addr].ab = (dma[addr].ab & 0xffff) | (dma[addr].page << 16); + dma[addr].ac = (dma[addr].ac & 0xffff) | (dma[addr].page << 16); + } } } @@ -599,7 +892,70 @@ dma_page_write(uint16_t addr, uint8_t val, void *priv) static uint8_t dma_page_read(uint16_t addr, void *priv) { - return(dmapages[addr & 0xf]); + uint8_t convert[8] = CHANNELS; + uint8_t ret = 0xff; + + addr &= 0x0f; + ret = dmaregs[2][addr]; + + if (addr >= 8) + addr = convert[addr & 0x07] | 4; + else + addr = convert[addr & 0x07]; + + if (addr < 8) + ret = dma[addr].page_l; + + return ret; +} + + +static void +dma_high_page_write(uint16_t addr, uint8_t val, void *priv) +{ + uint8_t convert[8] = CHANNELS; + + addr &= 0x0f; + + if (addr >= 8) + addr = convert[addr & 0x07] | 4; + else + addr = convert[addr & 0x07]; + + if (addr < 8) { + dma[addr].page_h = val; + + dma[addr].ab = ((dma[addr].ab & 0xffffff) | (dma[addr].page << 24)) & dma_mask; + dma[addr].ac = ((dma[addr].ac & 0xffffff) | (dma[addr].page << 24)) & dma_mask; + } +} + + +static uint8_t +dma_high_page_read(uint16_t addr, void *priv) +{ + uint8_t convert[8] = CHANNELS; + uint8_t ret = 0xff; + + addr &= 0x0f; + + if (addr >= 8) + addr = convert[addr & 0x07] | 4; + else + addr = convert[addr & 0x07]; + + if (addr < 8) + ret = dma[addr].page_h; + + return ret; +} + + +void +dma_set_params(uint8_t advanced, uint32_t mask) +{ + dma_advanced = advanced; + dma_mask = mask; } @@ -608,29 +964,107 @@ dma_reset(void) { int c; - dma_wp = dma16_wp = 0; + dma_wp[0] = dma_wp[1] = 0; dma_m = 0; dma_e = 0xff; for (c = 0; c < 16; c++) - dmaregs[c] = dma16regs[c] = 0; + dmaregs[0][c] = dmaregs[1][c] = 0; + for (c = 0; c < 8; c++) { - dma[c].mode = 0; - dma[c].ac = 0; - dma[c].cc = 0; - dma[c].ab = 0; - dma[c].cb = 0; + memset(&(dma[c]), 0x00, sizeof(dma_t)); dma[c].size = (c & 4) ? 1 : 0; + dma[c].transfer_mode = (c & 4) ? 0x0202 : 0x0101; } dma_stat = 0x00; dma_stat_rq = 0x00; dma_stat_rq_pc = 0x00; dma_req_is_soft = 0; + dma_advanced = 0; memset(dma_buffer, 0x00, sizeof(dma_buffer)); memset(dma16_buffer, 0x00, sizeof(dma16_buffer)); + + dma_remove_sg(); + dma_sg_base = 0x0400; + + dma_mask = 0x00ffffff; +} + + +void +dma_remove_sg(void) +{ + int i; + + io_removehandler(dma_sg_base + 0x0a, 0x01, + dma_sg_int_status_read, NULL, NULL, + NULL, NULL, NULL, + NULL); + + for (i = 0; i < 8; i++) { + io_removehandler(dma_sg_base + 0x10 + i, 0x01, + dma_sg_read, dma_sg_readw, dma_sg_readl, + dma_sg_write, dma_sg_writew, dma_sg_writel, + &dma[i]); + io_removehandler(dma_sg_base + 0x18 + i, 0x01, + dma_sg_read, dma_sg_readw, dma_sg_readl, + dma_sg_write, dma_sg_writew, dma_sg_writel, + &dma[i]); + io_removehandler(dma_sg_base + 0x20 + i, 0x04, + dma_sg_read, dma_sg_readw, dma_sg_readl, + dma_sg_write, dma_sg_writew, dma_sg_writel, + &dma[i]); + } +} + + +void +dma_set_sg_base(uint8_t sg_base) +{ + int i; + + dma_sg_base = sg_base << 8; + + io_sethandler(dma_sg_base + 0x0a, 0x01, + dma_sg_int_status_read, NULL, NULL, + NULL, NULL, NULL, + NULL); + + for (i = 0; i < 8; i++) { + io_sethandler(dma_sg_base + 0x10 + i, 0x01, + dma_sg_read, dma_sg_readw, dma_sg_readl, + dma_sg_write, dma_sg_writew, dma_sg_writel, + &dma[i]); + io_sethandler(dma_sg_base + 0x18 + i, 0x01, + dma_sg_read, dma_sg_readw, dma_sg_readl, + dma_sg_write, dma_sg_writew, dma_sg_writel, + &dma[i]); + io_sethandler(dma_sg_base + 0x20 + i, 0x04, + dma_sg_read, dma_sg_readw, dma_sg_readl, + dma_sg_write, dma_sg_writew, dma_sg_writel, + &dma[i]); + } +} + + +void +dma_ext_mode_init(void) +{ + io_sethandler(0x040b, 0x01, + NULL,NULL,NULL, dma_ext_mode_write,NULL,NULL, NULL); + io_sethandler(0x04d6, 0x01, + NULL,NULL,NULL, dma_ext_mode_write,NULL,NULL, NULL); +} + + +void +dma_high_page_init(void) +{ + io_sethandler(0x0480, 8, + dma_high_page_read,NULL,NULL, dma_high_page_write,NULL,NULL, NULL); } @@ -720,20 +1154,170 @@ ps2_dma_init(void) } -uint8_t -_dma_read(uint32_t addr) +extern void dma_bm_read(uint32_t PhysAddress, uint8_t *DataRead, uint32_t TotalSize, int TransferSize); +extern void dma_bm_write(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize, int TransferSize); + + +static int +dma_sg(uint8_t *data, int transfer_length, int out, void *priv) { - uint8_t temp = mem_readb_phys(addr); + dma_t *dev = (dma_t *) priv; +#ifdef ENABLE_DMA_LOG + char *sop; +#endif + + int force_end = 0, buffer_pos = 0; + +#ifdef ENABLE_DMA_LOG + sop = out ? "Read" : "Writ"; +#endif + + if (!(dev->sg_status & 1)) + return 2; /*S/G disabled*/ + + dma_log("DMA S/G %s: %i bytes\n", out ? "write" : "read", transfer_length); + + while (1) { + if (dev->count <= transfer_length) { + dma_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr); + if (out) + dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4); + else + dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4); + transfer_length -= dev->count; + buffer_pos += dev->count; + } else { + dma_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr); + if (out) + dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4); + else + dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4); + /* Increase addr and decrease count so that resumed transfers do not mess up. */ + dev->addr += transfer_length; + dev->count -= transfer_length; + transfer_length = 0; + force_end = 1; + } + + if (force_end) { + dma_log("Total transfer length smaller than sum of all blocks, partial block\n"); + return 1; /* This block has exhausted the data to transfer and it was smaller than the count, break. */ + } else { + if (!transfer_length && !dev->eot) { + dma_log("Total transfer length smaller than sum of all blocks, full block\n"); + return 1; /* We have exhausted the data to transfer but there's more blocks left, break. */ + } else if (transfer_length && dev->eot) { + dma_log("Total transfer length greater than sum of all blocks\n"); + return 4; /* There is data left to transfer but we have reached EOT - return with error. */ + } else if (dev->eot) { + dma_log("Regular EOT\n"); + return 5; /* We have regularly reached EOT - clear status and break. */ + } else { + /* We have more to transfer and there are blocks left, get next block. */ + dma_sg_next_addr(dev); + } + } + } + + return 1; +} + + +uint8_t +_dma_read(uint32_t addr, dma_t *dma_c) +{ + uint8_t temp; + + if (dma_advanced) { + if (dma_c->sg_status & 1) + dma_c->sg_status = (dma_c->sg_status & 0x0f) | (dma_sg(&temp, 1, 1, dma_c) << 4); + else + dma_bm_read(addr, &temp, 1, dma_transfer_size(dma_c)); + } else + temp = mem_readb_phys(addr); return(temp); } -void -_dma_write(uint32_t addr, uint8_t val) +static uint16_t +_dma_readw(uint32_t addr, dma_t *dma_c) { - mem_writeb_phys(addr, val); - mem_invalidate_range(addr, addr); + uint16_t temp; + + if (dma_advanced) { + if (dma_c->sg_status & 1) + dma_c->sg_status = (dma_c->sg_status & 0x0f) | (dma_sg((uint8_t *) &temp, 2, 1, dma_c) << 4); + else + dma_bm_read(addr, (uint8_t *) &temp, 2, dma_transfer_size(dma_c)); + } else + temp = _dma_read(addr, dma_c) | (_dma_read(addr + 1, dma_c) << 8); + + return(temp); +} + + +static void +_dma_write(uint32_t addr, uint8_t val, dma_t *dma_c) +{ + if (dma_advanced) { + if (dma_c->sg_status & 1) + dma_c->sg_status = (dma_c->sg_status & 0x0f) | (dma_sg(&val, 1, 0, dma_c) << 4); + else + dma_bm_write(addr, &val, 1, dma_transfer_size(dma_c)); + } else { + mem_writeb_phys(addr, val); + mem_invalidate_range(addr, addr); + } +} + + +static void +_dma_writew(uint32_t addr, uint16_t val, dma_t *dma_c) +{ + if (dma_advanced) { + if (dma_c->sg_status & 1) + dma_c->sg_status = (dma_c->sg_status & 0x0f) | (dma_sg((uint8_t *) &val, 2, 0, dma_c) << 4); + else + dma_bm_write(addr, (uint8_t *) &val, 2, dma_transfer_size(dma_c)); + } else { + _dma_write(addr, val & 0xff, dma_c); + _dma_write(addr + 1, val >> 8, dma_c); + } +} + + +static void +dma_retreat(dma_t *dma_c) +{ + int as = dma_c->transfer_mode >> 8; + + if (dma->sg_status & 1) { + dma_c->ac = (dma_c->ac - as) & dma_mask; + + dma_c->page = dma_c->page_l = (dma_c->ac >> 16) & 0xff; + dma_c->page_h = (dma_c->ac >> 24) & 0xff; + } else if (as == 2) + dma_c->ac = ((dma_c->ac & 0xfffe0000) & dma_mask) | ((dma_c->ac - as) & 0xffff); + else + dma_c->ac = ((dma_c->ac & 0xffff0000) & dma_mask) | ((dma_c->ac - as) & 0xffff); +} + + +void +dma_advance(dma_t *dma_c) +{ + int as = dma_c->transfer_mode >> 8; + + if (dma->sg_status & 1) { + dma_c->ac = (dma_c->ac + as) & dma_mask; + + dma_c->page = dma_c->page_l = (dma_c->ac >> 16) & 0xff; + dma_c->page_h = (dma_c->ac >> 24) & 0xff; + } else if (as == 2) + dma_c->ac = ((dma_c->ac & 0xfffe0000) & dma_mask) | ((dma_c->ac + as) & 0xffff); + else + dma_c->ac = ((dma_c->ac & 0xffff0000) & dma_mask) | ((dma_c->ac + as) & 0xffff); } @@ -745,10 +1329,10 @@ dma_channel_read(int channel) int tc = 0; if (channel < 4) { - if (dma_command & 0x04) + if (dma_command[0] & 0x04) return(DMA_NODATA); } else { - if (dma16_command & 0x04) + if (dma_command[1] & 0x04) return(DMA_NODATA); } @@ -763,31 +1347,39 @@ dma_channel_read(int channel) refreshread(); if (! dma_c->size) { - temp = _dma_read(dma_c->ac); + temp = _dma_read(dma_c->ac, dma_c); if (dma_c->mode & 0x20) { if (dma_ps2.is_ps2) dma_c->ac--; - else + else if (dma_advanced) + dma_retreat(dma_c); + else dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); } else { if (dma_ps2.is_ps2) dma_c->ac++; - else + else if (dma_advanced) + dma_advance(dma_c); + else dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); } } else { - temp = _dma_read(dma_c->ac) | (_dma_read(dma_c->ac + 1) << 8); + temp = _dma_readw(dma_c->ac, dma_c); if (dma_c->mode & 0x20) { if (dma_ps2.is_ps2) dma_c->ac -= 2; - else + else if (dma_advanced) + dma_retreat(dma_c); + else dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); } else { if (dma_ps2.is_ps2) dma_c->ac += 2; - else + else if (dma_advanced) + dma_advance(dma_c); + else dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); } } @@ -796,17 +1388,27 @@ dma_channel_read(int channel) dma_c->cc--; if (dma_c->cc < 0) { - tc = 1; - if (dma_c->mode & 0x10) { /*Auto-init*/ - dma_c->cc = dma_c->cb; - dma_c->ac = dma_c->ab; - } else - dma_m |= (1 << channel); - dma_stat |= (1 << channel); + if (dma_advanced && (dma_c->sg_status & 1) && !(dma_c->sg_status & 6)) + dma_sg_next_addr(dma_c); + else { + tc = 1; + if (dma_c->mode & 0x10) { /*Auto-init*/ + dma_c->cc = dma_c->cb; + dma_c->ac = dma_c->ab; + } else + dma_m |= (1 << channel); + dma_stat |= (1 << channel); + } } - if (tc) + if (tc) { + if (dma_advanced && (dma_c->sg_status & 1) && ((dma_c->sg_command & 0xc0) == 0x40)) { + picint(1 << 13); + dma_c->sg_status |= 8; + } + return(temp | DMA_OVER); + } return(temp); } @@ -818,10 +1420,10 @@ dma_channel_write(int channel, uint16_t val) dma_t *dma_c = &dma[channel]; if (channel < 4) { - if (dma_command & 0x04) + if (dma_command[0] & 0x04) return(DMA_NODATA); } else { - if (dma16_command & 0x04) + if (dma_command[1] & 0x04) return(DMA_NODATA); } @@ -833,33 +1435,40 @@ dma_channel_write(int channel, uint16_t val) return(DMA_NODATA); if (! dma_c->size) { - _dma_write(dma_c->ac, val & 0xff); + _dma_write(dma_c->ac, val & 0xff, dma_c); if (dma_c->mode & 0x20) { if (dma_ps2.is_ps2) dma_c->ac--; - else + else if (dma_advanced) + dma_retreat(dma_c); + else dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); } else { if (dma_ps2.is_ps2) dma_c->ac++; - else + else if (dma_advanced) + dma_advance(dma_c); + else dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); } } else { - _dma_write(dma_c->ac, val & 0xff); - _dma_write(dma_c->ac + 1, val >> 8); + _dma_writew(dma_c->ac, val, dma_c); if (dma_c->mode & 0x20) { if (dma_ps2.is_ps2) dma_c->ac -= 2; - else + else if (dma_advanced) + dma_retreat(dma_c); + else dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); } else { if (dma_ps2.is_ps2) dma_c->ac += 2; - else + else if (dma_advanced) + dma_advance(dma_c); + else dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); } } @@ -868,16 +1477,26 @@ dma_channel_write(int channel, uint16_t val) dma_c->cc--; if (dma_c->cc < 0) { - if (dma_c->mode & 0x10) { /*Auto-init*/ - dma_c->cc = dma_c->cb; - dma_c->ac = dma_c->ab; - } else - dma_m |= (1 << channel); - dma_stat |= (1 << channel); + if (dma_advanced && (dma_c->sg_status & 1) && !(dma_c->sg_status & 6)) + dma_sg_next_addr(dma_c); + else { + if (dma_c->mode & 0x10) { /*Auto-init*/ + dma_c->cc = dma_c->cb; + dma_c->ac = dma_c->ab; + } else + dma_m |= (1 << channel); + dma_stat |= (1 << channel); + } } - if (dma_m & (1 << channel)) + if (dma_m & (1 << channel)) { + if (dma_advanced && (dma_c->sg_status & 1) && ((dma_c->sg_command & 0xc0) == 0x40)) { + picint(1 << 13); + dma_c->sg_status |= 8; + } + return(DMA_OVER); + } return(0); } @@ -892,7 +1511,7 @@ dma_ps2_run(int channel) case DMA_PS2_XFER_MEM_TO_IO: do { if (! dma_c->size) { - uint8_t temp = _dma_read(dma_c->ac); + uint8_t temp = _dma_read(dma_c->ac, dma_c); outb(dma_c->io_addr, temp); @@ -901,7 +1520,7 @@ dma_ps2_run(int channel) else dma_c->ac++; } else { - uint16_t temp = _dma_read(dma_c->ac) | (_dma_read(dma_c->ac + 1) << 8); + uint16_t temp = _dma_readw(dma_c->ac, dma_c); outw(dma_c->io_addr, temp); @@ -923,7 +1542,7 @@ dma_ps2_run(int channel) if (! dma_c->size) { uint8_t temp = inb(dma_c->io_addr); - _dma_write(dma_c->ac, temp); + _dma_write(dma_c->ac, temp, dma_c); if (dma_c->ps2_mode & DMA_PS2_DEC2) dma_c->ac--; @@ -932,8 +1551,7 @@ dma_ps2_run(int channel) } else { uint16_t temp = inw(dma_c->io_addr); - _dma_write(dma_c->ac, temp & 0xff); - _dma_write(dma_c->ac + 1, temp >> 8); + _dma_writew(dma_c->ac, temp, dma_c); if (dma_c->ps2_mode & DMA_PS2_DEC2) dma_c->ac -= 2; diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 66e665f76..44bea7b25 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -35,6 +35,7 @@ #include <86box/ui.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> extern uint64_t motoron[FDD_NUM]; @@ -89,6 +90,9 @@ int lastbyte=0; int floppymodified[4]; int floppyrate[4]; + +int fdc_type = 0; + #ifdef ENABLE_FDC_LOG int fdc_do_log = ENABLE_FDC_LOG; @@ -110,6 +114,85 @@ fdc_log(const char *fmt, ...) #endif +typedef const struct { + const char *name; + const char *internal_name; + const device_t *device; +} fdc_cards_t; + +/* All emulated machines have at least one integrated FDC controller */ +static fdc_cards_t fdc_cards[] = { + { "Internal controller", "internal", NULL, }, + { "DTK PII-151B", "dtk_pii151b", &fdc_pii151b_device, }, + { "DTK PII-158B", "dtk_pii158b", &fdc_pii158b_device, }, + { "", "", NULL, }, +}; + +int +fdc_card_available(int card) +{ + if (fdc_cards[card].device) + return(device_available(fdc_cards[card].device)); + + return(1); +} + + +char * +fdc_card_getname(int card) +{ + return((char *) fdc_cards[card].name); +} + + +const device_t * +fdc_card_getdevice(int card) +{ + return(fdc_cards[card].device); +} + + +int +fdc_card_has_config(int card) +{ + if (! fdc_cards[card].device) return(0); + + return(fdc_cards[card].device->config ? 1 : 0); +} + + +char * +fdc_card_get_internal_name(int card) +{ + return((char *) fdc_cards[card].internal_name); +} + + +int +fdc_card_get_from_internal_name(char *s) +{ + int c = 0; + + while (strlen((char *) fdc_cards[c].internal_name)) { + if (!strcmp((char *) fdc_cards[c].internal_name, s)) + return(c); + c++; + } + + return(0); +} + + +void +fdc_card_init(void) +{ + if (!fdc_cards[fdc_type].device) + return; + + device_add(fdc_cards[fdc_type].device); +} + + uint8_t fdc_get_current_drive(void) { @@ -475,7 +558,7 @@ fdc_update_rate(fdc_t *fdc, int drive) break; } - fdc->bitcell_period = 1000000 / fdc->bit_rate * 2; /*Bitcell period in ns*/ + fdc->bitcell_period = (1000000 / fdc->bit_rate) * 2; /*Bitcell period in ns*/ } @@ -1037,8 +1120,11 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) if (fdc->flags & FDC_FLAG_PCJR) { fdc->fintr = 1; fdc->interrupt = -4; - } else + } else { + timer_disable(&fdc->timer); fdc->interrupt = -3; + fdc_callback(fdc); + } break; } if ((real_drive(fdc, fdc->drive) != 1) || fdc->drv2en) @@ -1087,7 +1173,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) /* Three conditions under which the command should fail. */ if (!fdd_get_flags(drive_num) || (drive_num >= FDD_NUM) || !motoron[drive_num]) { /* Yes, failed SEEK's still report success, unlike failed RECALIBRATE's. */ - fdc->st0 = 0x20 | (fdc->params[0] & 7); + fdc->st0 = 0x20 | (fdc->params[0] & 3); if (fdc->command & 0x80) { if (fdc->command & 0x40) fdc->pcn[fdc->params[0] & 3] += fdc->params[1]; @@ -1095,7 +1181,14 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pcn[fdc->params[0] & 3] -= fdc->params[1]; } else fdc->pcn[fdc->params[0] & 3] = fdc->params[1]; - fdc->interrupt = -3; + if (fdc->flags & FDC_FLAG_PCJR) { + fdc->fintr = 1; + fdc->interrupt = -4; + } else { + timer_disable(&fdc->timer); + fdc->interrupt = -3; + fdc_callback(fdc); + } break; } if (fdc->command & 0x80) { @@ -1113,16 +1206,30 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } fdc->step = 1; } else { - fdc->st0 = 0x20 | (fdc->params[0] & 7); - fdc->interrupt = -3; + fdc->st0 = 0x20 | (fdc->params[0] & 3); + if (fdc->flags & FDC_FLAG_PCJR) { + fdc->fintr = 1; + fdc->interrupt = -4; + } else { + timer_disable(&fdc->timer); + fdc->interrupt = -3; + fdc_callback(fdc); + } break; } } else { fdc_log("Seeking to track %i (PCN = %i)...\n", fdc->params[1], fdc->pcn[fdc->params[0] & 3]); if ((fdc->params[1] - fdc->pcn[fdc->params[0] & 3]) == 0) { fdc_log("Failed seek\n"); - fdc->st0 = 0x20 | (fdc->params[0] & 7); - fdc->interrupt = -3; + fdc->st0 = 0x20 | (fdc->params[0] & 3); + if (fdc->flags & FDC_FLAG_PCJR) { + fdc->fintr = 1; + fdc->interrupt = -4; + } else { + timer_disable(&fdc->timer); + fdc->interrupt = -3; + fdc_callback(fdc); + } break; } if (fdc->params[1] > fdc->pcn[fdc->params[0] & 3]) @@ -1632,7 +1739,7 @@ fdc_callback(void *priv) fdc->interrupt = 0; return; case 0x0f: /*Seek*/ - fdc->st0 = 0x20 | (fdc->params[0] & 7); + fdc->st0 = 0x20 | (fdc->params[0] & 3); fdc->stat = 0x80 | (1 << fdc->rw_drive); if (fdc->flags & FDC_FLAG_PCJR) { fdc->fintr = 1; @@ -2138,7 +2245,6 @@ fdc_init(const device_t *info) memset(fdc, 0, sizeof(fdc_t)); fdc->flags = info->local; - fdc_reset(fdc); fdc->irq = 6; @@ -2271,3 +2377,13 @@ const device_t fdc_at_nsc_device = { fdc_reset, NULL, NULL, NULL }; + +const device_t fdc_dp8473_device = { + "NS DP8473 Floppy Drive Controller", + 0, + FDC_FLAG_NSDP, + fdc_init, + fdc_close, + fdc_reset, + NULL, NULL, NULL +}; diff --git a/src/floppy/fdc_pii15xb.c b/src/floppy/fdc_pii15xb.c new file mode 100644 index 000000000..55dd55460 --- /dev/null +++ b/src/floppy/fdc_pii15xb.c @@ -0,0 +1,208 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Implementation of the DTK PII-151B and PII-158B cards. + * + * These are DP8473-based floppy controller ISA cards for XT + * class systems, and allow usage of standard and high-density + * drives on them. They have their own BIOS which takes over + * from the standard system BIOS. + * + * Author: Fred N. van Kempen, + * + * Copyright 2019 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 + * HOLDER 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. + */ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/pic.h> +#include <86box/rom.h> +#include <86box/machine.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/ui.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> + +#define ROM_PII_151B L"roms/floppy/dtk/pii-151b.rom" +#define ROM_PII_158B L"roms/floppy/dtk/pii-158b.rom" + +typedef struct { + const char *name; + int type; + + uint32_t bios_addr, + bios_size; + rom_t bios_rom; + + fdc_t *fdc; +} pii_t; + + +/* Load and enable a BIOS ROM if we have one, and is enabled. */ +static void +set_bios(pii_t *dev, wchar_t *fn) +{ + uint32_t temp; + FILE *fp; + + /* Only do this if needed. */ + if ((fn == NULL) || (dev->bios_addr == 0)) return; + + if ((fp = rom_fopen(fn, L"rb")) == NULL) return; + + (void)fseek(fp, 0L, SEEK_END); + temp = ftell(fp); + (void)fclose(fp); + + /* Assume 128K, then go down. */ + dev->bios_size = 0x020000; + while (temp < dev->bios_size) + dev->bios_size >>= 1; + + /* Create a memory mapping for the space. */ + rom_init(&dev->bios_rom, fn, dev->bios_addr, + dev->bios_size, dev->bios_size-1, 0, MEM_MAPPING_EXTERNAL); +} + + +static void +pii_close(void *priv) +{ + pii_t *dev = (pii_t *)priv; + + free(dev); +} + + +static void * +pii_init(const device_t *info) +{ + pii_t *dev; + + dev = (pii_t *)malloc(sizeof(pii_t)); + memset(dev, 0x00, sizeof(pii_t)); + dev->type = info->local; + + dev->bios_addr = device_get_config_hex20("bios_addr"); + + if (dev->bios_addr != 0x000000) { + switch (dev->type) { + case 151: + set_bios(dev, ROM_PII_151B); + break; + case 158: + set_bios(dev, ROM_PII_158B); + break; + } + } + + /* Attach the DP8473 chip. */ + dev->fdc = device_add(&fdc_at_device); + + //pclog("FDC: %s (I/O=%04X, flags=%08x)\n", + // info->name, dev->fdc->base_address, dev->fdc->flags); + + return(dev); +} + +static int pii_151b_available(void) +{ + return rom_present(ROM_PII_151B); +} + +static int pii_158_available(void) +{ + return rom_present(ROM_PII_158B); +} + +static const device_config_t pii_config[] = { + { + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0x0ce000, + { + { + "Disabled", 0 + }, + { + "CA00H", 0x0ca000 + }, + { + "CC00H", 0x0cc000 + }, + { + "CE00H", 0x0ce000 + }, + { + "" + } + } + }, + { + "", "", -1 + } +}; + +const device_t fdc_pii151b_device = { + "DTK PII-151B (MiniMicro) Floppy Drive Controller", + DEVICE_ISA, + 151, + pii_init, pii_close, NULL, + pii_151b_available, NULL, NULL, + pii_config +}; + +const device_t fdc_pii158b_device = { + "DTK PII-158B (MiniMicro4) Floppy Drive Controller", + DEVICE_ISA, + 158, + pii_init, pii_close, NULL, + pii_158_available, NULL, NULL, + pii_config +}; diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index d3fbd2a06..ddcc515f0 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -3811,7 +3811,7 @@ d86f_load(int drive, wchar_t *fn) if (dev->extra_bit_cells[1] > 32768) dev->extra_bit_cells[1] = 32768; } } else { - dev->extra_bit_cells[0] = 0; + dev->extra_bit_cells[1] = 0; } } else { switch ((dev->disk_flags >> 1) >> 3) { diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index b29f17c6e..bbb37895e 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -42,6 +42,10 @@ #endif #define COPYRIGHT_YEAR "2020" +/* Web URL info. */ +#define EMU_SITE L"86box.github.io" +#define EMU_ROMS_URL L"https://github.com/86Box/roms/releases/latest" + /* Filename and pathname info. */ #define CONFIG_FILE L"86box.cfg" #define NVR_PATH L"nvr" @@ -116,7 +120,7 @@ extern uint32_t mem_size; /* (C) memory size */ extern int cpu_manufacturer, /* (C) cpu manufacturer */ cpu, /* (C) cpu type */ cpu_use_dynarec, /* (C) cpu uses/needs Dyna */ - enable_external_fpu; /* (C) enable external FPU */ + fpu_type; /* (C) fpu type */ extern int time_sync; /* (C) enable time sync */ extern int network_type; /* (C) net provider type */ extern int network_card; /* (C) net interface num */ diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index ce78f0ec5..a94564e68 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -32,21 +32,35 @@ extern const device_t headland_device; extern const device_t headland_386_device; /* Intel 4x0xX */ +extern const device_t i420ex_device; extern const device_t i420tx_device; extern const device_t i420zx_device; extern const device_t i430lx_device; extern const device_t i430nx_device; extern const device_t i430fx_device; -extern const device_t i430fx_pb640_device; +extern const device_t i430fx_rev02_device; extern const device_t i430hx_device; extern const device_t i430vx_device; extern const device_t i430tx_device; extern const device_t i440fx_device; -extern const device_t i440lx_device; -extern const device_t i440ex_device; +extern const device_t i440lx_device; +extern const device_t i440ex_device; extern const device_t i440bx_device; +extern const device_t i440gx_device; extern const device_t i440zx_device; +extern const device_t sio_device; +extern const device_t sio_zb_device; + +extern const device_t piix_device; +extern const device_t piix_rev02_device; +extern const device_t piix3_device; +extern const device_t piix4_device; +extern const device_t piix4e_device; +extern const device_t slc90e66_device; + +extern const device_t ioapic_device; + /* OPTi */ extern const device_t opti495_device; extern const device_t opti5x7_device; @@ -68,9 +82,12 @@ extern const device_t sis_85c50x_device; /* VIA */ extern const device_t via_vpx_device; -extern const device_t via_vp3_device; -extern const device_t via_mvp3_device; -extern const device_t via_apro_device; +extern const device_t via_vp3_device; +extern const device_t via_mvp3_device; +extern const device_t via_apro_device; + +extern const device_t via_vt82c586b_device; +extern const device_t via_vt82c596b_device; /* VLSI */ extern const device_t vlsi_scamp_device; diff --git a/src/include/86box/config.h b/src/include/86box/config.h index 969bc2489..1a82a0879 100644 --- a/src/include/86box/config.h +++ b/src/include/86box/config.h @@ -117,7 +117,8 @@ typedef struct { parallel_enabled[3]; /* LPT1, LPT2, LPT3 enabled */ /* Other peripherals category */ - int hdc, /* Hard disk controller */ + int fdc_type, /* Floppy disk controller type */ + hdc, /* Hard disk controller */ scsi_card, /* SCSI controller */ ide_ter_enabled, /* Tertiary IDE controller enabled */ ide_qua_enabled, /* Quaternary IDE controller enabled */ diff --git a/src/include/86box/dma.h b/src/include/86box/dma.h index 5a2fbe701..d5ee9fcb3 100644 --- a/src/include/86box/dma.h +++ b/src/include/86box/dma.h @@ -46,19 +46,21 @@ typedef struct { - uint32_t ab, ac; - uint16_t cb; - int cc; - int wp; - uint8_t m, mode; - uint8_t page; - uint8_t stat, stat_rq; - uint8_t command; - int size; - - uint8_t ps2_mode; - uint8_t arb_level; - uint16_t io_addr; + uint8_t m, mode, page, stat, + stat_rq, command, + ps2_mode, arb_level, + sg_command, sg_status, + ptr0, enabled, + ext_mode, page_l, + page_h, pad; + uint16_t cb, io_addr, + base, transfer_mode; + uint32_t ptr, ptr_cur, + addr, + ab, ac; + int cc, wp, + size, count, + eot; } dma_t; @@ -93,5 +95,13 @@ extern void dma_alias_remove_piix(void); extern void dma_bm_read(uint32_t PhysAddress, uint8_t *DataRead, uint32_t TotalSize, int TransferSize); extern void dma_bm_write(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize, int TransferSize); +void dma_set_params(uint8_t advanced, uint32_t mask); +void dma_ext_mode_init(void); + +void dma_high_page_init(void); + +void dma_remove_sg(void); +void dma_set_sg_base(uint8_t sg_base); + #endif /*EMU_DMA_H*/ diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index cae83896a..56249069b 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -22,6 +22,7 @@ #ifndef EMU_FDC_H # define EMU_FDC_H +extern int fdc_type; #define FDC_FLAG_PCJR 0x01 /* PCjr */ #define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ @@ -33,6 +34,7 @@ #define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ #define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ #define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ +#define FDC_FLAG_NSDP 0x400 /* DP8473N, DP8473V */ typedef struct { @@ -178,7 +180,7 @@ extern const device_t fdc_at_ps1_device; extern const device_t fdc_at_smc_device; extern const device_t fdc_at_winbond_device; extern const device_t fdc_at_nsc_device; +extern const device_t fdc_dp8473_device; #endif - #endif /*EMU_FDC_H*/ diff --git a/src/include/86box/fdc_ext.h b/src/include/86box/fdc_ext.h new file mode 100644 index 000000000..1e10e4b7a --- /dev/null +++ b/src/include/86box/fdc_ext.h @@ -0,0 +1,42 @@ +/* + * 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 the NEC uPD-765 and compatible floppy disk + * controller. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2018-2020 Fred N. van Kempen. + */ +#ifndef EMU_FDC_EXT_H +# define EMU_FDC_EXT_H + +extern int fdc_type; + +/* Controller types. */ +#define FDC_INTERNAL 0 + +extern const device_t fdc_pii151b_device; +extern const device_t fdc_pii158b_device; + +extern void fdc_card_init(void); + +extern char *fdc_card_getname(int card); +extern char *fdc_card_get_internal_name(int card); +extern int fdc_card_get_from_internal_name(char *s); +extern const device_t *fdc_card_getdevice(int card); +extern int fdc_card_has_config(int card); +extern int fdc_card_available(int card); + +#endif /*EMU_FDC_H*/ diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index b96379d1a..48b7c8939 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -29,7 +29,8 @@ enum #ifdef SCSI_DEVICE_H typedef struct ide_s { - uint8_t atastat, error, + uint8_t selected, + atastat, error, command, fdisk; int type, board, irqstat, service, @@ -49,6 +50,8 @@ typedef struct ide_s { uint16_t *buffer; uint8_t *sector_buffer; + pc_timer_t timer; + /* Stuff mostly used by ATAPI */ scsi_common_t *sc; int interrupt_drq; @@ -63,6 +66,8 @@ typedef struct ide_s { void (*command_stop)(scsi_common_t *sc); void (*bus_master_error)(scsi_common_t *sc); } ide_t; + +extern ide_t *ide_drives[IDE_NUM]; #endif /* Type: @@ -133,7 +138,10 @@ extern void ide_sec_disable(void); extern void ide_board_set_force_ata3(int board, int force_ata3); extern double ide_atapi_get_period(uint8_t channel); -extern void ide_set_callback(uint8_t channel, double callback); +#ifdef SCSI_DEVICE_H +extern void ide_set_callback(ide_t *ide, double callback); +#endif +extern void ide_set_board_callback(uint8_t board, double callback); extern void ide_padstr(char *str, const char *src, int len); extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src); diff --git a/src/include/86box/intel_sio.h b/src/include/86box/intel_sio.h deleted file mode 100644 index 924de555c..000000000 --- a/src/include/86box/intel_sio.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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. - * - * Emulation of Intel System I/O PCI chip. - * - * - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -extern const device_t sio_device; -extern const device_t sio_zb_device; diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index d90fff256..e09ca2844 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -82,6 +82,7 @@ extern const device_t keyboard_ps2_quadtel_device; extern const device_t keyboard_ps2_pci_device; extern const device_t keyboard_ps2_ami_pci_device; extern const device_t keyboard_ps2_intel_ami_pci_device; +extern const device_t keyboard_ps2_acer_pci_device; #endif extern void keyboard_init(void); diff --git a/src/include/86box/language.h b/src/include/86box/language.h index b95f692f7..0e603e92f 100644 --- a/src/include/86box/language.h +++ b/src/include/86box/language.h @@ -22,10 +22,10 @@ /* String IDs. */ #define IDS_STRINGS 2048 // "86Box" -#define IDS_2049 2049 // "86Box Error" -#define IDS_2050 2050 // "86Box Fatal Error" -#define IDS_2051 2051 // "This will hard reset the.." -#define IDS_2052 2052 // "Use CTRL+ALT+PAGE DOWN.." +#define IDS_2049 2049 // "Error" +#define IDS_2050 2050 // "Fatal error" +#define IDS_2051 2051 // "Are you sure you want to save..." +#define IDS_2052 2052 // "Press CTRL+ALT+PAGE DOWN..." #define IDS_2053 2053 // "Speed" #define IDS_2054 2054 // "ZIP %i (%03i): %ls" #define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..." @@ -36,8 +36,8 @@ #define IDS_2060 2060 // "On" #define IDS_2061 2061 // "Off" #define IDS_2062 2062 // "All floppy images (*.DSK..." -#define IDS_2063 2063 // "Configured ROM set not avai.." -#define IDS_2064 2064 // "Configured video BIOS not.." +#define IDS_2063 2063 // "Machine ""%S"" is not..." +#define IDS_2064 2064 // "Video card ""%S"" is not..." #define IDS_2065 2065 // "Machine" #define IDS_2066 2066 // "Display" #define IDS_2067 2067 // "Input devices" @@ -62,7 +62,7 @@ #define IDS_2086 2086 // "MB" #define IDS_2087 2087 // "Check BPB" #define IDS_2088 2088 // "KB" -#define IDS_2089 2089 // "Neither DirectDraw nor Dire.." +#define IDS_2089 2089 // "Could not initialize the video..." #define IDS_2090 2090 // "Default" #define IDS_2091 2091 // "%i Wait state(s)" #define IDS_2092 2092 // "Type" @@ -77,8 +77,8 @@ #define IDS_2101 2101 // "Microsoft SideWinder Pad" #define IDS_2102 2102 // "Thrustmaster Flight Cont.." #define IDS_2103 2103 // "None" -#define IDS_2104 2104 // "Unable to load Accelerators" -#define IDS_2105 2105 // "Unable to register Raw Input" +#define IDS_2104 2104 // "Unable to load keyboard..." +#define IDS_2105 2105 // "Unable to register raw input." #define IDS_2106 2106 // "%u" #define IDS_2107 2107 // "%u MB (CHS: %i, %i, %i)" #define IDS_2108 2108 // "Floppy %i (%s): %ls" @@ -91,6 +91,27 @@ #define IDS_2115 2115 // "MO %i (%03i): %ls" #define IDS_2116 2116 // "MO images (*.IM?)\0*.IM..." #define IDS_2117 2117 // "Welcome to 86Box!" +#define IDS_2118 2118 // "Internal controller" +#define IDS_2119 2119 // "Exit" +#define IDS_2120 2120 // "No ROMs found" +#define IDS_2121 2121 // "Save changes\nThis will hard..." +#define IDS_2122 2122 // "Discard changes\nAll changes..." +#define IDS_2123 2123 // "Cancel\nGo back to the..." +#define IDS_2124 2124 // "About " EMU_NAME +#define IDS_2125 2125 // EMU_NAME " v" EMU_VERSION +#define IDS_2126 2126 // "An emulator of old computers..." +#define IDS_2127 2127 // "OK" +#define IDS_2128 2128 // "Hardware not available" +#define IDS_2129 2129 // "Make sure " LIB_NAME_PCAP "..." +#define IDS_2130 2130 // "Invalid configuration" +#define IDS_2131 2131 // LIB_NAME_FREETYPE " is required..." +#define IDS_2132 2132 // LIB_NAME_GS " is required for... +#define IDS_2133 2133 // LIB_NAME_FLUIDSYNTH " is required..." +#define IDS_2134 2134 // "Entering fullscreen mode" +#define IDS_2135 2135 // "Don't show this message again" +#define IDS_2136 2136 // "Don't Exit" +#define IDS_2137 2137 // "Reset" +#define IDS_2138 2138 // "Don't Reset" #define IDS_4096 4096 // "Hard disk (%s)" #define IDS_4097 4097 // "%01i:%01i" @@ -100,16 +121,24 @@ #define IDS_4101 4101 // "Custom (large)..." #define IDS_4102 4102 // "Add New Hard Disk" #define IDS_4103 4103 // "Add Existing Hard Disk" -#define IDS_4104 4104 // "Attempting to create a HDI ima.." -#define IDS_4105 4105 // "Attempting to create a spurio.." +#define IDS_4104 4104 // "HDI disk images cannot be..." +#define IDS_4105 4105 // "Disk images cannot be larger..." #define IDS_4106 4106 // "Hard disk images (*.HDI;*.HD.." #define IDS_4107 4107 // "Unable to open the file for read" #define IDS_4108 4108 // "Unable to open the file for write" #define IDS_4109 4109 // "HDI or HDX image with a sect.." #define IDS_4110 4110 // "USB is not yet supported" -#define IDS_4111 4111 // "This image exists and will be.." -#define IDS_4112 4112 // "Please enter a valid file name" +#define IDS_4111 4111 // "Disk image file already exists" +#define IDS_4112 4112 // "Please specify a valid file name." #define IDS_4113 4113 // "Remember to partition and fo.." +#define IDS_4114 4114 // "Make sure the file exists and..." +#define IDS_4115 4115 // "Make sure the file is being..." +#define IDS_4116 4116 // "Disk image too large" +#define IDS_4117 4117 // "Remember to partition and format..." +#define IDS_4118 4118 // "The selected file will be..." +#define IDS_4119 4119 // "Unsupported disk image" +#define IDS_4120 4120 // "Overwrite" +#define IDS_4121 4121 // "Don't Overwrite" #define IDS_4352 4352 // "MFM/RLL" #define IDS_4353 4353 // "XT IDE" @@ -169,7 +198,7 @@ #define IDS_LANG_ENUS IDS_7168 -#define STR_NUM_2048 70 +#define STR_NUM_2048 71 #define STR_NUM_3072 11 #define STR_NUM_4096 18 #define STR_NUM_4352 7 diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 5c973bb9a..6c011cc10 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -40,7 +40,7 @@ #define MACHINE_MOUSE 0x008000 /* sys has int mouse */ #define MACHINE_SOUND 0x010000 /* sys has int sound */ #define MACHINE_NONMI 0x020000 /* sys does not have NMI's */ -#define MACHINE_COREBOOT 0x040000 /* sys has coreboot BIOS */ +#define MACHINE_FDC 0x040000 /* sys has int FDC */ #else #define MACHINE_PC 0x000000 /* PC architecture */ #define MACHINE_AT 0x000001 /* PC/AT architecture */ @@ -58,16 +58,44 @@ #define MACHINE_MOUSE 0x008000 /* sys has int mouse */ #define MACHINE_SOUND 0x010000 /* sys has int sound */ #define MACHINE_NONMI 0x020000 /* sys does not have NMI's */ -#define MACHINE_COREBOOT 0x040000 /* sys has coreboot BIOS */ +#define MACHINE_FDC 0x040000 /* sys has int FDC */ #endif #define IS_ARCH(m, a) (machines[(m)].flags & (a)) ? 1 : 0; +enum { + MACHINE_TYPE_NONE = 0, + MACHINE_TYPE_8088, + MACHINE_TYPE_8086, + MACHINE_TYPE_286, + MACHINE_TYPE_386SX, + MACHINE_TYPE_386DX, + MACHINE_TYPE_486, + MACHINE_TYPE_SOCKET4, + MACHINE_TYPE_SOCKET5, + MACHINE_TYPE_SOCKET7_3V, + MACHINE_TYPE_SOCKET7, + MACHINE_TYPE_SOCKETS7, + MACHINE_TYPE_SOCKET8, + MACHINE_TYPE_SLOT1, + MACHINE_TYPE_SLOT2, + MACHINE_TYPE_SOCKET370, + MACHINE_TYPE_MAX +}; + + +typedef struct _machine_type_ { + const char *name; + const char id; +} machine_type_t; + + #ifdef NEW_STRUCT typedef struct _machine_ { const char *name; const char *internal_name; + const char type; #ifdef EMU_DEVICE_H const device_t *device; #else @@ -90,6 +118,7 @@ typedef struct _machine_ { typedef struct _machine_ { const char *name; const char *internal_name; + const char type; struct { const char *name; #ifdef EMU_CPU_H @@ -113,10 +142,11 @@ typedef struct _machine_ { /* Global variables. */ -extern const machine_t machines[]; -extern int bios_only; -extern int machine; -extern int AT, PCI; +extern const machine_type_t machine_types[]; +extern const machine_t machines[]; +extern int bios_only; +extern int machine; +extern int AT, PCI; /* Core functions. */ @@ -222,6 +252,7 @@ extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_pb410a_init(const machine_t *); +extern int machine_at_acera1g_init(const machine_t *); extern int machine_at_ali1429_init(const machine_t *); extern int machine_at_winbios1429_init(const machine_t *); @@ -229,6 +260,7 @@ extern int machine_at_opti495_init(const machine_t *); extern int machine_at_opti495_ami_init(const machine_t *); extern int machine_at_opti495_mr_init(const machine_t *); +extern int machine_at_vli486sv2g_init(const machine_t *); extern int machine_at_ami471_init(const machine_t *); extern int machine_at_dtk486_init(const machine_t *); extern int machine_at_px471_init(const machine_t *); @@ -240,8 +272,11 @@ extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); extern int machine_at_4dps_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_486sp3g_init(const machine_t *); +extern int machine_at_486ap4_init(const machine_t *); + +#ifdef EMU_DEVICE_H +extern const device_t *at_acera1g_get_device(void); #endif /* m_at_commodore.c */ @@ -272,11 +307,13 @@ extern int machine_at_430nx_init(const machine_t *); extern int machine_at_p54tp4xe_init(const machine_t *); extern int machine_at_endeavor_init(const machine_t *); extern int machine_at_zappa_init(const machine_t *); +extern int machine_at_gw2kzp_init(const machine_t *); extern int machine_at_mb500n_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_VECTRA54) extern int machine_at_vectra54_init(const machine_t *); #endif extern int machine_at_powermate_v_init(const machine_t *); +extern int machine_at_acerv30_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *at_endeavor_get_device(void); @@ -286,6 +323,7 @@ extern const device_t *at_endeavor_get_device(void); extern int machine_at_chariot_init(const machine_t *); extern int machine_at_mr586_init(const machine_t *); extern int machine_at_thor_init(const machine_t *); +extern int machine_at_gw2katx_init(const machine_t *); extern int machine_at_mrthor_init(const machine_t *); extern int machine_at_pb640_init(const machine_t *); @@ -326,6 +364,10 @@ extern int machine_at_mvp3_init(const machine_t *); /* m_at_socket8.c */ extern int machine_at_686nx_init(const machine_t *); +extern int machine_at_v60n_init(const machine_t *); +extern int machine_at_vs440fx_init(const machine_t *); +extern int machine_at_gw2kvs_init(const machine_t *); +extern int machine_at_ap440fx_init(const machine_t *); extern int machine_at_mb600n_init(const machine_t *); extern int machine_at_8500ttc_init(const machine_t *); extern int machine_at_m6mi_init(const machine_t *); @@ -338,27 +380,25 @@ extern int machine_at_p65up5_cp6nd_init(const machine_t *); extern int machine_at_p65up5_cpknd_init(const machine_t *); extern int machine_at_kn97_init(const machine_t *); +extern int machine_at_lx6_init(const machine_t *); + extern int machine_at_p6i440e2_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_bf6_init(const machine_t *); +extern int machine_at_ax6bc_init(const machine_t *); extern int machine_at_atc6310bxii_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_tsunamiatx_init(const machine_t *); -#endif extern int machine_at_p6sba_init(const machine_t *); #ifdef EMU_DEVICE_H -#if defined(DEV_BRANCH) && defined(NO_SIO) extern const device_t *at_tsunamiatx_get_device(void); #endif -#endif /* m_at_slot2.c */ -#if defined(DEV_BRANCH) && defined(NO_SIO) +extern int machine_at_6gxu_init(const machine_t *); extern int machine_at_s2dge_init(const machine_t *); -#endif /* m_at_socket370.c */ extern int machine_at_s370slm_init(const machine_t *); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 7d084a2b0..a6dfaea32 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -27,31 +27,45 @@ #define MEM_MAPPING_ROM 4 /* Executing from ROM may involve * additional wait states. */ #define MEM_MAPPING_ROMCS 8 /* respond to ROMCS* */ +#define MEM_MAPPING_SMRAM 16 /* on internal bus (RAM) but SMRAM */ #define MEM_MAP_TO_SHADOW_RAM_MASK 1 #define MEM_MAP_TO_RAM_ADDR_MASK 2 -#define MEM_READ_ANY 0x00 -#define MEM_READ_INTERNAL 0x10 -#define MEM_READ_EXTERNAL 0x20 -#define MEM_READ_DISABLED 0x30 -#define MEM_READ_NORMAL 0x40 /* SMM only - means use the non-SMM state */ -#define MEM_READ_EXTERNAL_EX 0x50 /* External but with internal exec - needed by the VIA Apollo Pro */ -#define MEM_READ_ROMCS 0x60 /* EXTERNAL type + ROMC flag */ -#define MEM_READ_EXTANY 0x70 /* Any EXTERNAL type */ -#define MEM_READ_MASK 0xf0 +/* _mem_state layout: + Bits 0 - 7: Normal write + Bits 8 -15: Normal read + Bits 16 -23: SMM write + Bits 24 -31: SMM read +*/ -#define MEM_WRITE_ANY 0x00 -#define MEM_WRITE_INTERNAL 0x01 -#define MEM_WRITE_EXTERNAL 0x02 -#define MEM_WRITE_DISABLED 0x03 -#define MEM_WRITE_NORMAL 0x04 /* SMM only - means use the non-SMM state */ -#define MEM_WRITE_EXTERNAL_EX 0x05 -#define MEM_WRITE_ROMCS 0x06 /* EXTERNAL type + ROMC flag */ -#define MEM_WRITE_EXTANY 0x07 /* Any EXTERNAL type */ -#define MEM_WRITE_MASK 0x0f +#define MEM_READ_ANY 0x0000 +#define MEM_READ_INTERNAL 0x0100 +#define MEM_READ_EXTERNAL 0x0200 +#define MEM_READ_DISABLED 0x0300 +#define MEM_READ_NORMAL 0x0400 /* SMM only - means use the non-SMM state */ +#define MEM_READ_EXTERNAL_EX 0x0500 /* External but with internal exec - needed by the VIA Apollo Pro */ +#define MEM_READ_ROMCS 0x0600 /* EXTERNAL type + ROMC flag */ +#define MEM_READ_EXTANY 0x0700 /* Any EXTERNAL type */ +#define MEM_READ_SMRAM 0x1000 +#define MEM_READ_SMRAM_EX 0x2000 +#define MEM_READ_DISABLED_EX 0x4000 +#define MEM_READ_MASK 0xff00 -#define MEM_STATE_SMM_SHIFT 8 +#define MEM_WRITE_ANY 0x0000 +#define MEM_WRITE_INTERNAL 0x0001 +#define MEM_WRITE_EXTERNAL 0x0002 +#define MEM_WRITE_DISABLED 0x0003 +#define MEM_WRITE_NORMAL 0x0004 /* SMM only - means use the non-SMM state */ +#define MEM_WRITE_EXTERNAL_EX 0x0005 +#define MEM_WRITE_ROMCS 0x0006 /* EXTERNAL type + ROMC flag */ +#define MEM_WRITE_EXTANY 0x0007 /* Any EXTERNAL type */ +#define MEM_WRITE_SMRAM 0x0010 +#define MEM_WRITE_SMRAM_EX 0x0020 +#define MEM_WRITE_DISABLED_EX 0x0040 +#define MEM_WRITE_MASK 0x00ff + +#define MEM_STATE_SMM_SHIFT 16 /* #define's for memory granularity, currently 16k, but may change in the future - 4k works, less does not because of @@ -80,6 +94,13 @@ #define MEM_GRANULARITY_PAGE (MEM_GRANULARITY_MASK & ~0xfff) #endif +#define mem_set_mem_state_common(smm, base, size, state) mem_set_state(!!smm, 0, base, size, state) +#define mem_set_mem_state(base, size, state) mem_set_state(0, 0, base, size, state) +#define mem_set_mem_state_smm(base, size, state) mem_set_state(1, 0, base, size, state) +#define mem_set_mem_state_both(base, size, state) mem_set_state(2, 0, base, size, state) +#define mem_set_mem_state_smram(smm, base, size, is_smram) mem_set_state(!!smm, 1, base, size, is_smram) +#define mem_set_mem_state_smram_ex(smm, base, size, is_smram) mem_set_state(!!smm, 2, base, size, is_smram) + typedef struct _mem_mapping_ { struct _mem_mapping_ *prev, *next; @@ -162,7 +183,15 @@ typedef struct _page_ { #endif -extern uint8_t *ram; +typedef struct +{ + uint32_t size, + host_base, + ram_base; +} smram_t; + + +extern uint8_t *ram, *ram2; extern uint32_t rammask; extern uint8_t *rom; @@ -185,6 +214,8 @@ extern mem_mapping_t base_mapping, #endif ram_remapped_mapping, ram_high_mapping, + ram_2gb_mapping, + ram_smram_mapping[2], bios_mapping, bios_high_mapping; @@ -193,7 +224,8 @@ extern uint32_t mem_logical_addr; extern page_t *pages, **page_lookup; -extern uint32_t get_phys_virt,get_phys_phys; +extern uint32_t get_phys_virt, get_phys_phys; +extern smram_t smram[2]; extern int shadowbios, shadowbios_write; @@ -276,10 +308,7 @@ extern void mem_mapping_disable(mem_mapping_t *); extern void mem_mapping_enable(mem_mapping_t *); extern void mem_mapping_recalc(uint64_t base, uint64_t size); -extern void mem_set_mem_state_common(int smm, uint32_t base, uint32_t size, int state); - -extern void mem_set_mem_state(uint32_t base, uint32_t size, int state); -extern void mem_set_mem_state_smm(uint32_t base, uint32_t size, int state); +extern void mem_set_state(int smm, int mode, uint32_t base, uint32_t size, uint32_t state); extern uint8_t mem_readb_phys(uint32_t addr); extern uint16_t mem_readw_phys(uint32_t addr); @@ -297,6 +326,13 @@ extern void mem_write_ram(uint32_t addr, uint8_t val, void *priv); extern void mem_write_ramw(uint32_t addr, uint16_t val, void *priv); extern void mem_write_raml(uint32_t addr, uint32_t val, void *priv); +extern uint8_t mem_read_smram(uint32_t addr, void *priv); +extern uint16_t mem_read_smramw(uint32_t addr, void *priv); +extern uint32_t mem_read_smraml(uint32_t addr, void *priv); +extern void mem_write_smram(uint32_t addr, uint8_t val, void *priv); +extern void mem_write_smramw(uint32_t addr, uint16_t val, void *priv); +extern void mem_write_smraml(uint32_t addr, uint32_t val, void *priv); + extern uint8_t mem_read_bios(uint32_t addr, void *priv); extern uint16_t mem_read_biosw(uint32_t addr, void *priv); extern uint32_t mem_read_biosl(uint32_t addr, void *priv); diff --git a/src/include/86box/piix.h b/src/include/86box/piix.h deleted file mode 100644 index 025410b1a..000000000 --- a/src/include/86box/piix.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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. - * - * Emulation of the Intel PIIX, PIIX3, PIIX4, PIIX4E, and SMSC - * SLC90E66 (Victory66) Xcelerators. - * - * Emulation core dispatcher. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - */ - -extern const device_t piix_device; -extern const device_t piix_rev02_device; -extern const device_t piix3_device; -extern const device_t piix4_device; -extern const device_t piix4e_device; -extern const device_t slc90e66_device; diff --git a/src/include/86box/postcard.h b/src/include/86box/postcard.h index 6bc8564cf..8cf1d1c54 100644 --- a/src/include/86box/postcard.h +++ b/src/include/86box/postcard.h @@ -11,6 +11,7 @@ * * * Author: RichardG, + * * Copyright 2020 RichardG. */ #ifndef POSTCARD_H diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index 59dc27d0d..afcb33e5b 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -50,6 +50,7 @@ #define IDT_1705 1705 /* MB == IDC_TEXT_MB */ #define IDT_1706 1706 /* Memory: */ #define IDT_1707 1707 /* Video: */ +#define IDT_1708 1708 /* Machine type: */ #define IDT_1709 1709 /* Mouse: */ #define IDT_1710 1710 /* Joystick: */ #define IDT_1711 1711 /* Sound card: */ @@ -98,6 +99,7 @@ #define IDT_1765 1765 /* Board #3: */ #define IDT_1766 1766 /* Board #4: */ #define IDT_1767 1767 /* ISA RTC: */ +#define IDT_1768 1768 /* Ext FD Controller: */ /* @@ -116,17 +118,18 @@ #define IDC_COMBO_LANG 1009 #endif -#define IDC_COMBO_MACHINE 1010 /* machine/cpu config */ -#define IDC_CONFIGURE_MACHINE 1011 -#define IDC_COMBO_CPU_TYPE 1012 -#define IDC_COMBO_CPU 1013 -#define IDC_CHECK_FPU 1014 -#define IDC_COMBO_WS 1015 +#define IDC_COMBO_MACHINE_TYPE 1010 +#define IDC_COMBO_MACHINE 1011 /* machine/cpu config */ +#define IDC_CONFIGURE_MACHINE 1012 +#define IDC_COMBO_CPU_TYPE 1013 +#define IDC_COMBO_CPU 1014 +#define IDC_COMBO_FPU 1015 +#define IDC_COMBO_WS 1016 #ifdef USE_DYNAREC -#define IDC_CHECK_DYNAREC 1016 +#define IDC_CHECK_DYNAREC 1017 #endif -#define IDC_MEMTEXT 1017 -#define IDC_MEMSPIN 1018 +#define IDC_MEMTEXT 1018 +#define IDC_MEMSPIN 1019 #define IDC_TEXT_MB IDT_1705 #define IDC_VIDEO 1030 /* video config */ @@ -178,6 +181,8 @@ #define IDC_CHECK_POSTCARD 1130 #define IDC_COMBO_ISARTC 1131 #define IDC_CONFIGURE_ISARTC 1132 +#define IDC_COMBO_FDC 1133 +#define IDC_CONFIGURE_FDC 1134 #define IDC_GROUP_ISAMEM 1140 #define IDC_COMBO_ISAMEM_1 1141 #define IDC_COMBO_ISAMEM_2 1142 diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index b5ae837c1..d9b39ffe2 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -379,5 +379,6 @@ extern void scsi_device_command_phase0(scsi_device_t *dev, uint8_t *cdb); extern void scsi_device_command_phase1(scsi_device_t *dev); extern void scsi_device_command_stop(scsi_device_t *dev); extern void scsi_device_close_all(void); +extern void scsi_device_init(void); #endif /*SCSI_DEVICE_H*/ diff --git a/src/include/86box/scsi_ncr53c8xx.h b/src/include/86box/scsi_ncr53c8xx.h index f0cc4c5ec..423f8648e 100644 --- a/src/include/86box/scsi_ncr53c8xx.h +++ b/src/include/86box/scsi_ncr53c8xx.h @@ -26,6 +26,7 @@ extern const device_t ncr53c810_pci_device; +extern const device_t ncr53c810_onboard_pci_device; extern const device_t ncr53c825a_pci_device; extern const device_t ncr53c860_pci_device; extern const device_t ncr53c875_pci_device; diff --git a/src/include/86box/scsi_x54x.h b/src/include/86box/scsi_x54x.h index 175fdfe6c..6c8164902 100644 --- a/src/include/86box/scsi_x54x.h +++ b/src/include/86box/scsi_x54x.h @@ -423,7 +423,7 @@ typedef struct { PendingInterrupt, Lock, target_data_len, pad0; - uint32_t Base, rom_addr, /* address of BIOS ROM */ + uint32_t Base, fdc_address, rom_addr, /* address of BIOS ROM */ CmdParamLeft, Outgoing, transfer_size; @@ -486,6 +486,8 @@ typedef struct { pc_timer_t timer, ResetCB; Req_t Req; + + fdc_t *fdc; } x54x_t; diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index b618bfe1e..6e64742b6 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -25,6 +25,10 @@ extern const device_t fdc37c932fr_device; extern const device_t fdc37c932qf_device; extern const device_t fdc37c935_device; extern const device_t pc87306_device; +extern const device_t pc87307_device; +extern const device_t pc87309_device; +extern const device_t pc87332_device; +extern const device_t pc97307_device; extern const device_t sio_detect_device; extern const device_t um8669f_device; extern const device_t w83787f_device; diff --git a/src/include/86box/ui.h b/src/include/86box/ui.h index ce9635cf1..f497fb857 100644 --- a/src/include/86box/ui.h +++ b/src/include/86box/ui.h @@ -36,8 +36,12 @@ extern "C" { #define MBX_QUESTION_YN 4 #define MBX_FATAL 0x20 #define MBX_ANSI 0x80 +#define MBX_LINKS 0x100 +#define MBX_DONTASK 0x200 -extern int ui_msgbox(int type, void *arg); +extern int ui_msgbox(int flags, void *message); +extern int ui_msgbox_header(int flags, void *header, void *message); +extern int ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3); extern void ui_check_menu_item(int id, int checked); diff --git a/src/include/86box/via_vt82c586b.h b/src/include/86box/via_vt82c586b.h deleted file mode 100644 index 0dade9705..000000000 --- a/src/include/86box/via_vt82c586b.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - * - * Emulation of the VIA Apollo MVP3 southbridge - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2020 Melissa Goad. - */ - -extern const device_t via_vt82c586b_device; -extern const device_t via_vt82c596b_device; \ No newline at end of file diff --git a/src/include/86box/video.h b/src/include/86box/video.h index fb0c33b08..018b877a3 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -224,6 +224,7 @@ extern const device_t gd5426_vlb_device; extern const device_t gd5428_isa_device; extern const device_t gd5428_vlb_device; extern const device_t gd5428_mca_device; +extern const device_t gd5428_a1g_device; extern const device_t gd5429_isa_device; extern const device_t gd5429_vlb_device; extern const device_t gd5430_vlb_device; diff --git a/src/intel_sio.c b/src/intel_sio.c deleted file mode 100644 index 577c9ef50..000000000 --- a/src/intel_sio.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * 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. - * - * Emulation of Intel System I/O PCI chip. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/io.h> -#include <86box/apm.h> -#include <86box/dma.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/timer.h> -#include <86box/pit.h> -#include <86box/port_92.h> -#include <86box/machine.h> -#include <86box/intel_sio.h> - - -typedef struct -{ - uint8_t id, - regs[256]; - - uint16_t timer_base, - timer_latch; - - pc_timer_t timer; - - port_92_t * port_92; -} sio_t; - - -static void -sio_timer_write(uint16_t addr, uint8_t val, void *priv) -{ - sio_t *dev = (sio_t *) priv; - - if (!(addr & 0x0002)) { - if (addr & 0x0001) - dev->timer_latch = (dev->timer_latch & 0xff) | (val << 8); - else - dev->timer_latch = (dev->timer_latch & 0xff00) | val; - - timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); - } -} - - -static void -sio_timer_writew(uint16_t addr, uint16_t val, void *priv) -{ - sio_t *dev = (sio_t *) priv; - - if (!(addr & 0x0002)) { - dev->timer_latch = val; - - timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); - } -} - - -static uint8_t -sio_timer_read(uint16_t addr, void *priv) -{ - sio_t *dev = (sio_t *) priv; - uint16_t sio_timer_latch; - uint8_t ret = 0xff; - - if (!(addr & 0x0002)) { - sub_cycles((int)(PITCONST >> 32)); - - sio_timer_latch = timer_get_remaining_us(&dev->timer); - - if (addr & 0x0001) - ret = sio_timer_latch >> 8; - else - ret = sio_timer_latch & 0xff; - } - - return ret; -} - - -static uint16_t -sio_timer_readw(uint16_t addr, void *priv) -{ - sio_t *dev = (sio_t *) priv; - uint16_t ret = 0xffff; - - if (!(addr & 0x0002)) { - sub_cycles((int)(PITCONST >> 32)); - - ret = timer_get_remaining_us(&dev->timer); - } - - return ret; -} - - -static void -sio_write(int func, int addr, uint8_t val, void *priv) -{ - sio_t *dev = (sio_t *) priv; - uint8_t old; - - if (func > 0) - return; - - if (((addr >= 0x0f) && (addr < 0x4c)) && (addr != 0x40)) - return; - - /* The IB (original) variant of the SIO has no PCI IRQ steering. */ - if ((addr >= 0x60) && (addr <= 0x63) && (dev->id < 0x03)) - return; - - old = dev->regs[addr]; - dev->regs[addr] = val; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: - return; - - case 0x04: /*Command register*/ - val &= 0x08; - val |= 0x07; - break; - case 0x05: - val = 0; - break; - - case 0x06: /*Status*/ - val = 0; - break; - case 0x07: - val = 0x02; - break; - - case 0x40: - if (!((val ^ old) & 0x40)) - return; - - dma_alias_remove(); - if (val & 0x40) - dma_alias_set(); - break; - - case 0x4f: - if (!((val ^ old) & 0x40)) - return; - - port_92_remove(dev->port_92); - if (val & 0x40) - port_92_add(dev->port_92); - break; - - case 0x60: - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTA, val & 0xf); - break; - case 0x61: - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTC, val & 0xf); - break; - case 0x62: - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTB, val & 0xf); - break; - case 0x63: - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val & 0xf); - break; - - case 0x80: - case 0x81: - if (dev->timer_base & 0x01) { - io_removehandler(dev->timer_base & 0xfffc, 0x0004, - sio_timer_read, sio_timer_readw, NULL, - sio_timer_write, sio_timer_writew, NULL, dev); - } - dev->timer_base = (dev->regs[0x81] << 8) | (dev->regs[0x80] & 0xfd); - if (dev->timer_base & 0x01) { - io_sethandler(dev->timer_base & 0xfffc, 0x0004, - sio_timer_read, sio_timer_readw, NULL, - sio_timer_write, sio_timer_writew, NULL, dev); - } - break; - } -} - - -static uint8_t -sio_read(int func, int addr, void *priv) -{ - sio_t *dev = (sio_t *) priv; - uint8_t ret; - - ret = 0xff; - - if (func == 0) - ret = dev->regs[addr]; - - return ret; -} - - -static void -sio_config_write(uint16_t addr, uint8_t val, void *priv) -{ -} - - -static uint8_t -sio_config_read(uint16_t port, void *priv) -{ - uint8_t ret = 0x00; - - switch (port & 0x000f) { - case 3: - ret = 0xff; - break; - case 5: - ret = 0xd3; - - switch (cpu_pci_speed) { - case 20000000: - ret |= 0x0c; - break; - case 25000000: - default: - ret |= 0x00; - break; - case 30000000: - ret |= 0x08; - break; - case 33333333: - ret |= 0x04; - break; - } - break; - } - - return ret; -} - - -static void -sio_reset(void *priv) -{ - sio_t *dev = (sio_t *) priv; - - memset(dev->regs, 0, 256); - - dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/ - dev->regs[0x02] = 0x84; dev->regs[0x03] = 0x04; /*82378IB (SIO)*/ - dev->regs[0x04] = 0x07; dev->regs[0x05] = 0x00; - dev->regs[0x06] = 0x00; dev->regs[0x07] = 0x02; - dev->regs[0x08] = dev->id; - - dev->regs[0x40] = 0x20; dev->regs[0x41] = 0x00; - dev->regs[0x42] = 0x04; dev->regs[0x43] = 0x00; - dev->regs[0x44] = 0x20; dev->regs[0x45] = 0x10; - dev->regs[0x46] = 0x0f; dev->regs[0x47] = 0x00; - dev->regs[0x48] = 0x01; dev->regs[0x49] = 0x10; - dev->regs[0x4a] = 0x10; dev->regs[0x4b] = 0x0f; - dev->regs[0x4c] = 0x56; dev->regs[0x4d] = 0x40; - dev->regs[0x4e] = 0x07; dev->regs[0x4f] = 0x4f; - dev->regs[0x54] = 0x00; dev->regs[0x55] = 0x00; dev->regs[0x56] = 0x00; - dev->regs[0x60] = 0x80; dev->regs[0x61] = 0x80; dev->regs[0x62] = 0x80; dev->regs[0x63] = 0x80; - dev->regs[0x80] = 0x78; dev->regs[0x81] = 0x00; - dev->regs[0xa0] = 0x08; - dev->regs[0xa8] = 0x0f; - - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - if (dev->timer_base & 0x0001) { - io_removehandler(dev->timer_base & 0xfffc, 0x0004, - sio_timer_read, sio_timer_readw, NULL, - sio_timer_write, sio_timer_writew, NULL, dev); - } - - dev->timer_base = 0x0078; -} - - -static void -sio_close(void *p) -{ - sio_t *sio = (sio_t *)p; - - free(sio); -} - - -static void -sio_speed_changed(void *priv) -{ - sio_t *dev = (sio_t *) priv; - int te; - - te = timer_is_enabled(&dev->timer); - - timer_disable(&dev->timer); - if (te) - timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); -} - - -static void * -sio_init(const device_t *info) -{ - sio_t *sio = (sio_t *) malloc(sizeof(sio_t)); - memset(sio, 0, sizeof(sio_t)); - - pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, sio); - - device_add(&apm_device); - - sio->id = info->local; - sio_reset(sio); - - sio->port_92 = device_add(&port_92_pci_device); - - dma_alias_set(); - - io_sethandler(0x0073, 0x0001, - sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, sio); - io_sethandler(0x0075, 0x0001, - sio_config_read, NULL, NULL, sio_config_write, NULL, NULL, sio); - - timer_add(&sio->timer, NULL, NULL, 0); - - return sio; -} - - -const device_t sio_device = -{ - "Intel 82378IB (SIO)", - DEVICE_PCI, - 0x00, - sio_init, - sio_close, - NULL, - NULL, - sio_speed_changed, - NULL, - NULL -}; - - -const device_t sio_zb_device = -{ - "Intel 82378ZB (SIO)", - DEVICE_PCI, - 0x03, - sio_init, - sio_close, - NULL, - NULL, - sio_speed_changed, - NULL, - NULL -}; diff --git a/src/io.c b/src/io.c index 5aaedc8d6..b09624064 100644 --- a/src/io.c +++ b/src/io.c @@ -307,7 +307,7 @@ inb(uint16_t port) if (!found) sub_cycles(io_delay); - io_log("(%i, %i, %04i) in b(%04X) = %02X\n", in_smm, found, qfound, port, ret); + io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); return(ret); } @@ -332,11 +332,13 @@ outb(uint16_t port, uint8_t val) if (!found) { sub_cycles(io_delay); - if (cpu_use_dynarec && (port == 0xeb)) +#ifdef USE_DYNAREC + if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed))) update_tsc(); +#endif } - io_log("(%i, %i, %04i) outb(%04X, %02X)\n", in_smm, found, qfound, port, val); + io_log("[%04X:%08X] (%i, %i, %04i) outb(%04X, %02X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val); return; } @@ -387,7 +389,7 @@ inw(uint16_t port) if (!found) sub_cycles(io_delay); - io_log("(%i, %i, %04i) in w(%04X) = %04X\n", in_smm, found, qfound, port, ret); + io_log("[%04X:%08X] (%i, %i, %04i) in w(%04X) = %04X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); return ret; } @@ -425,11 +427,13 @@ outw(uint16_t port, uint16_t val) if (!found) { sub_cycles(io_delay); - if (cpu_use_dynarec && (port == 0xeb)) +#ifdef USE_DYNAREC + if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed))) update_tsc(); +#endif } - io_log("(%i, %i, %04i) outw(%04X, %04X)\n", in_smm, found, qfound, port, val); + io_log("[%04X:%08X] (%i, %i, %04i) outw(%04X, %04X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val); return; } @@ -498,8 +502,7 @@ inl(uint16_t port) if (!found) sub_cycles(io_delay); - if (in_smm) - io_log("(%i, %i, %04i) in l(%04X) = %08X\n", in_smm, found, qfound, port, ret); + io_log("[%04X:%08X] (%i, %i, %04i) in l(%04X) = %08X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); return ret; } @@ -552,11 +555,13 @@ outl(uint16_t port, uint32_t val) if (!found) { sub_cycles(io_delay); - if (cpu_use_dynarec && (port == 0xeb)) +#ifdef USE_DYNAREC + if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed))) update_tsc(); +#endif } - io_log("(%i, %i, %04i) outl(%04X, %08X)\n", in_smm, found, qfound, port, val); + io_log("[%04X:%08X] (%i, %i, %04i) outl(%04X, %08X)\n", CS, cpu_state.pc, in_smm, found, qfound, port, val); return; } diff --git a/src/ioapic.c b/src/ioapic.c new file mode 100644 index 000000000..a45ad14c7 --- /dev/null +++ b/src/ioapic.c @@ -0,0 +1,130 @@ +/* + * 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. + * + * Skeleton I/O APIC implementation, currently housing the MPS + * table patcher for machines that require it. + * + * + * + * Author: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/chipset.h> + + +typedef struct { + uint8_t dummy; +} ioapic_t; + + +#ifdef ENABLE_IOAPIC_LOG +int ioapic_do_log = ENABLE_IOAPIC_LOG; + + +static void +ioapic_log(const char *fmt, ...) +{ + va_list ap; + + if (ioapic_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define ioapic_log(fmt, ...) +#endif + + +static void +ioapic_write(uint16_t port, uint8_t val, void *priv) +{ + uint32_t addr, pcmp; + + /* target POST FF, issued by Award before jumping to the bootloader */ + if (val != 0xff) + return; + + ioapic_log("IOAPIC: Caught POST %02X\n", val); + + /* The _MP_ table must be located in the BIOS area, the EBDA, or the last 1k of conventional + memory; at a 16-byte boundary in all cases. Award writes both tables to the BIOS area. */ + for (addr = 0xf0000; addr <= 0xfffff; addr += 16) { + /* check signature for the _MP_ table (Floating Point Structure) */ + if (mem_readl_phys(addr) != 0x5f504d5f) /* ASCII "_MP_" */ + continue; + + /* read and check pointer to the PCMP table (Configuration Table) */ + pcmp = mem_readl_phys(addr + 4); + if ((pcmp < 0xf0000) || (pcmp > 0xfffff) || (mem_readl_phys(pcmp) != 0x504d4350)) /* ASCII "PCMP" */ + continue; + + /* patch over the signature on both tables */ + ioapic_log("IOAPIC: Patching _MP_ [%08x] and PCMP [%08x] tables\n", addr, pcmp); + ram[addr] = ram[addr + 1] = ram[addr + 2] = ram[addr + 3] = 0xff; + ram[pcmp] = ram[pcmp + 1] = ram[pcmp + 2] = ram[pcmp + 3] = 0xff; + + break; + } +} + + +static void +ioapic_reset(ioapic_t *dev) +{ +} + + +static void +ioapic_close(void *priv) +{ + ioapic_t *dev = (ioapic_t *) priv; + + io_removehandler(0x80, 1, + NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL); + + free(dev); +} + + +static void * +ioapic_init(const device_t *info) +{ + ioapic_t *dev = (ioapic_t *) malloc(sizeof(ioapic_t)); + memset(dev, 0, sizeof(ioapic_t)); + + ioapic_reset(dev); + + io_sethandler(0x80, 1, + NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL); + + return dev; +} + + +const device_t ioapic_device = { + "I/O Advanced Programmable Interrupt Controller", + DEVICE_AT, + 0, + ioapic_init, ioapic_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/machine/m_at.c b/src/machine/m_at.c index 90f4fc40c..7adc98ecd 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -49,6 +49,7 @@ #include <86box/device.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/nvr.h> #include <86box/gameport.h> #include <86box/keyboard.h> @@ -102,7 +103,8 @@ machine_at_ibm_common_init(const machine_t *model) mem_remap_top(384); - device_add(&fdc_at_device); + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); } diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index ddc349033..6b6e00e52 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -53,11 +53,11 @@ machine_at_mr286_init(const machine_t *model) machine_at_common_ide_init(model); device_add(&keyboard_at_device); device_add(&fdc_at_device); - device_add(&headland_device); return ret; } + static void machine_at_headland_common_init(int ht386) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 5f44c434b..21cb0971c 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -40,7 +40,6 @@ #include <86box/video.h> #include <86box/intel_flash.h> #include <86box/sst_flash.h> -#include <86box/intel_sio.h> #include <86box/scsi_ncr53c8xx.h> #include <86box/machine.h> @@ -126,6 +125,36 @@ machine_at_pb410a_init(const machine_t *model) return ret; } +int +machine_at_acera1g_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/acera1g/4alo001.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + + if (gfxcard == VID_INTERNAL) + device_add(&gd5428_a1g_device); + + device_add(&ali1429_device); + device_add(&keyboard_ps2_acer_pci_device); + device_add(&fdc_at_device); + device_add(&ide_isa_device); + + return ret; +} + +const device_t * +at_acera1g_get_device(void) +{ + return &gd5428_a1g_device; +} + static void machine_at_ali1429_common_init(const machine_t *model) @@ -268,6 +297,22 @@ machine_at_ami471_init(const machine_t *model) return ret; } +int +machine_at_vli486sv2g_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/vli486sv2g/0402.001", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_sis_85c471_common_init(model); + device_add(&keyboard_at_device); + + return ret; +} int machine_at_dtk486_init(const machine_t *model) @@ -446,7 +491,7 @@ machine_at_alfredo_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(NO_SIO) + int machine_at_486sp3g_init(const machine_t *model) { @@ -472,12 +517,40 @@ machine_at_486sp3g_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ device_add(&sio_device); /* Site says it has a ZB, but the BIOS is designed for an IB. */ - device_add(&pc87306_device); /*PC87332*/ + device_add(&pc87332_device); device_add(&sst_flash_29ee010_device); - device_add(&ncr53c810_pci_device); device_add(&i420zx_device); + device_add(&ncr53c810_onboard_pci_device); + + return ret; +} + + +int +machine_at_486ap4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/486ap4/0205.002", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + /* Excluded: 5, 6, 7, 8 */ + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 09 = Slot 1 */ + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 0a = Slot 2 */ + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 0b = Slot 3 */ + pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 0c = Slot 4 */ + device_add(&keyboard_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ + device_add(&fdc_at_device); + + device_add(&i420ex_device); return ret; } -#endif diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 7cd3f254e..aed26a6f6 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -33,6 +33,7 @@ #include <86box/device.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> @@ -45,7 +46,8 @@ enum { COMPAQ_PORTABLEII = 0, COMPAQ_PORTABLEIII, - COMPAQ_PORTABLEIII386 + COMPAQ_PORTABLEIII386, + COMPAQ_DESKPRO386 }; #define CGA_RGB 0 @@ -809,9 +811,11 @@ machine_at_compaq_init(const machine_t *model, int type) { machine_at_init(model); - mem_remap_top(384); + if (type != COMPAQ_DESKPRO386) + mem_remap_top(384); - device_add(&fdc_at_device); + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, read_ram, read_ramw, read_raml, @@ -833,6 +837,11 @@ machine_at_compaq_init(const machine_t *model, int type) if (gfxcard == VID_INTERNAL) device_add(&compaq_plasma_device); break; + + case COMPAQ_DESKPRO386: + if (hdc_current == 1) + device_add(&ide_isa_device); + break; } } diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index a324c56f9..b9ffbf658 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -30,10 +30,7 @@ #include <86box/hdc_ide.h> #include <86box/keyboard.h> #include <86box/intel_flash.h> -#include <86box/intel_sio.h> -#include <86box/piix.h> #include <86box/sio.h> -#include <86box/intel_sio.h> #include <86box/sst_flash.h> #include <86box/hwm.h> #include <86box/spd.h> @@ -58,6 +55,7 @@ machine_at_p65up5_cpknd_init(const machine_t *model) return ret; } + int machine_at_kn97_init(const machine_t *model) { @@ -108,6 +106,38 @@ machine_at_kn97_init(const machine_t *model) return ret; } + +int +machine_at_lx6_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/lx6/LX6C_PZ.B00", + 0x000e0000, 131072, 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, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i440lx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977tf_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + + return ret; +} + + int machine_at_p6i440e2_init(const machine_t *model) { @@ -161,6 +191,7 @@ machine_at_p6i440e2_init(const machine_t *model) return ret; } + int machine_at_p2bls_init(const machine_t *model) { @@ -222,6 +253,7 @@ machine_at_p2bls_init(const machine_t *model) return ret; } + int machine_at_p3bf_init(const machine_t *model) { @@ -285,6 +317,7 @@ machine_at_p3bf_init(const machine_t *model) return ret; } + int machine_at_bf6_init(const machine_t *model) { @@ -319,6 +352,40 @@ machine_at_bf6_init(const machine_t *model) return ret; } + +int +machine_at_ax6bc_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/ax6bc/AX6BC_R2.59.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(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977tf_device); + device_add(&sst_flash_29ee020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; +} + + int machine_at_atc6310bxii_init(const machine_t *model) { @@ -351,15 +418,10 @@ machine_at_atc6310bxii_init(const machine_t *model) return ret; } + int machine_at_p6sba_init(const machine_t *model) -{ - /* - AMI 440BX Board. - doesn't like the i686 CPU's. - 10 -> D3 -> D1 POST. Probably KBC related. - */ - +{ int ret; ret = bios_load_linear(L"roms/machines/p6sba/SBAB21.ROM", @@ -414,13 +476,10 @@ machine_at_p6sba_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(NO_SIO) + int machine_at_tsunamiatx_init(const machine_t *model) { - /* AMI 440BX board. Requires the PC87309 - and doesn't like the i686 CPUs */ - int ret; ret = bios_load_linear(L"roms/machines/tsunamiatx/bx46200f.rom", @@ -447,7 +506,7 @@ machine_at_tsunamiatx_init(const machine_t *model) if (sound_card_current == SOUND_INTERNAL) device_add(&es1371_onboard_device); - device_add(&pc87306_device); /* PC87309 */ + device_add(&pc87309_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -455,9 +514,9 @@ machine_at_tsunamiatx_init(const machine_t *model) return ret; } + const device_t * at_tsunamiatx_get_device(void) { return &es1371_onboard_device; } -#endif diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index b85ce9a83..8ed78a000 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -31,28 +31,74 @@ #include <86box/hdc_ide.h> #include <86box/keyboard.h> #include <86box/intel_flash.h> -#include <86box/intel_sio.h> -#include <86box/piix.h> +#include <86box/sst_flash.h> #include <86box/sio.h> -#include <86box/intel_sio.h> #include <86box/hwm.h> #include <86box/spd.h> #include <86box/video.h> #include "cpu.h" #include <86box/machine.h> -#if defined(DEV_BRANCH) && defined(NO_SIO) +int +machine_at_6gxu_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"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_NORMAL, 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); + + hwm_values_t machine_hwm = { + { /* fan speeds */ + 3000, /* Chassis */ + 3000, /* CPU */ + 3000 /* Power */ + }, { /* temperatures */ + 30, /* MB */ + 0, /* unused */ + 27 /* CPU */ + }, { /* voltages */ + 2050, /* VCORE (2.05V by default) */ + 0, /* unused */ + 3300, /* +3.3V */ + RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ + RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ + RESISTOR_DIVIDER(12000, 853, 347), /* -12V (divider values bruteforced) */ + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ + } + }; + if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) + machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Klamath */ + hwm_set_values(machine_hwm); + device_add(&w83781d_device); + + return ret; +} + int machine_at_s2dge_init(const machine_t *model) { - - /* - 440GX AMI Slot 2 motherboard - - This board under a i686 CPU freezes on POST code D0. - According to the manual it has to do with the NMI which - seems to be related on the I/O APIC. Works fine under a VIA C3. - */ int ret; ret = bios_load_linear(L"roms/machines/s2dge/2gu7301.rom", @@ -74,7 +120,7 @@ machine_at_s2dge_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&i440bx_device); /* i440GX */ + device_add(&i440gx_device); device_add(&piix4e_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&w83977tf_device); @@ -107,4 +153,3 @@ machine_at_s2dge_init(const machine_t *model) return ret; } -#endif \ No newline at end of file diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index c730a1af6..5642cc74f 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -30,9 +30,6 @@ #include <86box/hdc_ide.h> #include <86box/keyboard.h> #include <86box/intel_flash.h> -#include <86box/via_vt82c586b.h> -#include <86box/intel_sio.h> -#include <86box/piix.h> #include <86box/sio.h> #include <86box/sst_flash.h> #include <86box/hwm.h> diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index 0567a5d1a..eb311d587 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -35,9 +35,8 @@ #include <86box/fdc.h> #include <86box/keyboard.h> #include <86box/intel_flash.h> -#include <86box/intel_sio.h> +#include <86box/sst_flash.h> #include <86box/nvr.h> -#include <86box/piix.h> #include <86box/sio.h> #include <86box/video.h> #include <86box/machine.h> @@ -76,7 +75,7 @@ machine_at_premiere_common_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_ps2_intel_ami_pci_device); device_add(&sio_zb_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_ami_device); @@ -342,6 +341,35 @@ machine_at_zappa_init(const machine_t *model) } +int +machine_at_gw2kzp_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined(L"roms/machines/gw2k_zp/1011bs0t.bio", + L"roms/machines/gw2k_zp/1011bs0t.bi1", 0x20000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&pc87306_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + int machine_at_mb500n_init(const machine_t *model) { @@ -430,3 +458,34 @@ machine_at_powermate_v_init(const machine_t *model) return ret; } + + +int +machine_at_acerv30_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/acerv30/V30R01N9.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + 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, 0); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&keyboard_ps2_acer_pci_device); + device_add(&fdc37c665_device); + + device_add(&sst_flash_29ee010_device); + + return ret; +} diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index 0b93b7b20..41ca9aa55 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -34,11 +34,8 @@ #include <86box/hdc_ide.h> #include <86box/keyboard.h> #include <86box/intel_flash.h> -#include <86box/intel_sio.h> -#include <86box/piix.h> #include <86box/sio.h> #include <86box/sst_flash.h> -#include <86box/via_vt82c586b.h> #include <86box/hwm.h> #include <86box/video.h> #include <86box/spd.h> @@ -143,6 +140,23 @@ machine_at_thor_init(const machine_t *model) } +int +machine_at_gw2katx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined(L"roms/machines/gw2katx/1003cn0t.bio", + L"roms/machines/gw2katx/1003cn0t.bi1", 0x20000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_thor_common_init(model, 0); + + return ret; +} + + int machine_at_mrthor_init(const machine_t *model) { @@ -180,7 +194,7 @@ machine_at_pb640_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 2, 1, 4); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&i430fx_pb640_device); + device_add(&i430fx_rev02_device); device_add(&piix_rev02_device); if (gfxcard == VID_INTERNAL) @@ -227,7 +241,7 @@ machine_at_acerm3a_init(const machine_t *model) device_add(&fdc37c932fr_device); device_add(&acerm3a_device); - device_add(&intel_flash_bxb_device); + device_add(&sst_flash_29ee010_device); return ret; } @@ -260,7 +274,7 @@ machine_at_acerv35n_init(const machine_t *model) device_add(&fdc37c932fr_device); device_add(&acerm3a_device); - device_add(&intel_flash_bxb_device); + device_add(&sst_flash_29ee010_device); return ret; } @@ -572,10 +586,10 @@ machine_at_brio80xx_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x14, PCI_CARD_ONBOARD, 4, 0, 0, 0); pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); @@ -816,6 +830,7 @@ machine_at_ym430tx_init(const machine_t *model) return ret; } + int machine_at_mb540n_init(const machine_t *model) { @@ -846,6 +861,7 @@ machine_at_mb540n_init(const machine_t *model) return ret; } + int machine_at_p5mms98_init(const machine_t *model) { @@ -911,6 +927,7 @@ machine_at_p5mms98_init(const machine_t *model) return ret; } + int machine_at_ficva502_init(const machine_t *model) { @@ -940,6 +957,7 @@ machine_at_ficva502_init(const machine_t *model) return ret; } + int machine_at_ficpa2012_init(const machine_t *model) { diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index fd7b5bcea..95dfa2e14 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -31,8 +31,6 @@ #include <86box/keyboard.h> #include <86box/intel_flash.h> #include <86box/sst_flash.h> -#include <86box/intel_sio.h> -#include <86box/piix.h> #include <86box/sio.h> #include <86box/sst_flash.h> #include <86box/hwm.h> @@ -100,6 +98,138 @@ machine_at_mb600n_init(const machine_t *model) return ret; } +int +machine_at_v60n_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/v60n/V60NE5.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + 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, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x12, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 2, 3, 4, 1); + device_add(&i440fx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_pci_device); + device_add(&fdc37c935_device); + device_add(&acerm3a_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + +int +machine_at_vs440fx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2(L"roms/machines/vs440fx/1018CS1_.bio", + L"roms/machines/vs440fx/1018CS1_.bi1", + L"roms/machines/vs440fx/1018CS1_.bi2", + L"roms/machines/vs440fx/1018CS1_.bi3", + L"roms/machines/vs440fx/1018CS1_.rcv", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i440fx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&pc87307_device); + + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + +int +machine_at_gw2kvs_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2(L"roms/machines/gw2kvs/1011CS1T.bio", + L"roms/machines/gw2kvs/1011CS1T.bi1", + L"roms/machines/gw2kvs/1011CS1T.bi2", + L"roms/machines/gw2kvs/1011CS1T.bi3", + L"roms/machines/gw2kvs/1011CS1T.rcv", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i440fx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&pc87307_device); + + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + +int +machine_at_ap440fx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2(L"roms/machines/ap440fx/1011CT1_.bio", + L"roms/machines/ap440fx/1011CT1_.bi1", + L"roms/machines/ap440fx/1011CT1_.bi2", + L"roms/machines/ap440fx/1011CT1_.bi3", + L"roms/machines/ap440fx/1011CT1_.rcv", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_ONBOARD, 3, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + device_add(&i440fx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&pc87307_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + int machine_at_8500ttc_init(const machine_t *model) { @@ -176,6 +306,7 @@ machine_at_p65up5_common_init(const machine_t *model, const device_t *northbridg device_add(&keyboard_ps2_ami_pci_device); device_add(&w83877f_device); device_add(&intel_flash_bxt_device); + device_add(&ioapic_device); } int diff --git a/src/machine/m_at_super7_ss7.c b/src/machine/m_at_sockets7.c similarity index 97% rename from src/machine/m_at_super7_ss7.c rename to src/machine/m_at_sockets7.c index bc876a206..ebaaa49ee 100644 --- a/src/machine/m_at_super7_ss7.c +++ b/src/machine/m_at_sockets7.c @@ -34,11 +34,8 @@ #include <86box/hdc_ide.h> #include <86box/keyboard.h> #include <86box/intel_flash.h> -#include <86box/intel_sio.h> -#include <86box/piix.h> #include <86box/sio.h> #include <86box/sst_flash.h> -#include <86box/via_vt82c586b.h> #include <86box/spd.h> #include <86box/hwm.h> #include <86box/video.h> diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 3fee77bba..26777dc77 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -35,6 +35,7 @@ #include <86box/nvr.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/gameport.h> #include <86box/keyboard.h> #include <86box/sound.h> @@ -1495,7 +1496,8 @@ machine_tandy1k_init(const machine_t *model, int type) device_add(&keyboard_tandy_device); keyboard_set_table(scancode_tandy); - device_add(&fdc_xt_device); + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_xt_device); switch(type) { case TYPE_TANDY: @@ -1524,6 +1526,7 @@ machine_tandy1k_init(const machine_t *model, int type) device_add_ex(&vid_device_sl, dev); device_add(&pssj_device); device_add(&eep_1000sl2_device); + break; } if (joystick_type != JOYSTICK_TYPE_NONE) diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 0cbf071d1..2f55040e6 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -10,6 +10,7 @@ #include <86box/device.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/gameport.h> #include <86box/ibm_5161.h> #include <86box/keyboard.h> @@ -24,7 +25,9 @@ machine_xt_common_init(const machine_t *model) pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); - device_add(&fdc_xt_device); + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_xt_device); + nmi_init(); if (joystick_type != JOYSTICK_TYPE_NONE) device_add(&gameport_device); @@ -264,6 +267,9 @@ machine_xt_hed919_init(const machine_t *model) machine_xt_clone_init(model); + if (mem_size > 640) + mem_remap_top(mem_size - 640); + return ret; } diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index 575500ffb..1b84a10de 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -31,6 +31,7 @@ #include <86box/device.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/gameport.h> #include <86box/keyboard.h> #include <86box/lpt.h> @@ -53,7 +54,8 @@ machine_xt_compaq_init(const machine_t *model) pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); device_add(&keyboard_xt_compaq_device); - device_add(&fdc_xt_device); + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_xt_device); nmi_init(); if (joystick_type != JOYSTICK_TYPE_NONE) device_add(&gameport_device); diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index 0d527d20b..c0448bd09 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -36,6 +36,7 @@ #include <86box/device.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/gameport.h> #include <86box/keyboard.h> #include <86box/lpt.h> @@ -116,8 +117,10 @@ machine_xt_zenith_init(const machine_t *model) return ret; machine_common_init(model); - - device_add(&fdc_xt_device); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_xt_device); + lpt1_remove(); /* only one parallel port */ lpt2_remove(); lpt1_init(0x278); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f6817b427..27054993f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -64,272 +64,295 @@ #endif +const machine_type_t machine_types[] = { + { "None", MACHINE_TYPE_NONE }, + { "8088", MACHINE_TYPE_8088 }, + { "8086", MACHINE_TYPE_8086 }, + { "80286", MACHINE_TYPE_286 }, + { "i386SX", MACHINE_TYPE_386SX }, + { "i386DX", MACHINE_TYPE_386DX }, + { "i486", MACHINE_TYPE_486 }, + { "Socket 4", MACHINE_TYPE_SOCKET4 }, + { "Socket 5", MACHINE_TYPE_SOCKET5 }, + { "Socket 7-3V", MACHINE_TYPE_SOCKET7_3V }, + { "Socket 7", MACHINE_TYPE_SOCKET7 }, + { "Super Socket 7", MACHINE_TYPE_SOCKETS7 }, + { "Socket 8", MACHINE_TYPE_SOCKET8 }, + { "Slot 1", MACHINE_TYPE_SLOT1 }, + { "Slot 2", MACHINE_TYPE_SLOT2 }, + { "Socket 370", MACHINE_TYPE_SOCKET370 }, +}; + + const machine_t machines[] = { /* 8088 Machines */ - { "[8088] AMI XT clone", "amixt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_amixt_init, NULL }, - { "[8088] Compaq Portable", "portable", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL }, - { "[8088] DTK XT clone", "dtk", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_dtk_init, NULL }, - { "[8088] IBM PC (1981)", "ibmpc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 16, 64, 16, 0, machine_pc_init, NULL }, - { "[8088] IBM PC (1982)", "ibmpc82", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 256, 256, 0, machine_pc82_init, NULL }, - { "[8088] IBM PCjr", "ibmpcjr", {{"Intel", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device }, - { "[8088] IBM XT (1982)", "ibmxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 256, 64, 0, machine_xt_init, NULL }, - { "[8088] IBM XT (1986)", "ibmxt86", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 64, 0, machine_xt86_init, NULL }, - { "[8088] Generic XT clone", "genxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_genxt_init, NULL }, - { "[8088] Juko XT clone", "jukopc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, - { "[8088] OpenXT", "open_xt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_open_xt_init, NULL }, - { "[8088] Phoenix XT clone", "pxxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_pxxt_init, NULL }, - { "[8088] Schneider EuroPC", "europc", {{"Siemens", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_HDC | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL }, - { "[8088] Tandy 1000", "tandy", {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_tandy_init, tandy1k_get_device }, - { "[8088] Tandy 1000 HX", "tandy1000hx", {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 256, 640, 128, 0, machine_tandy1000hx_init, tandy1k_hx_get_device }, - { "[8088] Toshiba T1000", "t1000", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, t1000_get_device }, + { "[8088] IBM PC (1981)", "ibmpc", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 16, 64, 16, 0, machine_pc_init, NULL }, + { "[8088] IBM PC (1982)", "ibmpc82", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 256, 256, 0, machine_pc82_init, NULL }, + { "[8088] IBM PCjr", "ibmpcjr", MACHINE_TYPE_8088, {{"Intel", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device }, + { "[8088] IBM XT (1982)", "ibmxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 256, 64, 0, machine_xt_init, NULL }, + { "[8088] IBM XT (1986)", "ibmxt86", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 64, 0, machine_xt86_init, NULL }, + { "[8088] AMI XT clone", "amixt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_amixt_init, NULL }, + { "[8088] Tandy 1000", "tandy", MACHINE_TYPE_8088, {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_tandy_init, tandy1k_get_device }, + { "[8088] Tandy 1000 HX", "tandy1000hx", MACHINE_TYPE_8088, {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 256, 640, 128, 0, machine_tandy1000hx_init, tandy1k_hx_get_device }, + { "[8088] Compaq Portable", "portable", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL }, + { "[8088] Generic XT clone", "genxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_genxt_init, NULL }, + { "[8088] DTK XT clone", "dtk", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_dtk_init, NULL }, + { "[8088] Juko XT clone", "jukopc", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, + { "[8088] OpenXT", "open_xt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_open_xt_init, NULL }, + { "[8088] Phoenix XT clone", "pxxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_pxxt_init, NULL }, + { "[8088] Schneider EuroPC", "europc", MACHINE_TYPE_8088, {{"Siemens", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_HDC | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL }, + { "[8088] Toshiba T1000", "t1000", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, t1000_get_device }, #if defined(DEV_BRANCH) && defined(USE_LASERXT) - { "[8088] VTech Laser Turbo XT", "ltxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_laserxt_init, NULL }, + { "[8088] VTech Laser Turbo XT", "ltxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_laserxt_init, NULL }, #endif - { "[8088] Xi8088", "xi8088", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device }, - { "[8088] Zenith Data SupersPort", "zdsupers", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_zenith_init, NULL }, + { "[8088] Xi8088", "xi8088", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device }, + { "[8088] Zenith Data SupersPort", "zdsupers", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_zenith_init, NULL }, /* 8086 Machines */ - { "[8086] Amstrad PC1512", "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device }, - { "[8086] Amstrad PC1640", "pc1640", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc1640_init, pc1640_get_device }, - { "[8086] Amstrad PC2086", "pc2086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc2086_init, pc2086_get_device }, - { "[8086] Amstrad PC3086", "pc3086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc3086_init, pc3086_get_device }, - { "[8086] Amstrad PC20(0)", "pc200", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_pc200_init, pc200_get_device }, - { "[8086] Amstrad PPC512/640", "ppc512", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_ppc512_init, ppc512_get_device }, - { "[8086] Olivetti M24", "olivetti_m24", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL }, - { "[8086] Tandy 1000 SL/2", "tandy1000sl2", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 512, 768, 128, 0, machine_tandy1000sl2_init, NULL }, - { "[8086] Toshiba T1200", "t1200", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device }, + { "[8086] Amstrad PC1512", "pc1512", MACHINE_TYPE_8086, {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device }, + { "[8086] Amstrad PC1640", "pc1640", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc1640_init, pc1640_get_device }, + { "[8086] Amstrad PC2086", "pc2086", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc2086_init, pc2086_get_device }, + { "[8086] Amstrad PC3086", "pc3086", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc3086_init, pc3086_get_device }, + { "[8086] Amstrad PC20(0)", "pc200", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_pc200_init, pc200_get_device }, + { "[8086] Amstrad PPC512/640", "ppc512", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_ppc512_init, ppc512_get_device }, + { "[8086] Olivetti M24", "olivetti_m24", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL }, + { "[8086] Tandy 1000 SL/2", "tandy1000sl2", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 512, 768, 128, 0, machine_tandy1000sl2_init, NULL }, + { "[8086] Toshiba T1200", "t1200", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device }, #if defined(DEV_BRANCH) && defined(USE_LASERXT) - { "[8086] VTech Laser XT3", "lxt3", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_lxt3_init, NULL }, + { "[8086] VTech Laser XT3", "lxt3", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_lxt3_init, NULL }, #endif /* 286 XT machines */ - { "[286 XT] Hedaka HED-919", "hed919", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_hed919_init, NULL }, + { "[Citygate D30 XT] Hedaka HED-919", "hed919", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 1024, 64, 0, machine_xt_hed919_init, NULL }, /* 286 AT machines */ - { "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, - { "[286 ISA] Phoenix 286 clone", "px286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_px286_init, NULL }, - { "[286 ISA] Quadtel 286 clone", "quadt286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_quadt286_init, NULL }, - { "[286 ISA] MR 286 clone", "mr286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 16384, 128, 127, machine_at_mr286_init, NULL }, - { "[286 ISA] Commodore PC 30 III", "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, - { "[286 ISA] Compaq Portable II", "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, - { "[286 ISA] Compaq Portable III", "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO, 640,16384, 128, 127, machine_at_portableiii_init, at_cpqiii_get_device }, - { "[286 ISA] GW-286CT GEAR", "gw286ct", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_gw286ct_init, NULL }, - { "[286 ISA] Goldstar GDC-212M", "gdc212m", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 512, 4096, 512, 127, machine_at_gdc212m_init, NULL }, - { "[286 ISA] Hyundai Super-286TR", "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_super286tr_init, NULL }, - { "[286 ISA] IBM AT", "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL }, - { "[286 ISA] AMI IBM AT", "ibmatami", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatami_init, NULL }, - { "[286 ISA] Quadtel IBM AT", "ibmatquadtel", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatquadtel_init, NULL }, - { "[286 ISA] Phoenix IBM AT", "ibmatpx", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatpx_init, NULL }, - { "[286 ISA] IBM PS/1 model 2011", "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC | MACHINE_PS2, 512,16384, 512, 63, machine_ps1_m2011_init, NULL }, - { "[286 ISA] IBM PS/2 model 30-286", "ibmps2_m30_286", {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC | MACHINE_PS2, 1, 16, 1, 127, machine_ps2_m30_286_init, NULL }, - { "[286 ISA] IBM XT Model 286", "ibmxt286", {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 127, machine_at_ibmxt286_init, NULL }, + { "[ISA] IBM AT", "ibmat", MACHINE_TYPE_286, {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL }, + { "[ISA] AMI IBM AT", "ibmatami", MACHINE_TYPE_286, {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatami_init, NULL }, + { "[ISA] Quadtel IBM AT", "ibmatquadtel", MACHINE_TYPE_286, {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatquadtel_init, NULL }, + { "[ISA] Phoenix IBM AT", "ibmatpx", MACHINE_TYPE_286, {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatpx_init, NULL }, + { "[ISA] IBM PS/1 model 2011", "ibmps1es", MACHINE_TYPE_286, {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC | MACHINE_PS2, 512,16384, 512, 63, machine_ps1_m2011_init, NULL }, + { "[ISA] IBM PS/2 model 30-286", "ibmps2_m30_286", MACHINE_TYPE_286, {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC | MACHINE_PS2, 1, 16, 1, 127, machine_ps2_m30_286_init, NULL }, + { "[ISA] IBM XT Model 286", "ibmxt286", MACHINE_TYPE_286, {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 127, machine_at_ibmxt286_init, NULL }, + { "[ISA] Commodore PC 30 III", "cmdpc30", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, + { "[ISA] Compaq Portable II", "portableii", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, + { "[ISA] Compaq Portable III", "portableiii", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO, 640,16384, 128, 127, machine_at_portableiii_init, at_cpqiii_get_device }, + { "[NEAT] AMI 286 clone", "ami286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, + { "[NEAT] Phoenix 286 clone", "px286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_px286_init, NULL }, + { "[SCAT] Award 286 clone", "award286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, + { "[SCAT] GW-286CT GEAR", "gw286ct", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_gw286ct_init, NULL }, + { "[SCAT] Goldstar GDC-212M", "gdc212m", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 512, 4096, 512, 127, machine_at_gdc212m_init, NULL }, + { "[SCAT] Hyundai Super-286TR", "super286tr", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_super286tr_init, NULL }, + { "[SCAT] Samsung SPC-4200P", "spc4200p", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 127, machine_at_spc4200p_init, NULL }, + { "[SCAT] Samsung SPC-4216P", "spc4216p", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 127, machine_at_spc4216p_init, NULL }, + { "[SCAT] Samsung Deskmaster 286", "deskmaster286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL }, + { "[HT18] Quadtel 286 clone", "quadt286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_quadt286_init, NULL }, + { "[HT18] Trigem 286M", "tg286m", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_tg286m_init, NULL }, + { "[ISA] MR 286 clone", "mr286", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_mr286_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_SIEMENS) - { "[286 ISA] Siemens PCD-2L", "siemens", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_siemens_init, NULL }, + { "[ISA] Siemens PCD-2L", "siemens", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_siemens_init, NULL }, #endif #if defined(DEV_BRANCH) && defined(USE_OPEN_AT) - { "[286 ISA] OpenAT", "open_at", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_open_at_init, NULL }, + { "[ISA] OpenAT", "open_at", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_open_at_init, NULL }, #endif - { "[286 ISA] Samsung SPC-4200P", "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 127, machine_at_spc4200p_init, NULL }, - { "[286 ISA] Samsung SPC-4216P", "spc4216p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 127, machine_at_spc4216p_init, NULL }, - { "[286 ISA] Toshiba T3100e", "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL }, - { "[286 ISA] Trigem 286M", "tg286m", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_tg286m_init, NULL }, - - { "[286 ISA] Samsung Deskmaster 286", "deskmaster286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL }, + { "[ISA] Toshiba T3100e", "t3100e", MACHINE_TYPE_286, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL }, /* 286 machines that utilize the MCA bus */ - { "[286 MCA] IBM PS/2 model 50", "ibmps2_m50", {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL }, + { "[MCA] IBM PS/2 model 50", "ibmps2_m50", MACHINE_TYPE_286, {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL }, /* 386SX machines */ - { "[386SX ISA] AMA-932J", "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device }, + { "[ISA] IBM PS/1 model 2121", "ibmps1_2121", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 2, 6, 1, 63, machine_ps1_m2121_init, NULL }, + { "[ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 2, 6, 1, 63, machine_ps1_m2121_init, NULL }, + { "[HT18] AMA-932J", "ama932j", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device }, #if defined(DEV_BRANCH) && defined(USE_AMI386SX) - { "[386SX ISA] AMI Unknown 386SX", "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, + { "[HT18] AMI Unknown 386SX", "ami386", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, #endif - { "[386SX ISA] Amstrad MegaPC", "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 32, 1, 127, machine_at_wd76c10_init, NULL }, - { "[386SX ISA] Commodore SL386SX", "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, - { "[386SX ISA] DTK 386SX clone", "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_neat_init, NULL }, - { "[386SX ISA] IBM PS/1 model 2121", "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 2, 6, 1, 63, machine_ps1_m2121_init, NULL }, - { "[386SX ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 2, 6, 1, 63, machine_ps1_m2121_init, NULL }, - { "[386SX ISA] KMX-C-02", "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_kmxc02_init, NULL }, - - { "[386SX ISA] Goldstar 386", "goldstar386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_goldstar386_init, NULL }, + { "[WD76C10] Amstrad MegaPC", "megapc", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 32, 1, 127, machine_at_wd76c10_init, NULL }, + { "[SCAMP] Commodore SL386SX", "cbm_sl386sx25", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127,machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, + { "[NEAT] DTK 386SX clone", "dtk386", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_neat_init, NULL }, + { "[NEAT] Goldstar 386", "goldstar386", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_goldstar386_init, NULL }, + { "[SCAT] KMX-C-02", "kmxc02", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_kmxc02_init, NULL }, /* 386SX machines which utilize the MCA bus */ - { "[386SX MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"IBM",cpus_IBM486SLC},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL }, + { "[MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"IBM",cpus_IBM486SLC},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL }, /* 386DX machines */ - { "[386DX ISA] Compaq Portable III (386)", "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_portableiii386_init, at_cpqiii_get_device }, - { "[386DX ISA] AMI 386DX clone", "acc386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 16384, 128, 127, machine_at_acc386_init, NULL }, - { "[386DX ISA] ASUS 386DX ISA", "asus386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 16384, 128, 127, machine_at_asus386_init, NULL }, - { "[386DX ISA] ECS 386/32", "ecs386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 1, 32, 1, 127, machine_at_ecs386_init, NULL }, - { "[386DX ISA] Micronics 386 clone", "micronics386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_micronics386_init, NULL }, + { "[ACC 2168] AMI 386DX clone", "acc386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 16384, 128, 127, machine_at_acc386_init, NULL }, + { "[SiS Rabbit] ASUS ISA-386C", "asus386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 16384, 128, 127, machine_at_asus386_init, NULL }, + { "[ISA] Compaq Portable III (386)", "portableiii386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_portableiii386_init, at_cpqiii_get_device }, + { "[ISA] Micronics 386 clone", "micronics386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_micronics386_init, NULL }, + { "[C&T 386] ECS 386/32", "ecs386", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 1, 16, 1, 127, machine_at_ecs386_init, NULL }, /* 386DX machines which utilize the VLB bus */ - { "[386DX VLB] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, - { "[386DX VLB] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX VLB] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, + { "[OPTi 495] Award 386DX clone", "award386dx", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, + { "[OPTi 495] Dataexpert SX495 (386DX)", "ami386dx", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, + { "[OPTi 495] MR 386DX clone", "mr386dx", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, /* 386DX machines which utilize the MCA bus */ - { "[386DX MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL }, - { "[386DX MCA] IBM PS/2 model 80", "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 12, 1, 63, machine_ps2_model_80_init, NULL }, + { "[MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL }, + { "[MCA] IBM PS/2 model 80", "ibmps2_m80", MACHINE_TYPE_386DX, {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 12, 1, 63, machine_ps2_model_80_init, NULL }, /* 486 machines with just the ISA slot */ - { "[486 ISA] Packard Bell PB410A", "pb410a", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL }, + { "[ACC 2168] Packard Bell PB410A", "pb410a", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL }, /* 486 machines */ - { "[486 VLB] Award 486 clone", "award486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, - { "[486 VLB] Dataexpert SX495 (486)", "ami486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[486 VLB] Olystar LIL1429", "ali1429", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_PS1M2133) - { "[486 VLB] IBM PS/1 model 2133", "ibmps1_2133", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_NONMI, 1, 64, 1, 127, machine_ps1_m2133_init, NULL }, -#endif - { "[486 VLB] AMI SiS 471", "ami471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL }, - { "[486 VLB] AMI WinBIOS 486", "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL }, + { "[OPTi 495] Award 486 clone", "award486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, + { "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, + { "[OPTi 495] Dataexpert SX495 (486)", "ami486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, + { "[SiS 471] ASUS VL/I-486SV2G (GX4)", "vli486sv2g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_vli486sv2g_init, NULL }, + { "[SiS 471] AMI 486 Clone", "ami471", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_WIN471) - { "[486 VLB] AMI WinBIOS SiS 471", "win471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_win471_init, NULL }, + { "[SiS 471] AMI WinBIOS 486 clone", "win471", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_win471_init, NULL }, +#endif + { "[SiS 471] DTK PKM-0038S E-2", "dtk486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_dtk486_init, NULL }, + { "[SiS 471] Phoenix SiS 471", "px471", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_px471_init, NULL }, + { "[ALi M1429G] Acer A1G", "acera1g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO | MACHINE_PS2, 4, 36, 1, 127, machine_at_acera1g_init, at_acera1g_get_device }, + { "[ALi M1429] Olystar LIL1429", "ali1429", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL }, + { "[ALi M1429] AMI WinBIOS 486", "win486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL }, +#if defined(DEV_BRANCH) && defined(USE_PS1M2133) + { "[VLB] IBM PS/1 model 2133", "ibmps1_2133", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_NONMI, 1, 64, 1, 127, machine_ps1_m2133_init, NULL }, #endif - { "[486 VLB] DTK PKM-0038S E-2", "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_dtk486_init, NULL }, - - { "[486 VLB] MR 486 clone", "mr486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, - { "[486 VLB] Phoenix SiS 471", "px471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_px471_init, NULL }, + /* 486 machines with utilize the MCA bus */ #if defined(DEV_BRANCH) && defined(USE_PS2M70T4) - { "[486 MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL }, + { "[MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL }, #endif /* 486 machines which utilize the PCI bus */ -#if defined(DEV_BRANCH) && defined(NO_SIO) - { "[486 PCI] ASUS PCI/I-486SP3G", "486sp3g", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486sp3g_init, NULL }, -#endif - { "[486 PCI] Intel Classic/PCI", "alfredo", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL }, - { "[486 PCI] Lucky Star LS-486E", "ls486e", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_ls486e_init, NULL }, - { "[486 PCI] Rise Computer R418", "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, - { "[486 PCI] Zida Tomato 4DP", "4dps", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL }, + { "[i420EX] ASUS PVI-486AP4", "486ap4", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486ap4_init, NULL }, + { "[i420ZX] ASUS PCI/I-486SP3G", "486sp3g", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486sp3g_init, NULL }, + { "[i420TX] Intel Classic/PCI", "alfredo", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL }, + { "[SiS 496] Lucky Star LS-486E", "ls486e", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_ls486e_init, NULL }, + { "[SiS 496] Rise Computer R418", "r418", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, + { "[SiS 496] Zida Tomato 4DP", "4dps", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL }, /* Socket 4 machines */ /* OPTi 596/597 */ - { "[Socket 4 OPTi] AMI Excalibur VLB", "excalibur", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_excalibur_init, NULL }, + { "[OPTi Python] AMI Excalibur VLB", "excalibur", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_excalibur_init, NULL }, /* 430LX */ - { "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, + { "[i430LX] IBM Ambra DP60 PCI", "ambradp60", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_VPP60) - { "[Socket 4 LX] IBM PS/ValuePoint P60", "valuepointp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL }, + { "[i430LX] IBM PS/ValuePoint P60", "valuepointp60", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL }, #endif - { "[Socket 4 LX] Intel Premiere/PCI", "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, - { "[Socket 4 LX] Micro Star 586MC1", "586mc1", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, + { "[i430LX] Intel Premiere/PCI", "revenge", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, + { "[i430LX] Micro Star 586MC1", "586mc1", MACHINE_TYPE_SOCKET4, {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, /* Socket 5 machines */ /* 430NX */ - { "[Socket 5 NX] Intel Premiere/PCI II", "plato", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, - { "[Socket 5 NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL }, - { "[Socket 5 NX] Gigabyte GA-586IP", "430nx", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL }, + { "[i430NX] Intel Premiere/PCI II", "plato", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, + { "[i430NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL }, + { "[i430NX] Gigabyte GA-586IP", "430nx", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL }, /* 430FX */ + { "[i430FX] Acer V30", "acerv30", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_acerv30_init, NULL }, + { "[i430FX] Gateway 2000 Zappa", "gw2kzp", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_gw2kzp_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_VECTRA54) - { "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 511, machine_at_vectra54_init, NULL }, + { "[i430FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 8, 128, 8, 511, machine_at_vectra54_init, NULL }, #endif - { "[Socket 5 FX] Intel Advanced/ZP", "zappa", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, - { "[Socket 5 FX] NEC PowerMate V", "powermate_v", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_powermate_v_init, NULL }, - { "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, + { "[i430FX] Intel Advanced/ZP", "zappa", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, + { "[i430FX] NEC PowerMate V", "powermate_v", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_powermate_v_init, NULL }, + { "[i430FX] PC Partner MB500N", "mb500n", MACHINE_TYPE_SOCKET5, MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, /* Socket 7 machines */ /* 430FX */ - { "[Socket 7-3V FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, - { "[Socket 7-3V FX] QDI Chariot", "chariot", MACHINE_CPUS_PENTIUM_S73VCH, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_chariot_init, NULL }, - { "[Socket 7-3V FX] MR 430FX clone", "mr586", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 8, 128, 8, 127, machine_at_mr586_init, NULL }, - { "[Socket 7-3V FX] Intel Advanced/ATX", "thor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, - { "[Socket 7-3V FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, - { "[Socket 7-3V FX] MR Intel Advanced/ATX", "mrthor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, - { "[Socket 7-3V FX] Packard Bell PB640", "pb640", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, + { "[i430FX-3V] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, + { "[i430FX-3V] Gateway 2000 Thor", "gw2katx", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_gw2katx_init, NULL }, + { "[i430FX-3V] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, + { "[i430FX-3V] Intel Advanced/EV", "endeavor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, + { "[i430FX-3V] MR 430FX clone", "mr586", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 8, 128, 8, 127, machine_at_mr586_init, NULL }, + { "[i430FX-3V] MR Intel Advanced/ATX", "mrthor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, + { "[i430FX-3V] Packard Bell PB640", "pb640", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, + { "[i430FX-3V] QDI Chariot", "chariot", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73VCH, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_chariot_init, NULL }, /* 430HX */ - { "[Socket 7-3V HX] Acer M3a", "acerm3a", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, - { "[Socket 7-3V HX] AOpen AP53", "ap53", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL }, - { "[Socket 7-3V HX] SuperMicro Super P55T2S","p55t2s", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, + { "[i430HX-3V] Acer M3a", "acerm3a", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, + { "[i430HX-3V] AOpen AP53", "ap53", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL }, + { "[i430HX-3V] SuperMicro Super P55T2S", "p55t2s", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, - { "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, - { "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, - { "[Socket 7 HX] Micronics M7S-Hi", "m7shi", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 511, machine_at_m7shi_init, NULL }, - { "[Socket 7 HX] Intel TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_tc430hx_init, NULL }, - { "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_equium5200_init, NULL }, - { "[Socket 7 HX] ASUS P/I-P65UP5 (C-P55T2D)","p65up5_cp55t2d", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p65up5_cp55t2d_init, NULL }, + { "[i430HX] Acer V35n", "acerv35n", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, + { "[i430HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, + { "[i430HX] Micronics M7S-Hi", "m7shi", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 511, machine_at_m7shi_init, NULL }, + { "[i430HX] Intel TC430HX", "tc430hx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_tc430hx_init, NULL }, + { "[i430HX] Toshiba Equium 5200D", "equium5200", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_equium5200_init, NULL }, + { "[i430HX] ASUS P/I-P65UP5 (C-P55T2D)", "p65up5_cp55t2d", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p65up5_cp55t2d_init, NULL }, /* 430VX */ - { "[Socket 7 VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, - { "[Socket 7 VX] Shuttle HOT-557", "430vx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, - { "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, - { "[Socket 7 VX] HP Brio 80xx", "brio80xx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_brio80xx_init, NULL }, - { "[Socket 7 VX] Biostar 8500TVX-A", "8500tvxa", {{ "Intel", cpus_Pentium}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_8500tvxa_init, NULL }, - { "[Socket 7 VX] Packard Bell PB680", "pb680", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_pb680_init, NULL }, + { "[i430VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, + { "[i430VX] Shuttle HOT-557", "430vx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, + { "[i430VX] Epox P55-VA", "p55va", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, + { "[i430VX] HP Brio 80xx", "brio80xx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_brio80xx_init, NULL }, + { "[i430VX] Biostar 8500TVX-A", "8500tvxa", MACHINE_TYPE_SOCKET7, {{ "Intel", cpus_Pentium}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_8500tvxa_init, NULL }, + { "[i430VX] Packard Bell PB680", "pb680", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_pb680_init, NULL }, /* 430TX */ - { "[Socket 7 TX] ADLink NuPRO-592", "nupro592", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_nupro592_init, NULL }, - { "[Socket 7 TX] ASUS TX97", "tx97", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_tx97_init, NULL }, - { "[Socket 7 TX] Intel YM430TX", "ym430tx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_ym430tx_init, NULL }, - { "[Socket 7 TX] PC Partner MB540N", "mb540n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_mb540n_init, NULL }, - { "[Socket 7 TX] Supermicro P5MMS98", "p5mms98", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p5mms98_init, NULL }, - + { "[i430TX] ADLink NuPRO-592", "nupro592", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_nupro592_init, NULL }, + { "[i430TX] ASUS TX97", "tx97", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_tx97_init, NULL }, + { "[i430TX] Intel YM430TX", "ym430tx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_ym430tx_init, NULL }, + { "[i430TX] PC Partner MB540N", "mb540n", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_mb540n_init, NULL }, + { "[i430TX] SuperMicro Super P5MMS98", "p5mms98", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p5mms98_init, NULL }, /* Apollo VPX */ - { "[Socket 7 VPX] FIC VA-502", "ficva502", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ficva502_init, NULL }, + { "[VIA VPX] FIC VA-502", "ficva502", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ficva502_init, NULL }, /* Apollo VP3 */ - { "[Socket 7 VP3] FIC PA-2012", "ficpa2012", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_ficpa2012_init, NULL }, + { "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_ficpa2012_init, NULL }, /* Super Socket 7 machines */ /* Apollo MVP3 */ - { "[Super 7 MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL }, - { "[Super 7 MVP3] FIC VA-503+", "ficva503p", MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, + { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL }, + { "[VIA MVP3] FIC VA-503+", "ficva503p", MACHINE_TYPE_SOCKETS7, MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, /* Socket 8 machines */ /* 440FX */ - { "[Socket 8 FX] Gigabyte GA-686NX", "686nx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_686nx_init, NULL }, - { "[Socket 8 FX] PC Partner MB600N", "mb600n", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_mb600n_init, NULL }, - { "[Socket 8 FX] Biostar MB-8500ttc", "8500ttc", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_8500ttc_init, NULL }, - { "[Socket 8 FX] Micronics M6MI", "m6mi", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 384, 8, 127, machine_at_m6mi_init, NULL }, - { "[Socket 8 FX] ASUS P/I-P65UP5 (C-P6ND)", "p65up5_cp6nd", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p65up5_cp6nd_init, NULL }, - + { "[i440FX] ASUS P/I-P65UP5 (C-P6ND)", "p65up5_cp6nd", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_p65up5_cp6nd_init, NULL }, + { "[i440FX] Biostar MB-8500ttc", "8500ttc", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_8500ttc_init, NULL }, + { "[i440FX] Gateway 2000 Venus", "gw2kvs", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_gw2kvs_init, NULL }, + { "[i440FX] Gigabyte GA-686NX", "686nx", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_686nx_init, NULL }, + { "[i440FX] Acer V60N", "v60n", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_v60n_init, NULL }, + { "[i440FX] Intel AP440FX", "ap440fx", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_ap440fx_init, NULL }, + { "[i440FX] Intel Venus", "vs440fx", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_vs440fx_init, NULL }, + { "[i440FX] Micronics M6MI", "m6mi", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_m6mi_init, NULL }, + { "[i440FX] PC Partner MB600N", "mb600n", MACHINE_TYPE_SOCKET8, {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_mb600n_init, NULL }, /* Slot 1 machines */ /* 440FX */ - { "[Slot 1 FX] ASUS P/I-P65UP5 (C-PKND)", "p65up5_cpknd", {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p65up5_cpknd_init, NULL }, - { "[Slot 1 FX] ASUS KN97", "kn97", {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 384, 8, 127, machine_at_kn97_init, NULL }, + { "[i440FX] ASUS P/I-P65UP5 (C-PKND)", "p65up5_cpknd", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_p65up5_cpknd_init, NULL }, + { "[i440FX] ASUS KN97", "kn97", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_kn97_init, NULL }, + + /* 440LX */ + { "[i440LX] Abit LX6", "lx6", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_lx6_init, NULL }, /* 440EX */ - { "[Slot 1 EX] QDI EXCELLENT II", "p6i440e2", {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_p6i440e2_init, NULL }, + { "[i440EX] QDI EXCELLENT II", "p6i440e2", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII66}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_p6i440e2_init, NULL }, /* 440BX */ - { "[Slot 1 BX] ASUS P2B-LS", "p2bls", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p2bls_init, NULL }, - { "[Slot 1 BX] ASUS P2B-LS (coreboot BIOS)","p2bls_cb", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"", NULL}, {"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_COREBOOT, 8, 1024, 8, 255, machine_at_p2bls_init, NULL }, - { "[Slot 1 BX] ASUS P3B-F", "p3bf", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p3bf_init, NULL }, - { "[Slot 1 BX] ASUS P3B-F (coreboot BIOS)", "p3bf_cb", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"", NULL}, {"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_COREBOOT, 8, 1024, 8, 255, machine_at_p3bf_init, NULL }, - { "[Slot 1 BX] ABit BF6", "bf6", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_bf6_init, NULL }, - { "[Slot 1 BX] A-Trend ATC6310BXII", "atc6310bxii", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_atc6310bxii_init, NULL }, -#if defined(DEV_BRANCH) && defined(NO_SIO) - { "[Slot 1 BX] Tyan Tsunami ATX", "tsunamiatx", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_SOUND, 8, 1024, 8, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device }, -#endif - { "[Slot 1 BX] Supermicro P6SBA", "p6sba", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_p6sba_init, NULL }, + { "[i440BX] ASUS P2B-LS", "p2bls", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p2bls_init, NULL }, + { "[i440BX] ASUS P3B-F", "p3bf", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p3bf_init, NULL }, + { "[i440BX] ABit BF6", "bf6", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_bf6_init, NULL }, + { "[i440BX] AOpen AX6BC", "ax6bc", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_ax6bc_init, NULL }, + { "[i440BX] A-Trend ATC6310BXII", "atc6310bxii", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_atc6310bxii_init, NULL }, + { "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"", NULL},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_SOUND, 8, 1024, 8, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device }, + { "[i440BX] Supermicro P6SBA", "p6sba", MACHINE_TYPE_SLOT1, {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"", NULL},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_p6sba_init, NULL }, - /* Slot 2 machines */ + /* Slot 2 machines(Including Slot 1/2 Hybrids) */ /* 440GX */ -#if defined(DEV_BRANCH) && defined(NO_SIO) - { "[Slot 2 GX] Supermicro S2DGE", "s2dge", {{"Intel", cpus_Xeon}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_s2dge_init, NULL }, -#endif + { "[i440GX] Gigabyte GA-6GXU", "6gxu", MACHINE_TYPE_SLOT2, {{"Intel", cpus_Xeon}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 16, 2048, 16, 511, machine_at_6gxu_init, NULL }, + { "[i440GX] SuperMicro Super S2DGE", "s2dge", MACHINE_TYPE_SLOT2, {{"Intel", cpus_Xeon}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 16, 2048, 16, 511, machine_at_s2dge_init, NULL }, /* PGA370 machines */ /* 440LX */ - { "[Socket 370 LX] Supermicro 370SLM", "s370slm", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_s370slm_init, NULL }, + { "[i440LX] SuperMicro Super 370SLM", "s370slm", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_s370slm_init, NULL }, /* 440BX */ - { "[Socket 370 BX] ASUS CUBX", "cubx", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_cubx_init, NULL }, - { "[Socket 370 BX] A-Trend ATC7020BXII", "atc7020bxii", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_atc7020bxii_init, NULL }, + { "[i440BX] ASUS CUBX", "cubx", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_cubx_init, NULL }, + { "[i440BX] A-Trend ATC7020BXII", "atc7020bxii", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_atc7020bxii_init, NULL }, /* 440ZX */ - { "[Socket 370 ZX] Soltek SL-63A1", "63a", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_63a_init, NULL }, + { "[i440ZX] Soltek SL-63A1", "63a", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_63a_init, NULL }, /* VIA Apollo Pro */ - { "[Socket 370 APRO] PC Partner APAS3", "apas3", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_apas3_init, NULL }, + { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_apas3_init, NULL }, - { NULL, NULL, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL } + { NULL, NULL, MACHINE_TYPE_NONE, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL } }; diff --git a/src/intel_flash.c b/src/mem/intel_flash.c similarity index 100% rename from src/intel_flash.c rename to src/mem/intel_flash.c diff --git a/src/mem.c b/src/mem/mem.c similarity index 84% rename from src/mem.c rename to src/mem/mem.c index d9c1256e8..091a07770 100644 --- a/src/mem.c +++ b/src/mem/mem.c @@ -22,6 +22,7 @@ * Copyright 2016-2020 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. */ +#include #include #include #include @@ -51,6 +52,10 @@ #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 FIXME 0 @@ -64,8 +69,10 @@ mem_mapping_t base_mapping, #endif ram_remapped_mapping, /* 640..1024K mapping */ ram_high_mapping, /* 1024K+ mapping */ + ram_2gb_mapping, /* 1024M+ mapping */ ram_remapped_mapping, ram_split_mapping, + ram_smram_mapping[2], bios_mapping, bios_high_mapping; @@ -73,7 +80,7 @@ page_t *pages, /* RAM page table */ **page_lookup; /* pagetable lookup */ uint32_t pages_sz; /* #pages in table */ -uint8_t *ram; /* the virtual RAM */ +uint8_t *ram, *ram2; /* the virtual RAM */ uint32_t rammask; uint8_t *rom; /* the virtual ROM */ @@ -102,6 +109,8 @@ int cachesize = 256; uint32_t get_phys_virt, get_phys_phys; +smram_t smram[2] = { { 0x000a0000, 0x000a0000 }, { 0x000a0000, 0x000a0000 } }; + int mem_a20_key = 0, mem_a20_alt = 0, mem_a20_state = 0; @@ -122,7 +131,7 @@ int use_phys_exec = 0; static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; -static int _mem_state[MEM_MAPPINGS_NO]; +static uint32_t _mem_state[MEM_MAPPINGS_NO]; static uint8_t *mtrr_areas[MEM_MAPPINGS_NO]; static uint8_t mtrr_area_refcounts[MEM_MAPPINGS_NO]; @@ -274,10 +283,17 @@ mem_flush_write_page(uint32_t addr, uint32_t virt) { page_t *page_target = &pages[addr >> 12]; int c; + uint32_t a; for (c = 0; c < 256; c++) { if (writelookup[c] != (int) 0xffffffff) { - uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)]; + a = (uintptr_t)(addr & ~0xfff) - (virt & ~0xfff); + uintptr_t target; + + if ((addr & ~0xfff) >= (1 << 30)) + target = (uintptr_t)&ram2[a - (1 << 30)]; + else + target = (uintptr_t)&ram[a]; if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { writelookup2[writelookup[c]] = -1; @@ -564,6 +580,8 @@ mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len) void addreadlookup(uint32_t virt, uint32_t phys) { + uint32_t a; + if (virt == 0xffffffff) return; if (readlookup2[virt>>12] != (uintptr_t) -1) return; @@ -571,7 +589,12 @@ addreadlookup(uint32_t virt, uint32_t phys) if (readlookup[readlnext] != (int) 0xffffffff) readlookup2[readlookup[readlnext]] = -1; - readlookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; + a = (uintptr_t)(phys & ~0xfff) - (uintptr_t)(virt & ~0xfff); + + if ((phys & ~0xfff) >= (1 << 30)) + readlookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)]; + else + readlookup2[virt>>12] = (uintptr_t)&ram[a]; readlookupp[readlnext] = mmu_perm; readlookup[readlnext++] = virt >> 12; @@ -584,6 +607,8 @@ addreadlookup(uint32_t virt, uint32_t phys) void addwritelookup(uint32_t virt, uint32_t phys) { + uint32_t a; + if (virt == 0xffffffff) return; if (page_lookup[virt >> 12]) return; @@ -594,7 +619,11 @@ addwritelookup(uint32_t virt, uint32_t phys) } #ifdef USE_NEW_DYNAREC +#ifdef USE_DYNAREC if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) +#else + if (pages[phys >> 12].block) +#endif #else #ifdef USE_DYNAREC if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) @@ -603,8 +632,14 @@ addwritelookup(uint32_t virt, uint32_t phys) #endif #endif page_lookup[virt >> 12] = &pages[phys >> 12]; - else - writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; + else { + a = (uintptr_t)(phys & ~0xfff) - (uintptr_t)(virt & ~0xfff); + + if ((phys & ~0xfff) >= (1 << 30)) + writelookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)]; + else + writelookup2[virt>>12] = (uintptr_t)&ram[a]; + } writelookupp[writelnext] = mmu_perm; writelookup[writelnext++] = virt >> 12; @@ -1702,6 +1737,87 @@ mem_read_raml(uint32_t addr, void *priv) } +uint8_t +mem_read_ram_2gb(uint32_t addr, void *priv) +{ +#ifdef ENABLE_MEM_LOG + if ((addr >= 0xa0000) && (addr <= 0xbffff)) + mem_log("Read B %02X from %08X\n", ram[addr], addr); +#endif + + addreadlookup(mem_logical_addr, addr); + + return ram2[addr - (1 << 30)]; +} + + +uint16_t +mem_read_ram_2gbw(uint32_t addr, void *priv) +{ +#ifdef ENABLE_MEM_LOG + if ((addr >= 0xa0000) && (addr <= 0xbffff)) + mem_log("Read W %04X from %08X\n", *(uint16_t *)&ram[addr], addr); +#endif + + addreadlookup(mem_logical_addr, addr); + + return *(uint16_t *)&ram2[addr - (1 << 30)]; +} + + +uint32_t +mem_read_ram_2gbl(uint32_t addr, void *priv) +{ +#ifdef ENABLE_MEM_LOG + if ((addr >= 0xa0000) && (addr <= 0xbffff)) + mem_log("Read L %08X from %08X\n", *(uint32_t *)&ram[addr], addr); +#endif + + addreadlookup(mem_logical_addr, addr); + + return *(uint32_t *)&ram2[addr - (1 << 30)]; +} + + +uint8_t +mem_read_smram(uint32_t addr, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + if (new_addr >= (1 << 30)) + return mem_read_ram_2gb(new_addr, priv); + else + return mem_read_ram(new_addr, priv); +} + + +uint16_t +mem_read_smramw(uint32_t addr, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + if (new_addr >= (1 << 30)) + return mem_read_ram_2gbw(new_addr, priv); + else + return mem_read_ramw(new_addr, priv); +} + + +uint32_t +mem_read_smraml(uint32_t addr, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + if (new_addr >= (1 << 30)) + return mem_read_ram_2gbl(new_addr, priv); + else + return mem_read_raml(new_addr, priv); +} + + #ifdef USE_NEW_DYNAREC static inline int page_index(page_t *p) @@ -1740,7 +1856,11 @@ page_remove_from_evict_list(page_t *p) void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) { +#ifdef USE_DYNAREC if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != p->mem[addr & 0xfff]) { +#endif uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); @@ -1759,7 +1879,11 @@ mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) { +#ifdef USE_DYNAREC if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != *(uint16_t *)&p->mem[addr & 0xfff]) { +#endif uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); @@ -1788,7 +1912,11 @@ mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) { +#ifdef USE_DYNAREC if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != *(uint32_t *)&p->mem[addr & 0xfff]) { +#endif uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); @@ -1896,6 +2024,36 @@ mem_write_raml(uint32_t addr, uint32_t val, void *priv) } +void +mem_write_smram(uint32_t addr, uint8_t val, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + mem_write_ram(new_addr, val, priv); +} + + +void +mem_write_smramw(uint32_t addr, uint16_t val, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + mem_write_ramw(new_addr, val, priv); +} + + +void +mem_write_smraml(uint32_t addr, uint32_t val, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + mem_write_raml(new_addr, val, priv); +} + + static uint8_t mem_read_remapped(uint32_t addr, void *priv) { @@ -2060,84 +2218,107 @@ mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) static __inline int -mem_mapping_read_allowed(uint32_t flags, int state, int exec) +mem_mapping_read_allowed(uint32_t flags, uint32_t state, int exec) { - int smm_state = state >> MEM_STATE_SMM_SHIFT; + uint32_t smm_state = state >> MEM_STATE_SMM_SHIFT; + uint32_t state_masked; + int ret = 0; if (in_smm && ((smm_state & MEM_READ_MASK) != MEM_READ_NORMAL)) state = smm_state; - switch (state & MEM_READ_MASK) { - case MEM_READ_DISABLED: - return 0; + state_masked = (state & MEM_READ_MASK); + if (state_masked & MEM_READ_SMRAM) + ret = (flags & MEM_MAPPING_SMRAM); + else if ((state_masked & MEM_READ_SMRAM_EX) && exec) + ret = (flags & MEM_MAPPING_SMRAM); + else if (!(state_masked & MEM_READ_DISABLED_EX)) switch (state_masked) { case MEM_READ_ANY: - return 1; + ret = !(flags & MEM_MAPPING_SMRAM); + break; /* On external and 0 mappings without ROMCS. */ case MEM_READ_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM); + break; /* On external and 0 mappings with ROMCS. */ case MEM_READ_ROMCS: - return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + ret = !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM); + break; /* On any external mappings. */ case MEM_READ_EXTANY: - return !(flags & MEM_MAPPING_INTERNAL); + ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM); + break; case MEM_READ_EXTERNAL_EX: if (exec) - return !(flags & MEM_MAPPING_EXTERNAL); + ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); else - return !(flags & MEM_MAPPING_INTERNAL); + ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM); + break; case MEM_READ_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); + ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); + break; default: - fatal("mem_mapping_read_allowed : bad state %x\n", state); + if (state_masked != MEM_READ_DISABLED) + fatal("mem_mapping_read_allowed : bad state %x\n", state_masked); + break; } - return 0; + return ret; } static __inline int -mem_mapping_write_allowed(uint32_t flags, int state) +mem_mapping_write_allowed(uint32_t flags, uint32_t state) { - int smm_state = state >> MEM_STATE_SMM_SHIFT; + uint32_t smm_state = state >> MEM_STATE_SMM_SHIFT; + uint32_t state_masked; + int ret = 0; if (in_smm && ((smm_state & MEM_WRITE_MASK) != MEM_WRITE_NORMAL)) state = smm_state; - switch (state & MEM_WRITE_MASK) { - case MEM_WRITE_DISABLED: - return 0; + state_masked = (state & MEM_WRITE_MASK); + if (state_masked & MEM_WRITE_SMRAM) + ret = (flags & MEM_MAPPING_SMRAM); + else if (!(state_masked & MEM_WRITE_DISABLED_EX)) switch (state_masked) { case MEM_WRITE_ANY: - return 1; + ret = !(flags & MEM_MAPPING_SMRAM); + break; /* On external and 0 mappings without ROMCS. */ case MEM_WRITE_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM); + break; /* On external and 0 mappings with ROMCS. */ case MEM_WRITE_ROMCS: - return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + ret = !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM); + break; /* On any external mappings. */ case MEM_WRITE_EXTANY: - return !(flags & MEM_MAPPING_INTERNAL); + ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM); + break; case MEM_WRITE_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); + ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); + break; default: - fatal("mem_mapping_write_allowed : bad state %x\n", state); + if (state_masked != MEM_WRITE_DISABLED) + fatal("mem_mapping_write_allowed : bad state %x\n", state_masked); + break; } - return 0; + return ret; } @@ -2346,18 +2527,47 @@ mem_mapping_enable(mem_mapping_t *map) void -mem_set_mem_state_common(int smm, uint32_t base, uint32_t size, int state) +mem_set_state(int smm, int mode, uint32_t base, uint32_t size, uint32_t state) { - uint32_t c; + uint32_t c, mask_l, mask_h, smstate = 0x0000; + + if (mode) { + mask_l = 0xffff0f0f; + mask_h = 0x0f0fffff; + } else { + mask_l = 0xfffff0f0; + mask_h = 0xf0f0ffff; + } + + if (mode) { + if (mode == 1) + state = !!state; + + switch (state & 0x03) { + case 0x00: + smstate = 0x0000; + break; + case 0x01: + smstate = (MEM_READ_SMRAM | MEM_WRITE_SMRAM); + break; + case 0x02: + smstate = MEM_READ_SMRAM_EX; + break; + case 0x03: + smstate = (MEM_READ_DISABLED_EX | MEM_WRITE_DISABLED_EX); + break; + } + } else + smstate = state & 0x0f0f; for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { - if (smm) - _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0x00ff) | ((state & 0xff) << 8); - else - _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0xff00) | (state & 0xff); + if (smm != 0) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & mask_h) | (smstate << MEM_STATE_SMM_SHIFT); + if (smm != 1) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & mask_l) | smstate; #ifdef ENABLE_MEM_LOG if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff)) - mem_log("Set mem state for block at %08X to %02X\n", c + base, state); + mem_log("Set mem state for block at %08X to %02X\n", c + base, smstate); #endif } @@ -2365,20 +2575,6 @@ mem_set_mem_state_common(int smm, uint32_t base, uint32_t size, int state) } -void -mem_set_mem_state(uint32_t base, uint32_t size, int state) -{ - mem_set_mem_state_common(0, base, size, state); -} - - -void -mem_set_mem_state_smm(uint32_t base, uint32_t size, int state) -{ - mem_set_mem_state_common(1, base, size, state); -} - - void mem_add_bios(void) { @@ -2396,16 +2592,16 @@ mem_add_bios(void) mem_write_null,mem_write_nullw,mem_write_nulll, &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - mem_set_mem_state(0x0e0000, 0x20000, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); + mem_set_mem_state_both(0x0e0000, 0x20000, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); } else { mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, mem_read_bios,mem_read_biosw,mem_read_biosl, mem_write_null,mem_write_nullw,mem_write_nulll, rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - mem_set_mem_state(biosaddr, biosmask + 1, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); + mem_set_mem_state_both(biosaddr, biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); } if (AT) { @@ -2414,8 +2610,8 @@ mem_add_bios(void) mem_write_null,mem_write_nullw,mem_write_nulll, rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - mem_set_mem_state(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); + mem_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); } } @@ -2446,8 +2642,22 @@ mem_reset(void) free(ram); ram = NULL; } - ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ - memset(ram, 0x00, m); + if (ram2 != NULL) { + free(ram2); + ram2 = NULL; + } + if (mem_size > 2097152) + fatal("Attempting to use more than 2 GB of guest RAM\n"); + + if (mem_size > 1048576) { + ram = (uint8_t *)malloc(1 << 30); /* allocate and clear the RAM block of the first 1 GB */ + memset(ram, 0x00, 1 << 30); + ram2 = (uint8_t *)malloc(m - (1 << 30)); /* allocate and clear the RAM block above 1 GB */ + memset(ram2, 0x00, m - (1 << 30)); + } else { + ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ + memset(ram, 0x00, m); + } /* * Allocate the page table based on how much RAM we have. @@ -2549,7 +2759,13 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); #endif for (c = 0; c < pages_sz; c++) { - pages[c].mem = &ram[c << 12]; + if (mem_size > 1048576) { + if ((c << 12) < (1 << 30)) + pages[c].mem = &ram[c << 12]; + else + pages[c].mem = &ram2[(c << 12) - (1 << 30)]; + } else + pages[c].mem = &ram[c << 12]; if (c < m) { pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; @@ -2573,16 +2789,11 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); memset(&base_mapping, 0x00, sizeof(base_mapping)); memset(_mem_state, 0x00, sizeof(_mem_state)); - /* Set SMM states to (MEM_READ_NORMAL | MEM_WRITE_NORMAL). */ - for (c = 0; c < MEM_MAPPINGS_NO; c++) - _mem_state[c] |= 0x4400; - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - /* mem_set_mem_state(0x0c0000, 0x40000, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); */ - mem_set_mem_state(0x0a0000, 0x60000, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state_both(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(0x0a0000, 0x60000, + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, @@ -2592,43 +2803,70 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); if (mem_size > 1024) { if (cpu_16bitbus && mem_size > 16256) { - mem_set_mem_state(0x100000, (16256 - 1024) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(0x100000, (16256 - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_mapping_add(&ram_high_mapping, 0x100000, ((16256 - 1024) * 1024), mem_read_ram,mem_read_ramw,mem_read_raml, mem_write_ram,mem_write_ramw,mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); } else { - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, - ((mem_size - 1024) * 1024), - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + if (mem_size > 1048576) { + mem_set_mem_state_both(0x100000, (1048576 - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((1048576 - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + mem_set_mem_state_both((1 << 30), (mem_size - 1048576) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_2gb_mapping, (1 << 30), + ((mem_size - 1048576) * 1024), + mem_read_ram_2gb,mem_read_ram_2gbw,mem_read_ram_2gbl, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram2, MEM_MAPPING_INTERNAL, NULL); + } else { + mem_set_mem_state_both(0x100000, (mem_size - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((mem_size - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } } } - /* if (mem_size > 768) - mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); */ - if (mem_size > 768) + if (mem_size > 768) { mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000, mem_read_ram,mem_read_ramw,mem_read_raml, mem_write_ram,mem_write_ramw,mem_write_raml, ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); + } + + mem_mapping_add(&ram_smram_mapping[0], 0xa0000, 0x60000, + mem_read_smram,mem_read_smramw,mem_read_smraml, + mem_write_smram,mem_write_smramw,mem_write_smraml, + ram + 0xa0000, MEM_MAPPING_SMRAM, &(smram[0])); + mem_mapping_add(&ram_smram_mapping[1], 0xa0000, 0x60000, + mem_read_smram,mem_read_smramw,mem_read_smraml, + mem_write_smram,mem_write_smramw,mem_write_smraml, + ram + 0xa0000, MEM_MAPPING_SMRAM, &(smram[1])); + mem_mapping_disable(&ram_smram_mapping[0]); + mem_mapping_disable(&ram_smram_mapping[1]); mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, mem_read_remapped,mem_read_remappedw,mem_read_remappedl, mem_write_remapped,mem_write_remappedw,mem_write_remappedl, ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_remapped_mapping); + mem_mapping_disable(&ram_remapped_mapping); mem_a20_init(); + smram[0].host_base = smram[0].ram_base = smram[0].size = 0x00000000; + smram[1].host_base = smram[1].ram_base = smram[1].size = 0x00000000; + #ifdef USE_NEW_DYNAREC purgable_page_list_head = 0; purgeable_page_count = 0; @@ -2641,6 +2879,7 @@ mem_init(void) { /* Perform a one-time init. */ ram = rom = NULL; + ram2 = NULL; pages = NULL; #if DYNAMIC_TABLES page_lookup = NULL; @@ -2670,7 +2909,7 @@ mem_init(void) void mem_remap_top(int kb) { - int c; + uint32_t c; uint32_t start = (mem_size >= 1024) ? mem_size : 1024; int offset, size = mem_size - 640; @@ -2700,8 +2939,8 @@ mem_remap_top(int kb) #endif } - mem_set_mem_state(start * 1024, size * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(start * 1024, size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); @@ -2848,7 +3087,7 @@ mem_invalidate_mtrr(uint8_t wb) if (mtrr) { page_base = (page << MEM_GRANULARITY_BITS); if (!mem_addr_is_ram(page_base)) - continue; /* don't invalidate pages not backed by RAM */ + continue; /* don't invalidate pages not backed by RAM (hack?) */ /* temporarily set area aside */ mtrr_areas[page] = 0; diff --git a/src/rom.c b/src/mem/rom.c similarity index 96% rename from src/rom.c rename to src/mem/rom.c index f8c4586ce..d05f69ae5 100644 --- a/src/rom.c +++ b/src/mem/rom.c @@ -382,11 +382,11 @@ bios_load_linear_combined2(wchar_t *fn1, wchar_t *fn2, wchar_t *fn3, wchar_t *fn { uint8_t ret = 0; - ret = bios_load_linear(fn3, 0x000f0000, 262144, 128); - ret &= bios_load_aux_linear(fn1, 0x000d0000, 65536, 128); - ret &= bios_load_aux_linear(fn2, 0x000c0000, 65536, 128); - ret &= bios_load_aux_linear(fn4, 0x000e0000, sz - 196608, 128); - ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, 128); + ret = bios_load_linear(fn3, 0x000f0000, 262144, off); + ret &= bios_load_aux_linear(fn1, 0x000d0000, 65536, off); + ret &= bios_load_aux_linear(fn2, 0x000c0000, 65536, off); + ret &= bios_load_aux_linear(fn4, 0x000e0000, sz - 196608, off); + ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, off); return ret; } diff --git a/src/spd.c b/src/mem/spd.c similarity index 100% rename from src/spd.c rename to src/mem/spd.c diff --git a/src/sst_flash.c b/src/mem/sst_flash.c similarity index 95% rename from src/sst_flash.c rename to src/mem/sst_flash.c index 468d5d48a..6acd4440b 100644 --- a/src/sst_flash.c +++ b/src/mem/sst_flash.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 an SST flash chip. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * Melissa Goad, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2020 Melissa Goad. - */ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/machine.h> -#include <86box/timer.h> -#include <86box/nvr.h> -#include <86box/plat.h> - - -typedef struct sst_t -{ - uint8_t id, is_39, page_bytes, sdp; - - int command_state, id_mode, - dirty; - - uint32_t size, mask, - page_mask, page_base; - - uint8_t page_buffer[128]; - uint8_t *array; - - mem_mapping_t mapping[8], mapping_h[8]; - - pc_timer_t page_write_timer; -} sst_t; - - -static wchar_t flash_path[1024]; - - -#define SST_CHIP_ERASE 0x10 /* Both 29 and 39, 6th cycle */ -#define SST_SDP_DISABLE 0x20 /* Only 29, Software data protect disable and write - treat as write */ -#define SST_SECTOR_ERASE 0x30 /* Only 39, 6th cycle */ -#define SST_SET_ID_MODE_ALT 0x60 /* Only 29, 6th cycle */ -#define SST_ERASE 0x80 /* Both 29 and 39 */ - /* With data 60h on 6th cycle, it's alt. ID */ -#define SST_SET_ID_MODE 0x90 /* Both 29 and 39 */ -#define SST_BYTE_PROGRAM 0xa0 /* Both 29 and 39 */ -#define SST_CLEAR_ID_MODE 0xf0 /* Both 29 and 39 */ - /* 1st cycle variant only on 39 */ - -#define SST_ID_MANUFACTURER 0xbf /* SST Manufacturer's ID */ -#define SST_ID_SST29EE010 0x07 -#define SST_ID_SST29LE_VE010 0x08 -#define SST_ID_SST29EE020 0x10 -#define SST_ID_SST29LE_VE020 0x12 -#define SST_ID_SST39SF512 0xb4 -#define SST_ID_SST39SF010 0xb5 -#define SST_ID_SST39SF020 0xb6 -#define SST_ID_SST39SF040 0xb7 - - -static void -sst_sector_erase(sst_t *dev, uint32_t addr) -{ - memset(&dev->array[addr & (dev->mask & ~0xfff)], 0xff, 4096); - dev->dirty = 1; -} - - -static void -sst_new_command(sst_t *dev, uint32_t addr, uint8_t val) -{ - if (dev->command_state == 5) switch (val) { - case SST_CHIP_ERASE: - memset(dev->array, 0xff, 0x20000); - dev->command_state = 0; - break; - - case SST_SDP_DISABLE: - if (!dev->is_39) - dev->sdp = 0; - dev->command_state = 0; - break; - - case SST_SECTOR_ERASE: - if (dev->is_39) - sst_sector_erase(dev, addr); - dev->command_state = 0; - break; - - case SST_SET_ID_MODE_ALT: - dev->id_mode = 1; - dev->command_state = 0; - break; - - default: - dev->command_state = 0; - break; - } else switch (val) { - case SST_ERASE: - dev->command_state = 3; - break; - - case SST_SET_ID_MODE: - dev->id_mode = 1; - dev->command_state = 0; - break; - - case SST_BYTE_PROGRAM: - if (!dev->is_39) { - memset(dev->page_buffer, 0xff, 128); - dev->page_bytes = 0; - timer_on_auto(&dev->page_write_timer, 210.0); - } - dev->command_state = 6; - break; - - case SST_CLEAR_ID_MODE: - dev->id_mode = 0; - dev->command_state = 0; - break; - - default: - dev->command_state = 0; - break; - } -} - - -static void -sst_page_write(void *priv) -{ - sst_t *dev = (sst_t *) priv; - - memcpy(&(dev->array[dev->page_base]), dev->page_buffer, 128); - dev->dirty = 1; - dev->page_bytes = 0; - dev->command_state = 0; -} - - -static uint8_t -sst_read_id(uint32_t addr, void *p) -{ - sst_t *dev = (sst_t *) p; - - if ((addr & 0xffff) == 0) - return SST_ID_MANUFACTURER; /* SST */ - else if ((addr & 0xffff) == 1) - return dev->id; - else - return 0xff; -} - - -static void -sst_buf_write(sst_t *dev, uint32_t addr, uint8_t val) -{ - dev->page_buffer[addr & 0x0000007f] = val; - timer_disable(&dev->page_write_timer); - dev->page_bytes++; - if (dev->page_bytes >= 128) - sst_page_write(dev); - else - timer_set_delay_u64(&dev->page_write_timer, 210 * TIMER_USEC); -} - - -static void -sst_write(uint32_t addr, uint8_t val, void *p) -{ - sst_t *dev = (sst_t *) p; - - switch (dev->command_state) { - case 0: - case 3: - /* 1st and 4th Bus Write Cycle */ - if ((val == 0xf0) && dev->is_39 && (dev->command_state == 0)) { - if (dev->id_mode) - dev->id_mode = 0; - dev->command_state = 0; - } else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa)) - dev->command_state++; - else { - if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) { - /* 29 series, software data protection off, start loading the page. */ - dev->page_base = addr & dev->page_mask; /* First byte, A7 onwards of its address are the page mask. */ - dev->command_state = 7; - sst_buf_write(dev, addr, val); - } - dev->command_state = 0; - } - break; - case 1: - case 4: - /* 2nd and 5th Bus Write Cycle */ - if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55)) - dev->command_state++; - else - dev->command_state = 0; - break; - case 2: - case 5: - /* 3rd and 6th Bus Write Cycle */ - if ((addr & 0x7fff) == 0x5555) - sst_new_command(dev, addr, val); - else - dev->command_state = 0; - break; - case 6: - /* Page Load Cycle (29) / Data Write Cycle (39SF) */ - if (dev->is_39) { - dev->array[addr & dev->mask] = val; - dev->command_state = 0; - dev->dirty = 1; - } else { - dev->page_base = addr & dev->page_mask; /* First byte, A7 onwards of its address are the page mask. */ - dev->command_state++; - sst_buf_write(dev, addr, val); - } - break; - case 7: - if (!dev->is_39 && ((addr & dev->page_mask) == dev->page_base)) - sst_buf_write(dev, addr, val); - break; - } -} - - -static uint8_t -sst_read(uint32_t addr, void *p) -{ - sst_t *dev = (sst_t *) p; - uint8_t ret = 0xff; - - addr &= 0x000fffff; - - if (dev->id_mode) - ret = sst_read_id(addr, p); - else { - if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) - ret = dev->array[addr - biosaddr]; - } - - return ret; -} - - -static uint16_t -sst_readw(uint32_t addr, void *p) -{ - sst_t *dev = (sst_t *) p; - uint16_t ret = 0xffff; - - addr &= 0x000fffff; - - if (dev->id_mode) - ret = sst_read(addr, p) | (sst_read(addr + 1, p) << 8); - else { - if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) - ret = *(uint16_t *)&dev->array[addr - biosaddr]; - } - - return ret; -} - - -static uint32_t -sst_readl(uint32_t addr, void *p) -{ - sst_t *dev = (sst_t *) p; - uint32_t ret = 0xffffffff; - - addr &= 0x000fffff; - - if (dev->id_mode) - ret = sst_readw(addr, p) | (sst_readw(addr + 2, p) << 16); - else { - if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) - ret = *(uint32_t *)&dev->array[addr - biosaddr]; - } - - return ret; -} - - -static void -sst_add_mappings(sst_t *dev) -{ - int i = 0, count; - uint32_t base, fbase; - uint32_t root_base; - - count = dev->size >> 16; - root_base = 0x100000 - dev->size; - - for (i = 0; i < count; i++) { - base = root_base + (i << 16); - fbase = base & biosmask; - - memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000); - - if (base >= 0xe0000) { - mem_mapping_add(&(dev->mapping[i]), base, 0x10000, - sst_read, sst_readw, sst_readl, - sst_write, NULL, NULL, - dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); - } - mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000), 0x10000, - sst_read, sst_readw, sst_readl, - sst_write, NULL, NULL, - dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); - } -} - - -static void * -sst_init(const device_t *info) -{ - FILE *f; - sst_t *dev = malloc(sizeof(sst_t)); - memset(dev, 0, sizeof(sst_t)); - - size_t l = strlen(machine_get_internal_name_ex(machine))+1; - wchar_t *machine_name = (wchar_t *) malloc(l * sizeof(wchar_t)); - mbstowcs(machine_name, machine_get_internal_name_ex(machine), l); - l = wcslen(machine_name)+5; - wchar_t *flash_name = (wchar_t *)malloc(l*sizeof(wchar_t)); - swprintf(flash_name, l, L"%ls.bin", machine_name); - - if (wcslen(flash_name) <= 1024) - wcscpy(flash_path, flash_name); - else - wcsncpy(flash_path, flash_name, 1024); - - mem_mapping_disable(&bios_mapping); - mem_mapping_disable(&bios_high_mapping); - - dev->array = (uint8_t *) malloc(biosmask + 1); - memset(dev->array, 0xff, biosmask + 1); - - dev->id = info->local; - dev->is_39 = (dev->id >= SST_ID_SST39SF512); - - if (dev->id == SST_ID_SST39SF512) - dev->size = 0x10000; - else if ((dev->id == SST_ID_SST29EE020) || (dev->id == SST_ID_SST29LE_VE020) || (dev->id == SST_ID_SST39SF020)) - dev->size = 0x40000; - else if (dev->id == SST_ID_SST39SF040) - dev->size = 0x80000; - else - dev->size = 0x20000; - dev->mask = dev->size - 1; - dev->page_mask = dev->mask & 0xffffff80; /* Filter out A0-A6. */ - dev->sdp = 1; - - sst_add_mappings(dev); - - f = nvr_fopen(flash_path, L"rb"); - if (f) { - if (fread(&(dev->array[0x00000]), 1, dev->size, f) != dev->size) - fatal("Less than %i bytes read from the SST Flash ROM file\n", dev->size); - fclose(f); - } else - dev->dirty = 1; /* It is by definition dirty on creation. */ - - free(flash_name); - free(machine_name); - - if (!dev->is_39) - timer_add(&dev->page_write_timer, sst_page_write, dev, 0); - - return dev; -} - - -static void -sst_close(void *p) -{ - FILE *f; - sst_t *dev = (sst_t *)p; - - if (dev->dirty) { - f = nvr_fopen(flash_path, L"wb"); - fwrite(&(dev->array[0x00000]), dev->size, 1, f); - fclose(f); - } - - free(dev->array); - dev->array = NULL; - - free(dev); -} - - -const device_t sst_flash_29ee010_device = -{ - "SST 29EE010 Flash BIOS", - 0, - SST_ID_SST29EE010, - sst_init, - sst_close, - NULL, - NULL, NULL, NULL, NULL -}; - - -const device_t sst_flash_29ee020_device = -{ - "SST 29EE020 Flash BIOS", - 0, - SST_ID_SST29EE020, - sst_init, - sst_close, - NULL, - NULL, NULL, NULL, NULL -}; - - -const device_t sst_flash_39sf010_device = -{ - "SST 39SF010 Flash BIOS", - 0, - SST_ID_SST39SF010, - sst_init, - sst_close, - NULL, - NULL, NULL, NULL, NULL -}; - - -const device_t sst_flash_39sf020_device = -{ - "SST 39SF020 Flash BIOS", - 0, - SST_ID_SST39SF020, - sst_init, - sst_close, - NULL, - NULL, NULL, NULL, NULL -}; +/* + * 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 an SST flash chip. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * Melissa Goad, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2020 Melissa Goad. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/machine.h> +#include <86box/timer.h> +#include <86box/nvr.h> +#include <86box/plat.h> + + +typedef struct sst_t +{ + uint8_t id, is_39, page_bytes, sdp; + + int command_state, id_mode, + dirty; + + uint32_t size, mask, + page_mask, page_base; + + uint8_t page_buffer[128]; + uint8_t *array; + + mem_mapping_t mapping[8], mapping_h[8]; + + pc_timer_t page_write_timer; +} sst_t; + + +static wchar_t flash_path[1024]; + + +#define SST_CHIP_ERASE 0x10 /* Both 29 and 39, 6th cycle */ +#define SST_SDP_DISABLE 0x20 /* Only 29, Software data protect disable and write - treat as write */ +#define SST_SECTOR_ERASE 0x30 /* Only 39, 6th cycle */ +#define SST_SET_ID_MODE_ALT 0x60 /* Only 29, 6th cycle */ +#define SST_ERASE 0x80 /* Both 29 and 39 */ + /* With data 60h on 6th cycle, it's alt. ID */ +#define SST_SET_ID_MODE 0x90 /* Both 29 and 39 */ +#define SST_BYTE_PROGRAM 0xa0 /* Both 29 and 39 */ +#define SST_CLEAR_ID_MODE 0xf0 /* Both 29 and 39 */ + /* 1st cycle variant only on 39 */ + +#define SST_ID_MANUFACTURER 0xbf /* SST Manufacturer's ID */ +#define SST_ID_SST29EE010 0x07 +#define SST_ID_SST29LE_VE010 0x08 +#define SST_ID_SST29EE020 0x10 +#define SST_ID_SST29LE_VE020 0x12 +#define SST_ID_SST39SF512 0xb4 +#define SST_ID_SST39SF010 0xb5 +#define SST_ID_SST39SF020 0xb6 +#define SST_ID_SST39SF040 0xb7 + + +static void +sst_sector_erase(sst_t *dev, uint32_t addr) +{ + memset(&dev->array[addr & (dev->mask & ~0xfff)], 0xff, 4096); + dev->dirty = 1; +} + + +static void +sst_new_command(sst_t *dev, uint32_t addr, uint8_t val) +{ + if (dev->command_state == 5) switch (val) { + case SST_CHIP_ERASE: + memset(dev->array, 0xff, 0x20000); + dev->command_state = 0; + break; + + case SST_SDP_DISABLE: + if (!dev->is_39) + dev->sdp = 0; + dev->command_state = 0; + break; + + case SST_SECTOR_ERASE: + if (dev->is_39) + sst_sector_erase(dev, addr); + dev->command_state = 0; + break; + + case SST_SET_ID_MODE_ALT: + dev->id_mode = 1; + dev->command_state = 0; + break; + + default: + dev->command_state = 0; + break; + } else switch (val) { + case SST_ERASE: + dev->command_state = 3; + break; + + case SST_SET_ID_MODE: + dev->id_mode = 1; + dev->command_state = 0; + break; + + case SST_BYTE_PROGRAM: + if (!dev->is_39) { + memset(dev->page_buffer, 0xff, 128); + dev->page_bytes = 0; + timer_on_auto(&dev->page_write_timer, 210.0); + } + dev->command_state = 6; + break; + + case SST_CLEAR_ID_MODE: + dev->id_mode = 0; + dev->command_state = 0; + break; + + default: + dev->command_state = 0; + break; + } +} + + +static void +sst_page_write(void *priv) +{ + sst_t *dev = (sst_t *) priv; + + memcpy(&(dev->array[dev->page_base]), dev->page_buffer, 128); + dev->dirty = 1; + dev->page_bytes = 0; + dev->command_state = 0; +} + + +static uint8_t +sst_read_id(uint32_t addr, void *p) +{ + sst_t *dev = (sst_t *) p; + + if ((addr & 0xffff) == 0) + return SST_ID_MANUFACTURER; /* SST */ + else if ((addr & 0xffff) == 1) + return dev->id; + else + return 0xff; +} + + +static void +sst_buf_write(sst_t *dev, uint32_t addr, uint8_t val) +{ + dev->page_buffer[addr & 0x0000007f] = val; + timer_disable(&dev->page_write_timer); + dev->page_bytes++; + if (dev->page_bytes >= 128) + sst_page_write(dev); + else + timer_set_delay_u64(&dev->page_write_timer, 210 * TIMER_USEC); +} + + +static void +sst_write(uint32_t addr, uint8_t val, void *p) +{ + sst_t *dev = (sst_t *) p; + + switch (dev->command_state) { + case 0: + case 3: + /* 1st and 4th Bus Write Cycle */ + if ((val == 0xf0) && dev->is_39 && (dev->command_state == 0)) { + if (dev->id_mode) + dev->id_mode = 0; + dev->command_state = 0; + } else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa)) + dev->command_state++; + else { + if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) { + /* 29 series, software data protection off, start loading the page. */ + dev->page_base = addr & dev->page_mask; /* First byte, A7 onwards of its address are the page mask. */ + dev->command_state = 7; + sst_buf_write(dev, addr, val); + } + dev->command_state = 0; + } + break; + case 1: + case 4: + /* 2nd and 5th Bus Write Cycle */ + if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55)) + dev->command_state++; + else + dev->command_state = 0; + break; + case 2: + case 5: + /* 3rd and 6th Bus Write Cycle */ + if ((addr & 0x7fff) == 0x5555) + sst_new_command(dev, addr, val); + else + dev->command_state = 0; + break; + case 6: + /* Page Load Cycle (29) / Data Write Cycle (39SF) */ + if (dev->is_39) { + dev->array[addr & dev->mask] = val; + dev->command_state = 0; + dev->dirty = 1; + } else { + dev->page_base = addr & dev->page_mask; /* First byte, A7 onwards of its address are the page mask. */ + dev->command_state++; + sst_buf_write(dev, addr, val); + } + break; + case 7: + if (!dev->is_39 && ((addr & dev->page_mask) == dev->page_base)) + sst_buf_write(dev, addr, val); + break; + } +} + + +static uint8_t +sst_read(uint32_t addr, void *p) +{ + sst_t *dev = (sst_t *) p; + uint8_t ret = 0xff; + + addr &= 0x000fffff; + + if (dev->id_mode) + ret = sst_read_id(addr, p); + else { + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = dev->array[addr - biosaddr]; + } + + return ret; +} + + +static uint16_t +sst_readw(uint32_t addr, void *p) +{ + sst_t *dev = (sst_t *) p; + uint16_t ret = 0xffff; + + addr &= 0x000fffff; + + if (dev->id_mode) + ret = sst_read(addr, p) | (sst_read(addr + 1, p) << 8); + else { + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint16_t *)&dev->array[addr - biosaddr]; + } + + return ret; +} + + +static uint32_t +sst_readl(uint32_t addr, void *p) +{ + sst_t *dev = (sst_t *) p; + uint32_t ret = 0xffffffff; + + addr &= 0x000fffff; + + if (dev->id_mode) + ret = sst_readw(addr, p) | (sst_readw(addr + 2, p) << 16); + else { + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint32_t *)&dev->array[addr - biosaddr]; + } + + return ret; +} + + +static void +sst_add_mappings(sst_t *dev) +{ + int i = 0, count; + uint32_t base, fbase; + uint32_t root_base; + + count = dev->size >> 16; + root_base = 0x100000 - dev->size; + + for (i = 0; i < count; i++) { + base = root_base + (i << 16); + fbase = base & biosmask; + + memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000); + + if (base >= 0xe0000) { + mem_mapping_add(&(dev->mapping[i]), base, 0x10000, + sst_read, sst_readw, sst_readl, + sst_write, NULL, NULL, + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); + } + mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000), 0x10000, + sst_read, sst_readw, sst_readl, + sst_write, NULL, NULL, + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); + } +} + + +static void * +sst_init(const device_t *info) +{ + FILE *f; + sst_t *dev = malloc(sizeof(sst_t)); + memset(dev, 0, sizeof(sst_t)); + + size_t l = strlen(machine_get_internal_name_ex(machine))+1; + wchar_t *machine_name = (wchar_t *) malloc(l * sizeof(wchar_t)); + mbstowcs(machine_name, machine_get_internal_name_ex(machine), l); + l = wcslen(machine_name)+5; + wchar_t *flash_name = (wchar_t *)malloc(l*sizeof(wchar_t)); + swprintf(flash_name, l, L"%ls.bin", machine_name); + + if (wcslen(flash_name) <= 1024) + wcscpy(flash_path, flash_name); + else + wcsncpy(flash_path, flash_name, 1024); + + mem_mapping_disable(&bios_mapping); + mem_mapping_disable(&bios_high_mapping); + + dev->array = (uint8_t *) malloc(biosmask + 1); + memset(dev->array, 0xff, biosmask + 1); + + dev->id = info->local; + dev->is_39 = (dev->id >= SST_ID_SST39SF512); + + if (dev->id == SST_ID_SST39SF512) + dev->size = 0x10000; + else if ((dev->id == SST_ID_SST29EE020) || (dev->id == SST_ID_SST29LE_VE020) || (dev->id == SST_ID_SST39SF020)) + dev->size = 0x40000; + else if (dev->id == SST_ID_SST39SF040) + dev->size = 0x80000; + else + dev->size = 0x20000; + dev->mask = dev->size - 1; + dev->page_mask = dev->mask & 0xffffff80; /* Filter out A0-A6. */ + dev->sdp = 1; + + sst_add_mappings(dev); + + f = nvr_fopen(flash_path, L"rb"); + if (f) { + if (fread(&(dev->array[0x00000]), 1, dev->size, f) != dev->size) + fatal("Less than %i bytes read from the SST Flash ROM file\n", dev->size); + fclose(f); + } else + dev->dirty = 1; /* It is by definition dirty on creation. */ + + free(flash_name); + free(machine_name); + + if (!dev->is_39) + timer_add(&dev->page_write_timer, sst_page_write, dev, 0); + + return dev; +} + + +static void +sst_close(void *p) +{ + FILE *f; + sst_t *dev = (sst_t *)p; + + if (dev->dirty) { + f = nvr_fopen(flash_path, L"wb"); + fwrite(&(dev->array[0x00000]), dev->size, 1, f); + fclose(f); + } + + free(dev->array); + dev->array = NULL; + + free(dev); +} + + +const device_t sst_flash_29ee010_device = +{ + "SST 29EE010 Flash BIOS", + 0, + SST_ID_SST29EE010, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; + + +const device_t sst_flash_29ee020_device = +{ + "SST 29EE020 Flash BIOS", + 0, + SST_ID_SST29EE020, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; + + +const device_t sst_flash_39sf010_device = +{ + "SST 39SF010 Flash BIOS", + 0, + SST_ID_SST39SF010, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; + + +const device_t sst_flash_39sf020_device = +{ + "SST 39SF020 Flash BIOS", + 0, + SST_ID_SST39SF020, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; diff --git a/src/network/network.c b/src/network/network.c index a32f232c1..77fbfa1ae 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -438,7 +438,7 @@ network_reset(void) if (i < 0) { /* Tell user we can't do this (at the moment.) */ - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2093); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2093, (wchar_t *) IDS_2129); // FIXME: we should ask in the dialog if they want to // reconfigure or quit, and throw them into the diff --git a/src/pc.c b/src/pc.c index 28a5a2b58..574b81d58 100644 --- a/src/pc.c +++ b/src/pc.c @@ -59,6 +59,7 @@ #include <86box/gameport.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -135,7 +136,7 @@ uint32_t mem_size = 0; /* (C) memory size */ int cpu_manufacturer = 0, /* (C) cpu manufacturer */ cpu_use_dynarec = 0, /* (C) cpu uses/needs Dyna */ cpu = 3, /* (C) cpu type */ - enable_external_fpu = 0; /* (C) enable external FPU */ + fpu_type = 0; /* (C) fpu type */ int time_sync = 0; /* (C) enable time sync */ #ifdef USE_DISCORD int enable_discord = 0; /* (C) enable Discord integration */ @@ -282,7 +283,7 @@ fatal(const char *fmt, ...) to avoid things like threads getting stuck. */ do_stop(); - ui_msgbox(MBX_ERROR|MBX_FATAL|MBX_ANSI, temp); + ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp); fflush(stdlog); @@ -552,6 +553,7 @@ int pc_init_modules(void) { int c, m; + wchar_t temp[512]; pc_log("Scanning for ROM images:\n"); c = m = 0; @@ -567,11 +569,12 @@ pc_init_modules(void) /* Load the ROMs for the selected machine. */ if (! machine_available(machine)) { + swprintf(temp, sizeof(temp), plat_get_string(IDS_2063), machine_getname()); c = 0; machine = -1; while (machine_get_internal_name_ex(c) != NULL) { if (machine_available(c)) { - ui_msgbox(MBX_INFO, (wchar_t *)IDS_2063); + ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2128, temp); machine = c; config_save(); break; @@ -587,11 +590,12 @@ pc_init_modules(void) /* Make sure we have a usable video card. */ if (! video_card_available(gfxcard)) { + swprintf(temp, sizeof(temp), plat_get_string(IDS_2064), video_card_getname(gfxcard)); c = 0; while (video_get_internal_name(c) != NULL) { gfxcard = -1; if (video_card_available(c)) { - ui_msgbox(MBX_INFO, (wchar_t *)IDS_2064); + ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2128, temp); gfxcard = c; config_save(); break; @@ -731,6 +735,8 @@ pc_reset_hard_init(void) sound_reset(); + scsi_device_init(); + /* Initialize the actual machine and its basic modules. */ machine_init(); @@ -745,6 +751,8 @@ pc_reset_hard_init(void) /* Reset any ISA RTC cards. */ isartc_reset(); + + fdc_card_init(); fdd_reset(); @@ -838,7 +846,7 @@ pc_close(thread_t *ptr) plat_delay_ms(200); } -#ifdef USE_NEW_DYNAREC +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) codegen_close(); #endif diff --git a/src/pci.c b/src/pci.c index 283cffedc..4f5b40f66 100644 --- a/src/pci.c +++ b/src/pci.c @@ -31,8 +31,8 @@ #include <86box/pic.h> #include <86box/mem.h> #include <86box/device.h> +#include <86box/dma.h> #include <86box/pci.h> -#include <86box/piix.h> #include <86box/keyboard.h> @@ -677,6 +677,7 @@ static void trc_reset(uint8_t val) { if (val & 2) { + dma_reset(); device_reset_all_pci(); cpu_alt_reset = 0; diff --git a/src/pic.c b/src/pic.c index b740406ed..4e723a12a 100644 --- a/src/pic.c +++ b/src/pic.c @@ -61,6 +61,9 @@ pic_log(const char *fmt, ...) #endif +int picinterrupt_poll(int is_pic2); + + void pic_updatepending() { @@ -238,6 +241,8 @@ pic_write(uint16_t addr, uint8_t val, void *priv) } } else { /*OCW3*/ pic.ocw3 = val; + if (val & 4) + pic.read=4; if (val & 2) pic.read=(val & 1); } @@ -249,6 +254,7 @@ uint8_t pic_read(uint16_t addr, void *priv) { uint8_t ret = 0xff; + int temp; if ((addr == 0x20) && shadow) { ret = ((pic.ocw3 & 0x20) >> 5) << 4; @@ -260,7 +266,13 @@ pic_read(uint16_t addr, void *priv) ret = ((pic.vector & 0xf8) >> 3) << 0; else if (addr & 1) ret = pic.mask; - else if (pic.read) { + else if (pic.read & 4) { + temp = picinterrupt_poll(0); + if (temp >= 0) + ret = temp | 0x80; + else + ret = 0x00; + } else if (pic.read) { if (AT) ret = pic.ins | (pic2.ins ? 4 : 0); else @@ -392,8 +404,10 @@ pic2_write(uint16_t addr, uint8_t val, void *priv) } } else { /*OCW3*/ pic2.ocw3 = val; + if (val & 4) + pic2.read=4; if (val & 2) - pic2.read=(val & 1); + pic2.read=(val & 3); } } } @@ -403,6 +417,7 @@ uint8_t pic2_read(uint16_t addr, void *priv) { uint8_t ret = 0xff; + int temp; if ((addr == 0xa0) && shadow) { ret = ((pic2.ocw3 & 0x20) >> 5) << 4; @@ -414,7 +429,13 @@ pic2_read(uint16_t addr, void *priv) ret = ((pic2.vector & 0xf8) >> 3) << 0; else if (addr & 1) ret = pic2.mask; - else if (pic2.read) + else if (pic2.read & 4) { + temp = picinterrupt_poll(1); + if (temp >= 0) + ret = (temp | 0x80); + else + ret = 0x00; + } else if (pic2.read) ret = pic2.ins; else ret = pic2.pend; @@ -623,6 +644,32 @@ picinterrupt() } +int +picinterrupt_poll(int is_pic2) +{ + int c, d; + int ret; + + if (is_pic2) + pic2.read &= ~4; + else + pic.read &= ~4; + + for (c = 0; c <= 7; c++) { + if (AT && ((1 << c) == pic.icw3)) { + for (d = 8; d <= 15; d++) { + ret = pic_process_interrupt(&pic2, d); + if ((ret != -1) && is_pic2) return c & 7; + } + } else { + ret = pic_process_interrupt(&pic, c); + if ((ret != -1) && !is_pic2) return c; + } + } + return -1; +} + + void dumppic() { diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 9cfc2a762..b30d955ef 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -2036,7 +2036,7 @@ escp_init(void *lpt) if (ft_handle == NULL) { ft_handle = dynld_module(fn, ft_imports); if (ft_handle == NULL) { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2110); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2110, (wchar_t *) IDS_2131); return(NULL); } } @@ -2044,7 +2044,7 @@ escp_init(void *lpt) /* Initialize FreeType. */ if (ft_lib == NULL) { if (ft_Init_FreeType(&ft_lib)) { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2110); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2110, (wchar_t *) IDS_2131); dynld_close(ft_lib); ft_lib = NULL; return(NULL); diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index b822ff17a..b3d7500d4 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -352,7 +352,7 @@ ps_init(void *lpt) /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); if (ghostscript_handle == NULL) { - ui_msgbox(MBX_ERROR, (wchar_t *) IDS_2114); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2114, (wchar_t *) IDS_2132); } else { if (gsapi_revision(&rev, sizeof(rev)) == 0) { pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index c22d41fa9..829e273c1 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -84,7 +84,8 @@ static SCSI_CARD scsi_cards[] = { }; -int scsi_card_available(int card) +int +scsi_card_available(int card) { if (scsi_cards[card].device) return(device_available(scsi_cards[card].device)); @@ -93,19 +94,22 @@ int scsi_card_available(int card) } -char *scsi_card_getname(int card) +char * +scsi_card_getname(int card) { return((char *) scsi_cards[card].name); } -const device_t *scsi_card_getdevice(int card) +const device_t * +scsi_card_getdevice(int card) { return(scsi_cards[card].device); } -int scsi_card_has_config(int card) +int +scsi_card_has_config(int card) { if (! scsi_cards[card].device) return(0); @@ -113,13 +117,15 @@ int scsi_card_has_config(int card) } -char *scsi_card_get_internal_name(int card) +char * +scsi_card_get_internal_name(int card) { return((char *) scsi_cards[card].internal_name); } -int scsi_card_get_from_internal_name(char *s) +int +scsi_card_get_from_internal_name(char *s) { int c = 0; @@ -133,21 +139,12 @@ int scsi_card_get_from_internal_name(char *s) } -void scsi_card_init(void) +void +scsi_card_init(void) { - int i; - scsi_device_t *dev; - if (!scsi_cards[scsi_card_current].device) return; - for (i = 0; i < SCSI_ID_MAX; i++) { - dev = &(scsi_devices[i]); - - memset(dev, 0, sizeof(scsi_device_t)); - dev->type = SCSI_NONE; - } - device_add(scsi_cards[scsi_card_current].device); scsi_card_last = scsi_card_current; diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index e8342ad90..8e50864e1 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -36,6 +36,8 @@ #include <86box/dma.h> #include <86box/pic.h> #include <86box/plat.h> +#include <86box/fdd.h> +#include <86box/fdc.h> #include <86box/scsi.h> #include <86box/scsi_aha154x.h> #include <86box/scsi_x54x.h> @@ -187,6 +189,13 @@ aha154x_eeprom(x54x_t *dev, uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint r = 0; aha_eeprom_save(dev); + + if (dev->type == AHA_154xCF) { + if (dev->fdc_address > 0) { + fdc_remove(dev->fdc); + fdc_set_base(dev->fdc, dev->fdc_address); + } + } } if (cmd == 0x23) { @@ -702,6 +711,8 @@ aha_initnvr(x54x_t *dev) /* Initialize the on-board EEPROM. */ dev->nvr[0] = dev->HostID; /* SCSI ID 7 */ dev->nvr[0] |= (0x10 | 0x20 | 0x40); + if (dev->fdc_address == 0x370) + dev->nvr[0] |= EE0_ALTFLOP; dev->nvr[1] = dev->Irq-9; /* IRQ15 */ dev->nvr[1] |= (dev->DmaChannel<<4); /* DMA6 */ dev->nvr[2] = (EE2_HABIOS | /* BIOS enabled */ @@ -757,6 +768,10 @@ aha_init(const device_t *info) dev->Irq = device_get_config_int("irq"); dev->DmaChannel = device_get_config_int("dma"); dev->rom_addr = device_get_config_hex20("bios_addr"); + if (!(dev->bus & DEVICE_MCA)) + dev->fdc_address = device_get_config_hex16("fdc_addr"); + else + dev->fdc_address = 0; dev->HostID = 7; /* default HA ID */ dev->setup_info_len = sizeof(aha_setup_t); dev->max_id = 7; @@ -834,6 +849,8 @@ aha_init(const device_t *info) dev->ven_get_irq = aha_get_irq; /* function to return IRQ from EEPROM */ dev->ven_get_dma = aha_get_dma; /* function to return DMA channel from EEPROM */ dev->ha_bps = 10000000.0; /* fast SCSI */ + if (dev->fdc_address > 0) + dev->fdc = device_add(&fdc_at_device); break; case AHA_154xCP: @@ -1022,7 +1039,6 @@ static const device_config_t aha_154xb_config[] = { } }; - static const device_config_t aha_154x_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x334, @@ -1122,6 +1138,122 @@ static const device_config_t aha_154x_config[] = { }; +static const device_config_t aha_154xcf_config[] = { + { + "base", "Address", CONFIG_HEX16, "", 0x334, + { + { + "None", 0 + }, + { + "0x330", 0x330 + }, + { + "0x334", 0x334 + }, + { + "0x230", 0x230 + }, + { + "0x234", 0x234 + }, + { + "0x130", 0x130 + }, + { + "0x134", 0x134 + }, + { + "" + } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "IRQ 12", 12 + }, + { + "IRQ 14", 14 + }, + { + "IRQ 15", 15 + }, + { + "" + } + }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, + { + { + "DMA 5", 5 + }, + { + "DMA 6", 6 + }, + { + "DMA 7", 7 + }, + { + "" + } + }, + }, + { + "bios_addr", "BIOS Address", CONFIG_HEX20, "", 0, + { + { + "Disabled", 0 + }, + { + "C800H", 0xc8000 + }, + { + "D000H", 0xd0000 + }, + { + "D800H", 0xd8000 + }, + { + "" + } + }, + }, + { + "fdc_addr", "FDC address", CONFIG_HEX16, "", 0, + { + { + "None", 0 + }, + { + "0x3f0", 0x3f0 + }, + { + "0x370", 0x370 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; + + const device_t aha154xa_device = { "Adaptec AHA-154xA", DEVICE_ISA | DEVICE_AT, @@ -1155,7 +1287,7 @@ const device_t aha154xcf_device = { AHA_154xCF, aha_init, x54x_close, NULL, NULL, NULL, NULL, - aha_154x_config + aha_154xcf_config }; const device_t aha1640_device = { diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 71529ef32..a3e7b6161 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -37,6 +37,8 @@ #include <86box/device.h> #include <86box/nvr.h> #include <86box/dma.h> +#include <86box/fdd.h> +#include <86box/fdc.h> #include <86box/pic.h> #include <86box/pci.h> #include <86box/plat.h> diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 0c4748505..8e1b5a55d 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -27,7 +27,6 @@ #include <86box/config.h> #include <86box/timer.h> #include <86box/device.h> -#include <86box/piix.h> #include <86box/scsi_device.h> #include <86box/nvr.h> #include <86box/hdc.h> @@ -339,7 +338,7 @@ static void scsi_cdrom_set_callback(scsi_cdrom_t *dev) { if (dev && dev->drv && (dev->drv->bus_type != CDROM_BUS_SCSI)) - ide_set_callback(dev->drv->ide_channel >> 1, dev->callback); + ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); } diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index 19093c0ab..f4dc555c0 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -170,3 +170,18 @@ scsi_device_close_all(void) dev->command_stop(dev->sc); } } + + +void +scsi_device_init(void) +{ + int i; + scsi_device_t *dev; + + for (i = 0; i < SCSI_ID_MAX; i++) { + dev = &(scsi_devices[i]); + + memset(dev, 0, sizeof(scsi_device_t)); + dev->type = SCSI_NONE; + } +} diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index da65d517b..19d87bfa6 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -23,7 +23,6 @@ #include <86box/timer.h> #include <86box/device.h> #include <86box/nvr.h> -#include <86box/piix.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/scsi_device.h> @@ -1262,6 +1261,8 @@ scsi_disk_close(void) for (c = 0; c < HDD_NUM; c++) { if (hdd[c].bus == HDD_BUS_SCSI) { + memset(&scsi_devices[hdd[c].scsi_id], 0x00, sizeof(scsi_device_t)); + hdd_image_close(c); dev = hdd[c].priv; diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 49ddef4ce..d9c06a33f 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -2646,14 +2646,17 @@ ncr53c8xx_init(const device_t *info) ncr53c8xx_pci_bar[0].addr_regs[0] = 1; ncr53c8xx_pci_bar[1].addr_regs[0] = 0; - dev->chip = info->local; + dev->chip = info->local & 0xff; ncr53c8xx_pci_regs[0x04] = 3; ncr53c8xx_mem_init(dev, 0x0fffff00); ncr53c8xx_mem_disable(dev); - dev->has_bios = device_get_config_int("bios"); + if (info->local & 0x8000) + dev->has_bios = 0; + else + dev->has_bios = device_get_config_int("bios"); if (dev->has_bios) rom_init(&dev->bios, NCR53C8XX_ROM, 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (dev->chip >= CHIP_825) { @@ -2730,6 +2733,16 @@ const device_t ncr53c810_pci_device = ncr53c8xx_pci_config }; +const device_t ncr53c810_onboard_pci_device = +{ + "NCR 53c810 (SCSI) On-Board", + DEVICE_PCI, + 0x8001, + ncr53c8xx_init, ncr53c8xx_close, NULL, + NULL, NULL, NULL, + NULL +}; + const device_t ncr53c825a_pci_device = { "NCR 53c825A (SCSI)", diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 0f301abdf..a3e8d2f0d 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -38,6 +38,8 @@ #include <86box/mem.h> #include <86box/rom.h> #include <86box/device.h> +#include <86box/fdd.h> +#include <86box/fdc.h> #include <86box/nvr.h> #include <86box/plat.h> #include <86box/scsi.h> diff --git a/src/sio_acc3221.c b/src/sio/sio_acc3221.c similarity index 100% rename from src/sio_acc3221.c rename to src/sio/sio_acc3221.c diff --git a/src/sio_detect.c b/src/sio/sio_detect.c similarity index 100% rename from src/sio_detect.c rename to src/sio/sio_detect.c diff --git a/src/sio_f82c710.c b/src/sio/sio_f82c710.c similarity index 100% rename from src/sio_f82c710.c rename to src/sio/sio_f82c710.c diff --git a/src/sio_fdc37c669.c b/src/sio/sio_fdc37c669.c similarity index 100% rename from src/sio_fdc37c669.c rename to src/sio/sio_fdc37c669.c diff --git a/src/sio_fdc37c66x.c b/src/sio/sio_fdc37c66x.c similarity index 100% rename from src/sio_fdc37c66x.c rename to src/sio/sio_fdc37c66x.c diff --git a/src/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c similarity index 100% rename from src/sio_fdc37c93x.c rename to src/sio/sio_fdc37c93x.c diff --git a/src/sio_pc87306.c b/src/sio/sio_pc87306.c similarity index 91% rename from src/sio_pc87306.c rename to src/sio/sio_pc87306.c index 5f3b625f8..604567395 100644 --- a/src/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -226,42 +226,40 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) case 0: if (valxor & 1) { lpt1_remove(); - if (val & 1) + if ((val & 1) && !(dev->regs[2] & 1)) lpt1_handler(dev); } if (valxor & 2) { serial_remove(dev->uart[0]); - if (val & 2) + if ((val & 2) && !(dev->regs[2] & 1)) serial_handler(dev, 0); } if (valxor & 4) { serial_remove(dev->uart[1]); - if (val & 4) + if ((val & 4) && !(dev->regs[2] & 1)) serial_handler(dev, 1); } if (valxor & 0x28) { fdc_remove(dev->fdc); - if (val & 8) + if ((val & 8) && !(dev->regs[2] & 1)) fdc_set_base(dev->fdc, (val & 0x20) ? 0x370 : 0x3f0); } break; case 1: if (valxor & 3) { lpt1_remove(); - if (dev->regs[0] & 1) + if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) lpt1_handler(dev); } if (valxor & 0xcc) { - if (dev->regs[0] & 2) + serial_remove(dev->uart[0]); + if ((dev->regs[0] & 2) && !(dev->regs[2] & 1)) serial_handler(dev, 0); - else - serial_remove(dev->uart[0]); } if (valxor & 0xf0) { - if (dev->regs[0] & 4) + serial_remove(dev->uart[1]); + if ((dev->regs[0] & 4) && !(dev->regs[2] & 1)) serial_handler(dev, 1); - else - serial_remove(dev->uart[1]); } break; case 2: @@ -282,6 +280,11 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) fdc_set_base(dev->fdc, (dev->regs[0] & 0x20) ? 0x370 : 0x3f0); } } + if (valxor & 8) { + lpt1_remove(); + if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) + lpt1_handler(dev); + } break; case 9: if (valxor & 0x44) { @@ -300,7 +303,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) case 0x19: if (valxor) { lpt1_remove(); - if (dev->regs[0] & 1) + if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) lpt1_handler(dev); } break; @@ -309,15 +312,18 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) lpt1_remove(); if (!(val & 0x40)) dev->regs[0x19] = 0xEF; - if (dev->regs[0] & 1) + if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) lpt1_handler(dev); } break; case 0x1C: if (valxor) { - if (dev->regs[0] & 2) + serial_remove(dev->uart[0]); + serial_remove(dev->uart[1]); + + if ((dev->regs[0] & 2) && !(dev->regs[2] & 1)) serial_handler(dev, 0); - if (dev->regs[0] & 4) + if ((dev->regs[0] & 4) && !(dev->regs[2] & 1)) serial_handler(dev, 1); } break; diff --git a/src/sio/sio_pc87307.c b/src/sio/sio_pc87307.c new file mode 100644 index 000000000..0921c4677 --- /dev/null +++ b/src/sio/sio_pc87307.c @@ -0,0 +1,569 @@ +/* + * 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 NatSemi PC87307 Super I/O chip. + * + * + * + * Author: Miran Grca, + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/lpt.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/pci.h> +#include <86box/rom.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sio.h> + + +typedef struct { + uint8_t id, pm_idx, + regs[48], ld_regs[256][208], + pcregs[16], gpio[8], + pm[8]; + uint16_t gpio_base, pm_base; + int cur_reg; + fdc_t *fdc; + serial_t *uart[2]; +} pc87307_t; + + +static void fdc_handler(pc87307_t *dev); +static void lpt1_handler(pc87307_t *dev); +static void serial_handler(pc87307_t *dev, int uart); + + +static void +pc87307_gpio_write(uint16_t port, uint8_t val, void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + + dev->gpio[port & 7] = val; +} + + +uint8_t +pc87307_gpio_read(uint16_t port, void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + + return dev->gpio[port & 7]; +} + + +static void +pc87307_gpio_remove(pc87307_t *dev) +{ + if (dev->gpio_base != 0xffff) { + io_removehandler(dev->gpio_base, 0x0008, + pc87307_gpio_read, NULL, NULL, pc87307_gpio_write, NULL, NULL, dev); + dev->gpio_base = 0xffff; + } +} + + +static void +pc87307_gpio_init(pc87307_t *dev, uint16_t addr) +{ + dev->gpio_base = addr; + + io_sethandler(dev->gpio_base, 0x0008, + pc87307_gpio_read, NULL, NULL, pc87307_gpio_write, NULL, NULL, dev); +} + + +static void +pc87307_pm_write(uint16_t port, uint8_t val, void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + + if (port & 1) + dev->pm[dev->pm_idx] = val; + else { + dev->pm_idx = val & 0x07; + switch (dev->pm_idx) { + case 0x00: + fdc_handler(dev); + lpt1_handler(dev); + serial_handler(dev, 1); + serial_handler(dev, 0); + break; + } + } +} + + +uint8_t +pc87307_pm_read(uint16_t port, void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + + if (port & 1) + return dev->pm[dev->pm_idx]; + else + return dev->pm_idx; +} + + +static void +pc87307_pm_remove(pc87307_t *dev) +{ + if (dev->pm_base != 0xffff) { + io_removehandler(dev->pm_base, 0x0008, + pc87307_pm_read, NULL, NULL, pc87307_pm_write, NULL, NULL, dev); + dev->pm_base = 0xffff; + } +} + + +static void +pc87307_pm_init(pc87307_t *dev, uint16_t addr) +{ + dev->pm_base = addr; + + io_sethandler(dev->pm_base, 0x0008, + pc87307_pm_read, NULL, NULL, pc87307_pm_write, NULL, NULL, dev); +} + + +static void +fdc_handler(pc87307_t *dev) +{ + uint8_t irq, active; + uint16_t addr; + + fdc_remove(dev->fdc); + + active = (dev->ld_regs[0x03][0x00] & 0x01) && (dev->pm[0x00] & 0x08); + addr = ((dev->ld_regs[0x03][0x30] << 8) | dev->ld_regs[0x03][0x31]) - 0x0002; + irq = (dev->ld_regs[0x03][0x40] & 0x0f); + + if (active && (addr <= 0xfff2)) { + fdc_set_base(dev->fdc, addr); + fdc_set_irq(dev->fdc, irq); + } +} + + +static void +lpt1_handler(pc87307_t *dev) +{ + uint8_t irq, active; + uint16_t addr; + + lpt1_remove(); + + active = (dev->ld_regs[0x04][0x00] & 0x01) && (dev->pm[0x00] & 0x10); + addr = (dev->ld_regs[0x04][0x30] << 8) | dev->ld_regs[0x04][0x31]; + irq = (dev->ld_regs[0x04][0x40] & 0x0f); + + if (active && (addr <= 0xfffc)) { + lpt1_init(addr); + lpt1_irq(irq); + } +} + + +static void +serial_handler(pc87307_t *dev, int uart) +{ + uint8_t irq, active; + uint16_t addr; + + serial_remove(dev->uart[uart]); + + active = (dev->ld_regs[0x06 - uart][0x00] & 0x01) && (dev->pm[0x00] & (1 << (6 - uart))); + addr = (dev->ld_regs[0x06 - uart][0x30] << 8) | dev->ld_regs[0x06 - uart][0x31]; + irq = (dev->ld_regs[0x06 - uart][0x40] & 0x0f); + + if (active && (addr <= 0xfff8)) + serial_setup(dev->uart[uart], addr, irq); +} + + +static void +gpio_handler(pc87307_t *dev) +{ + uint8_t active; + uint16_t addr; + + pc87307_gpio_remove(dev); + + active = (dev->ld_regs[0x07][0x00] & 0x01); + addr = (dev->ld_regs[0x07][0x30] << 8) | dev->ld_regs[0x07][0x31]; + + if (active) + pc87307_gpio_init(dev, addr); +} + + +static void +pm_handler(pc87307_t *dev) +{ + uint8_t active; + uint16_t addr; + + pc87307_pm_remove(dev); + + active = (dev->ld_regs[0x08][0x00] & 0x01); + addr = (dev->ld_regs[0x08][0x30] << 8) | dev->ld_regs[0x08][0x31]; + + if (active) + pc87307_pm_init(dev, addr); +} + + +static void +pc87307_write(uint16_t port, uint8_t val, void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + uint8_t index; + + index = (port & 1) ? 0 : 1; + + if (index) { + dev->cur_reg = val; + return; + } else { + switch (dev->cur_reg) { + case 0x00: case 0x02: case 0x03: case 0x06: + case 0x07: case 0x21: + dev->regs[dev->cur_reg] = val; + break; + case 0x22: + dev->regs[dev->cur_reg] = val & 0x7f; + break; + case 0x23: + dev->regs[dev->cur_reg] = val & 0x0f; + break; + case 0x24: + dev->pcregs[dev->regs[0x23]] = val; + break; + default: + if (dev->cur_reg >= 0x30) { + if ((dev->regs[0x07] != 0x06) || !(dev->regs[0x21] & 0x10)) + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val; + } + break; + } + } + + switch(dev->cur_reg) { + case 0x30: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x01; + switch (dev->regs[0x07]) { + case 0x03: + fdc_handler(dev); + break; + case 0x04: + lpt1_handler(dev); + break; + case 0x05: + serial_handler(dev, 1); + break; + case 0x06: + serial_handler(dev, 0); + break; + case 0x07: + gpio_handler(dev); + break; + case 0x08: + pm_handler(dev); + break; + } + break; + case 0x60: case 0x62: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x07; + if (dev->cur_reg == 0x62) + break; + switch (dev->regs[0x07]) { + case 0x03: + fdc_handler(dev); + break; + case 0x04: + lpt1_handler(dev); + break; + case 0x05: + serial_handler(dev, 1); + break; + case 0x06: + serial_handler(dev, 0); + break; + case 0x07: + gpio_handler(dev); + break; + case 0x08: + pm_handler(dev); + break; + } + break; + case 0x61: + switch (dev->regs[0x07]) { + case 0x00: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfb; + break; + case 0x03: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfa; + fdc_handler(dev); + break; + case 0x04: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfc; + lpt1_handler(dev); + break; + case 0x05: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + serial_handler(dev, 1); + break; + case 0x06: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + serial_handler(dev, 0); + break; + case 0x07: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + gpio_handler(dev); + break; + case 0x08: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfe; + pm_handler(dev); + break; + } + break; + case 0x63: + if (dev->regs[0x07] == 0x00) + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = (val & 0xfb) | 0x04; + break; + case 0x70: + case 0x74: case 0x75: + switch (dev->regs[0x07]) { + case 0x03: + fdc_handler(dev); + break; + case 0x04: + lpt1_handler(dev); + break; + case 0x05: + serial_handler(dev, 1); + break; + case 0x06: + serial_handler(dev, 0); + break; + case 0x07: + gpio_handler(dev); + break; + case 0x08: + pm_handler(dev); + break; + } + break; + case 0xf0: + switch (dev->regs[0x07]) { + case 0x00: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xc1; + break; + case 0x03: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xe1; + fdc_update_densel_polarity(dev->fdc, (val & 0x20) ? 1 : 0); + fdc_update_enh_mode(dev->fdc, (val & 0x40) ? 1 : 0); + break; + case 0x04: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf3; + lpt1_handler(dev); + break; + case 0x05: case 0x06: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x87; + break; + } + break; + case 0xf1: + if (dev->regs[0x07] == 0x03) + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x0f; + break; + } +} + + +uint8_t +pc87307_read(uint16_t port, void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + uint8_t ret = 0xff, index; + + index = (port & 1) ? 0 : 1; + + if (index) + ret = dev->cur_reg; + else { + if (dev->cur_reg >= 0x30) + ret = dev->regs[dev->cur_reg]; + else if (dev->cur_reg == 0x24) + ret = dev->pcregs[dev->regs[0x23]]; + else + ret = dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30]; + } + + return ret; +} + + +void +pc87307_reset(pc87307_t *dev) +{ + int i; + + memset(dev->regs, 0x00, 0x30); + for (i = 0; i < 256; i++) + memset(dev->ld_regs[i], 0x00, 0xd0); + memset(dev->pcregs, 0x00, 0x10); + memset(dev->gpio, 0xff, 0x08); + memset(dev->pm, 0x00, 0x08); + + dev->regs[0x20] = dev->id; + dev->regs[0x21] = 0x04; + + dev->ld_regs[0x00][0x01] = 0x01; + dev->ld_regs[0x00][0x31] = 0x60; + dev->ld_regs[0x00][0x33] = 0x64; + dev->ld_regs[0x00][0x40] = 0x01; + dev->ld_regs[0x00][0x41] = 0x02; + dev->ld_regs[0x00][0x44] = 0x04; + dev->ld_regs[0x00][0x45] = 0x04; + dev->ld_regs[0x00][0xc0] = 0x40; + + dev->ld_regs[0x01][0x40] = 0x0c; + dev->ld_regs[0x01][0x41] = 0x02; + dev->ld_regs[0x01][0x44] = 0x04; + dev->ld_regs[0x01][0x45] = 0x04; + + dev->ld_regs[0x02][0x00] = 0x01; + dev->ld_regs[0x02][0x31] = 0x70; + dev->ld_regs[0x02][0x40] = 0x08; + dev->ld_regs[0x02][0x44] = 0x04; + dev->ld_regs[0x02][0x45] = 0x04; + + dev->ld_regs[0x03][0x01] = 0x01; + dev->ld_regs[0x03][0x30] = 0x03; + dev->ld_regs[0x03][0x31] = 0xf2; + dev->ld_regs[0x03][0x40] = 0x06; + dev->ld_regs[0x03][0x41] = 0x03; + dev->ld_regs[0x03][0x44] = 0x02; + dev->ld_regs[0x03][0x45] = 0x04; + dev->ld_regs[0x03][0xc0] = 0x02; + + dev->ld_regs[0x04][0x30] = 0x02; + dev->ld_regs[0x04][0x31] = 0x78; + dev->ld_regs[0x04][0x40] = 0x07; + dev->ld_regs[0x04][0x44] = 0x04; + dev->ld_regs[0x04][0x45] = 0x04; + dev->ld_regs[0x04][0xc0] = 0xf2; + + dev->ld_regs[0x05][0x30] = 0x02; + dev->ld_regs[0x05][0x31] = 0xf8; + dev->ld_regs[0x05][0x40] = 0x03; + dev->ld_regs[0x05][0x41] = 0x03; + dev->ld_regs[0x05][0x44] = 0x04; + dev->ld_regs[0x05][0x45] = 0x04; + dev->ld_regs[0x05][0xc0] = 0x02; + + dev->ld_regs[0x06][0x30] = 0x03; + dev->ld_regs[0x06][0x31] = 0xf8; + dev->ld_regs[0x06][0x40] = 0x04; + dev->ld_regs[0x06][0x41] = 0x03; + dev->ld_regs[0x06][0x44] = 0x04; + dev->ld_regs[0x06][0x45] = 0x04; + dev->ld_regs[0x06][0xc0] = 0x02; + + dev->ld_regs[0x07][0x44] = 0x04; + dev->ld_regs[0x07][0x45] = 0x04; + + dev->ld_regs[0x08][0x44] = 0x04; + dev->ld_regs[0x08][0x45] = 0x04; + + dev->gpio[0] = 0xff; + dev->gpio[1] = 0xfb; + + dev->pm[0] = 0xff; + dev->pm[1] = 0xff; + dev->pm[4] = 0x0e; + dev->pm[7] = 0x01; + + dev->gpio_base = dev->pm_base = 0xffff; + + /* + 0 = 360 rpm @ 500 kbps for 3.5" + 1 = Default, 300 rpm @ 500,300,250,1000 kbps for 3.5" + */ + lpt1_remove(); + serial_remove(dev->uart[0]); + serial_remove(dev->uart[1]); + fdc_reset(dev->fdc); +} + + +static void +pc87307_close(void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + + free(dev); +} + + +static void * +pc87307_init(const device_t *info) +{ + pc87307_t *dev = (pc87307_t *) malloc(sizeof(pc87307_t)); + memset(dev, 0, sizeof(pc87307_t)); + + dev->id = info->local & 0xff; + + dev->fdc = device_add(&fdc_at_nsc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + pc87307_reset(dev); + + io_sethandler(0x02e, 0x0002, + pc87307_read, NULL, NULL, pc87307_write, NULL, NULL, dev); + + return dev; +} + + +const device_t pc87307_device = { + "National Semiconductor PC87307 Super I/O", + 0, + 0xc0, + pc87307_init, pc87307_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +const device_t pc97307_device = { + "National Semiconductor PC97307 Super I/O", + 0, + 0xcf, + pc87307_init, pc87307_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio/sio_pc87309.c b/src/sio/sio_pc87309.c new file mode 100644 index 000000000..f60d02374 --- /dev/null +++ b/src/sio/sio_pc87309.c @@ -0,0 +1,477 @@ +/* + * 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 NatSemi PC87309 Super I/O chip. + * + * + * + * Author: Miran Grca, + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/lpt.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/pci.h> +#include <86box/rom.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sio.h> + + +typedef struct { + uint8_t id, pm_idx, + regs[48], ld_regs[256][208], + pm[8]; + uint16_t pm_base; + int cur_reg; + fdc_t *fdc; + serial_t *uart[2]; +} pc87309_t; + + +static void fdc_handler(pc87309_t *dev); +static void lpt1_handler(pc87309_t *dev); +static void serial_handler(pc87309_t *dev, int uart); + + +static void +pc87309_pm_write(uint16_t port, uint8_t val, void *priv) +{ + pc87309_t *dev = (pc87309_t *) priv; + + if (port & 1) + dev->pm[dev->pm_idx] = val; + else { + dev->pm_idx = val & 0x07; + switch (dev->pm_idx) { + case 0x00: + fdc_handler(dev); + lpt1_handler(dev); + serial_handler(dev, 1); + serial_handler(dev, 0); + break; + } + } +} + + +uint8_t +pc87309_pm_read(uint16_t port, void *priv) +{ + pc87309_t *dev = (pc87309_t *) priv; + + if (port & 1) + return dev->pm[dev->pm_idx]; + else + return dev->pm_idx; +} + + +static void +pc87309_pm_remove(pc87309_t *dev) +{ + if (dev->pm_base != 0xffff) { + io_removehandler(dev->pm_base, 0x0008, + pc87309_pm_read, NULL, NULL, pc87309_pm_write, NULL, NULL, dev); + dev->pm_base = 0xffff; + } +} + + +static void +pc87309_pm_init(pc87309_t *dev, uint16_t addr) +{ + dev->pm_base = addr; + + io_sethandler(dev->pm_base, 0x0008, + pc87309_pm_read, NULL, NULL, pc87309_pm_write, NULL, NULL, dev); +} + + +static void +fdc_handler(pc87309_t *dev) +{ + uint8_t irq, active; + uint16_t addr; + + fdc_remove(dev->fdc); + + active = (dev->ld_regs[0x00][0x00] & 0x01) && (dev->pm[0x00] & 0x08); + addr = ((dev->ld_regs[0x00][0x30] << 8) | dev->ld_regs[0x00][0x31]) - 0x0002; + irq = (dev->ld_regs[0x00][0x40] & 0x0f); + + if (active) { + fdc_set_base(dev->fdc, addr); + fdc_set_irq(dev->fdc, irq); + } +} + + +static void +lpt1_handler(pc87309_t *dev) +{ + uint8_t irq, active; + uint16_t addr; + + lpt1_remove(); + + active = (dev->ld_regs[0x01][0x00] & 0x01) && (dev->pm[0x00] & 0x10); + addr = (dev->ld_regs[0x01][0x30] << 8) | dev->ld_regs[0x01][0x31]; + irq = (dev->ld_regs[0x01][0x40] & 0x0f); + + if (active) { + lpt1_init(addr); + lpt1_irq(irq); + } +} + + +static void +serial_handler(pc87309_t *dev, int uart) +{ + uint8_t irq, active; + uint16_t addr; + + serial_remove(dev->uart[uart]); + + active = (dev->ld_regs[0x03 - uart][0x00] & 0x01) && (dev->pm[0x00] & (1 << (6 - uart))); + addr = (dev->ld_regs[0x03 - uart][0x30] << 8) | dev->ld_regs[0x03 - uart][0x31]; + irq = (dev->ld_regs[0x03 - uart][0x40] & 0x0f); + + if (active) + serial_setup(dev->uart[uart], addr, irq); +} + + +static void +pm_handler(pc87309_t *dev) +{ + uint8_t active; + uint16_t addr; + + pc87309_pm_remove(dev); + + active = (dev->ld_regs[0x04][0x00] & 0x01); + addr = (dev->ld_regs[0x04][0x30] << 8) | dev->ld_regs[0x04][0x31]; + + if (active) + pc87309_pm_init(dev, addr); +} + + +static void +pc87309_write(uint16_t port, uint8_t val, void *priv) +{ + pc87309_t *dev = (pc87309_t *) priv; + uint8_t index; + + index = (port & 1) ? 0 : 1; + + if (index) { + dev->cur_reg = val; + return; + } else { + switch (dev->cur_reg) { + case 0x00: case 0x02: case 0x03: case 0x06: + case 0x07: case 0x21: + dev->regs[dev->cur_reg] = val; + break; + case 0x22: + dev->regs[dev->cur_reg] = val & 0x7f; + break; + default: + if (dev->cur_reg >= 0x30) { + if ((dev->regs[0x07] != 0x06) || !(dev->regs[0x21] & 0x10)) + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val; + } + break; + } + } + + switch(dev->cur_reg) { + case 0x30: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x01; + switch (dev->regs[0x07]) { + case 0x00: + fdc_handler(dev); + break; + case 0x01: + lpt1_handler(dev); + break; + case 0x02: + serial_handler(dev, 1); + break; + case 0x03: + serial_handler(dev, 0); + break; + case 0x04: + pm_handler(dev); + break; + } + break; + case 0x60: case 0x62: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x07; + if (dev->cur_reg == 0x62) + break; + switch (dev->regs[0x07]) { + case 0x00: + fdc_handler(dev); + break; + case 0x01: + lpt1_handler(dev); + break; + case 0x02: + serial_handler(dev, 1); + break; + case 0x03: + serial_handler(dev, 0); + break; + case 0x04: + pm_handler(dev); + break; + } + break; + case 0x63: + if (dev->regs[0x07] == 0x06) + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = (val & 0xf8) | 0x04; + break; + case 0x61: + switch (dev->regs[0x07]) { + case 0x00: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfa; + fdc_handler(dev); + break; + case 0x01: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfc; + lpt1_handler(dev); + break; + case 0x02: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + serial_handler(dev, 1); + break; + case 0x03: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + serial_handler(dev, 0); + break; + case 0x04: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfe; + pm_handler(dev); + break; + case 0x06: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + break; + } + break; + case 0x70: + case 0x74: case 0x75: + switch (dev->regs[0x07]) { + case 0x00: + fdc_handler(dev); + break; + case 0x01: + lpt1_handler(dev); + break; + case 0x02: + serial_handler(dev, 1); + break; + case 0x03: + serial_handler(dev, 0); + break; + case 0x04: + pm_handler(dev); + break; + } + break; + case 0xf0: + switch (dev->regs[0x07]) { + case 0x00: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xe1; + fdc_update_densel_polarity(dev->fdc, (val & 0x20) ? 1 : 0); + fdc_update_enh_mode(dev->fdc, (val & 0x40) ? 1 : 0); + break; + case 0x01: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf3; + lpt1_handler(dev); + break; + case 0x02: case 0x03: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x87; + break; + case 0x06: + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xc1; + break; + } + break; + case 0xf1: + if (dev->regs[0x07] == 0x00) + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x0f; + break; + } +} + + +uint8_t +pc87309_read(uint16_t port, void *priv) +{ + pc87309_t *dev = (pc87309_t *) priv; + uint8_t ret = 0xff, index; + + index = (port & 1) ? 0 : 1; + + if (index) + ret = dev->cur_reg & 0x1f; + else { + if (dev->cur_reg == 8) + ret = 0x70; + else if (dev->cur_reg < 28) + ret = dev->regs[dev->cur_reg]; + } + + return ret; +} + + +void +pc87309_reset(pc87309_t *dev) +{ + int i; + + memset(dev->regs, 0x00, 0x30); + for (i = 0; i < 256; i++) + memset(dev->ld_regs[i], 0x00, 0xd0); + memset(dev->pm, 0x00, 0x08); + + dev->regs[0x20] = dev->id; + dev->regs[0x21] = 0x04; + + dev->ld_regs[0x00][0x01] = 0x01; + dev->ld_regs[0x00][0x30] = 0x03; + dev->ld_regs[0x00][0x31] = 0xf2; + dev->ld_regs[0x00][0x40] = 0x06; + dev->ld_regs[0x00][0x41] = 0x03; + dev->ld_regs[0x00][0x44] = 0x02; + dev->ld_regs[0x00][0x45] = 0x04; + dev->ld_regs[0x00][0xc0] = 0x02; + + dev->ld_regs[0x01][0x30] = 0x02; + dev->ld_regs[0x01][0x31] = 0x78; + dev->ld_regs[0x01][0x40] = 0x07; + dev->ld_regs[0x01][0x44] = 0x04; + dev->ld_regs[0x01][0x45] = 0x04; + dev->ld_regs[0x01][0xc0] = 0xf2; + + dev->ld_regs[0x02][0x30] = 0x02; + dev->ld_regs[0x02][0x31] = 0xf8; + dev->ld_regs[0x02][0x40] = 0x03; + dev->ld_regs[0x02][0x41] = 0x03; + dev->ld_regs[0x02][0x44] = 0x04; + dev->ld_regs[0x02][0x45] = 0x04; + dev->ld_regs[0x02][0xc0] = 0x02; + + dev->ld_regs[0x03][0x30] = 0x03; + dev->ld_regs[0x03][0x31] = 0xf8; + dev->ld_regs[0x03][0x40] = 0x04; + dev->ld_regs[0x03][0x41] = 0x03; + dev->ld_regs[0x03][0x44] = 0x04; + dev->ld_regs[0x03][0x45] = 0x04; + dev->ld_regs[0x03][0xc0] = 0x02; + + dev->ld_regs[0x04][0x44] = 0x04; + dev->ld_regs[0x04][0x45] = 0x04; + + dev->ld_regs[0x05][0x40] = 0x0c; + dev->ld_regs[0x05][0x41] = 0x02; + dev->ld_regs[0x05][0x44] = 0x04; + dev->ld_regs[0x05][0x45] = 0x04; + + dev->ld_regs[0x06][0x01] = 0x01; + dev->ld_regs[0x06][0x31] = 0x60; + dev->ld_regs[0x06][0x33] = 0x64; + dev->ld_regs[0x06][0x40] = 0x01; + dev->ld_regs[0x06][0x41] = 0x02; + dev->ld_regs[0x06][0x44] = 0x04; + dev->ld_regs[0x06][0x45] = 0x04; + dev->ld_regs[0x06][0xc0] = 0x40; + + dev->regs[0x00] = 0x0B; + dev->regs[0x01] = 0x01; + dev->regs[0x03] = 0x01; + dev->regs[0x05] = 0x0D; + dev->regs[0x08] = 0x70; + dev->regs[0x09] = 0xC0; + dev->regs[0x0b] = 0x80; + dev->regs[0x0f] = 0x1E; + dev->regs[0x12] = 0x30; + dev->regs[0x19] = 0xEF; + + dev->pm[0] = 0xe9; + dev->pm[4] = 0x0e; + + dev->pm_base = 0xffff; + + /* + 0 = 360 rpm @ 500 kbps for 3.5" + 1 = Default, 300 rpm @ 500,300,250,1000 kbps for 3.5" + */ + lpt1_remove(); + serial_remove(dev->uart[0]); + serial_remove(dev->uart[1]); + fdc_reset(dev->fdc); +} + + +static void +pc87309_close(void *priv) +{ + pc87309_t *dev = (pc87309_t *) priv; + + free(dev); +} + + +static void * +pc87309_init(const device_t *info) +{ + pc87309_t *dev = (pc87309_t *) malloc(sizeof(pc87309_t)); + memset(dev, 0, sizeof(pc87309_t)); + + dev->id = info->local & 0xff; + + dev->fdc = device_add(&fdc_at_nsc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + pc87309_reset(dev); + + io_sethandler(0x02e, 0x0002, + pc87309_read, NULL, NULL, pc87309_write, NULL, NULL, dev); + + return dev; +} + + +const device_t pc87309_device = { + "National Semiconductor PC87309 Super I/O", + 0, + 0xe0, + pc87309_init, pc87309_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio/sio_pc87332.c b/src/sio/sio_pc87332.c new file mode 100644 index 000000000..3a9b04785 --- /dev/null +++ b/src/sio/sio_pc87332.c @@ -0,0 +1,313 @@ +/* + * 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 NatSemi PC87332 Super I/O chip. + * + * + * + * Author: Miran Grca, + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/lpt.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/pci.h> +#include <86box/rom.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sio.h> + + +typedef struct { + uint8_t tries, + regs[15]; + int cur_reg; + fdc_t *fdc; + serial_t *uart[2]; + nvr_t *nvr; +} pc87332_t; + + +static void +lpt1_handler(pc87332_t *dev) +{ + int temp; + uint16_t lpt_port = 0x378; + uint8_t lpt_irq = 5; + + temp = dev->regs[0x01] & 3; + + switch (temp) { + case 0: + lpt_port = 0x378; + lpt_irq = (dev->regs[0x02] & 0x08) ? 7 : 5; + break; + case 1: + lpt_port = 0x3bc; + lpt_irq = 7; + break; + case 2: + lpt_port = 0x278; + lpt_irq = 5; + break; + case 3: + lpt_port = 0x000; + lpt_irq = 0xff; + break; + } + + if (lpt_port) + lpt1_init(lpt_port); + + lpt1_irq(lpt_irq); +} + + +static void +serial_handler(pc87332_t *dev, int uart) +{ + int temp; + + temp = (dev->regs[1] >> (2 << uart)) & 3; + + switch (temp) { + case 0: + serial_setup(dev->uart[uart], SERIAL1_ADDR, 4); + break; + case 1: + serial_setup(dev->uart[uart], SERIAL2_ADDR, 3); + break; + case 2: + switch ((dev->regs[1] >> 6) & 3) { + case 0: + serial_setup(dev->uart[uart], 0x3e8, 4); + break; + case 1: + serial_setup(dev->uart[uart], 0x338, 4); + break; + case 2: + serial_setup(dev->uart[uart], 0x2e8, 4); + break; + case 3: + serial_setup(dev->uart[uart], 0x220, 4); + break; + } + break; + case 3: + switch ((dev->regs[1] >> 6) & 3) { + case 0: + serial_setup(dev->uart[uart], 0x2e8, 3); + break; + case 1: + serial_setup(dev->uart[uart], 0x238, 3); + break; + case 2: + serial_setup(dev->uart[uart], 0x2e0, 3); + break; + case 3: + serial_setup(dev->uart[uart], 0x228, 3); + break; + } + break; + } +} + + +static void +pc87332_write(uint16_t port, uint8_t val, void *priv) +{ + pc87332_t *dev = (pc87332_t *) priv; + uint8_t index, valxor; + + index = (port & 1) ? 0 : 1; + + if (index) { + dev->cur_reg = val & 0x1f; + dev->tries = 0; + return; + } else { + if (dev->tries) { + valxor = val ^ dev->regs[dev->cur_reg]; + dev->tries = 0; + if ((dev->cur_reg <= 14) && (dev->cur_reg != 8)) + dev->regs[dev->cur_reg] = val; + else + return; + } else { + dev->tries++; + return; + } + } + + switch(dev->cur_reg) { + case 0: + if (valxor & 1) { + lpt1_remove(); + if ((val & 1) && !(dev->regs[2] & 1)) + lpt1_handler(dev); + } + if (valxor & 2) { + serial_remove(dev->uart[0]); + if ((val & 2) && !(dev->regs[2] & 1)) + serial_handler(dev, 0); + } + if (valxor & 4) { + serial_remove(dev->uart[1]); + if ((val & 4) && !(dev->regs[2] & 1)) + serial_handler(dev, 1); + } + if (valxor & 0x28) { + fdc_remove(dev->fdc); + if ((val & 8) && !(dev->regs[2] & 1)) + fdc_set_base(dev->fdc, (val & 0x20) ? 0x370 : 0x3f0); + } + break; + case 1: + if (valxor & 3) { + lpt1_remove(); + if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) + lpt1_handler(dev); + } + if (valxor & 0xcc) { + serial_remove(dev->uart[0]); + if ((dev->regs[0] & 2) && !(dev->regs[2] & 1)) + serial_handler(dev, 0); + } + if (valxor & 0xf0) { + serial_remove(dev->uart[1]); + if ((dev->regs[0] & 4) && !(dev->regs[2] & 1)) + serial_handler(dev, 1); + } + break; + case 2: + if (valxor & 1) { + lpt1_remove(); + serial_remove(dev->uart[0]); + serial_remove(dev->uart[1]); + fdc_remove(dev->fdc); + + if (!(val & 1)) { + if (dev->regs[0] & 1) + lpt1_handler(dev); + if (dev->regs[0] & 2) + serial_handler(dev, 0); + if (dev->regs[0] & 4) + serial_handler(dev, 1); + if (dev->regs[0] & 8) + fdc_set_base(dev->fdc, (dev->regs[0] & 0x20) ? 0x370 : 0x3f0); + } + } + if (valxor & 8) { + lpt1_remove(); + if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) + lpt1_handler(dev); + } + break; + } +} + + +uint8_t +pc87332_read(uint16_t port, void *priv) +{ + pc87332_t *dev = (pc87332_t *) priv; + uint8_t ret = 0xff, index; + + index = (port & 1) ? 0 : 1; + + dev->tries = 0; + + if (index) + ret = dev->cur_reg & 0x1f; + else { + if (dev->cur_reg == 8) + ret = 0x10; + else if (dev->cur_reg < 14) + ret = dev->regs[dev->cur_reg]; + } + + return ret; +} + + +void +pc87332_reset(pc87332_t *dev) +{ + memset(dev->regs, 0, 15); + + dev->regs[0x00] = 0x0F; + dev->regs[0x01] = 0x10; + dev->regs[0x03] = 0x01; + dev->regs[0x05] = 0x0D; + dev->regs[0x08] = 0x70; + + /* + 0 = 360 rpm @ 500 kbps for 3.5" + 1 = Default, 300 rpm @ 500,300,250,1000 kbps for 3.5" + */ + lpt1_remove(); + lpt1_handler(dev); + serial_remove(dev->uart[0]); + serial_remove(dev->uart[1]); + serial_handler(dev, 0); + serial_handler(dev, 1); + fdc_reset(dev->fdc); +} + + +static void +pc87332_close(void *priv) +{ + pc87332_t *dev = (pc87332_t *) priv; + + free(dev); +} + + +static void * +pc87332_init(const device_t *info) +{ + pc87332_t *dev = (pc87332_t *) malloc(sizeof(pc87332_t)); + memset(dev, 0, sizeof(pc87332_t)); + + dev->fdc = device_add(&fdc_at_nsc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + // dev->nvr = device_add(&piix4_nvr_device); + + pc87332_reset(dev); + + io_sethandler(0x02e, 0x0002, + pc87332_read, NULL, NULL, pc87332_write, NULL, NULL, dev); + + return dev; +} + + +const device_t pc87332_device = { + "National Semiconductor PC87332 Super I/O", + 0, + 0, + pc87332_init, pc87332_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio_um8669f.c b/src/sio/sio_um8669f.c similarity index 100% rename from src/sio_um8669f.c rename to src/sio/sio_um8669f.c diff --git a/src/sio_w83787f.c b/src/sio/sio_w83787f.c similarity index 100% rename from src/sio_w83787f.c rename to src/sio/sio_w83787f.c diff --git a/src/sio_w83877f.c b/src/sio/sio_w83877f.c similarity index 100% rename from src/sio_w83877f.c rename to src/sio/sio_w83877f.c diff --git a/src/sio_w83977f.c b/src/sio/sio_w83977f.c similarity index 100% rename from src/sio_w83977f.c rename to src/sio/sio_w83977f.c diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 11c4a8b57..20f64b55a 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -230,7 +230,7 @@ void* fluidsynth_init(const device_t *info) #endif if (fluidsynth_handle == NULL) { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2080); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2080, (wchar_t *) IDS_2133); return NULL; } diff --git a/src/sound/munt/Analog.cpp b/src/sound/munt/Analog.cpp index 2901198f2..b14d824dd 100644 --- a/src/sound/munt/Analog.cpp +++ b/src/sound/munt/Analog.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Analog.h b/src/sound/munt/Analog.h index 3b6dcabfa..244e4118f 100644 --- a/src/sound/munt/Analog.h +++ b/src/sound/munt/Analog.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/BReverbModel.cpp b/src/sound/munt/BReverbModel.cpp index af559a92a..1eb6f7e56 100644 --- a/src/sound/munt/BReverbModel.cpp +++ b/src/sound/munt/BReverbModel.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/BReverbModel.h b/src/sound/munt/BReverbModel.h index 5b1d41198..ee2f838b2 100644 --- a/src/sound/munt/BReverbModel.h +++ b/src/sound/munt/BReverbModel.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Enumerations.h b/src/sound/munt/Enumerations.h index bb580ca5b..05a2b6f6d 100644 --- a/src/sound/munt/Enumerations.h +++ b/src/sound/munt/Enumerations.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/File.cpp b/src/sound/munt/File.cpp index a5967b4f3..dbe226648 100644 --- a/src/sound/munt/File.cpp +++ b/src/sound/munt/File.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/File.h b/src/sound/munt/File.h index 91a0a7fe6..a4b099fbb 100644 --- a/src/sound/munt/File.h +++ b/src/sound/munt/File.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/FileStream.cpp b/src/sound/munt/FileStream.cpp index 48ecc84b1..3fa1a3107 100644 --- a/src/sound/munt/FileStream.cpp +++ b/src/sound/munt/FileStream.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -15,12 +15,26 @@ * along with this program. If not, see . */ +#ifdef MT32EMU_SHARED +#include +#endif + #include "internals.h" #include "FileStream.h" namespace MT32Emu { +static inline void configureSystemLocale() { +#ifdef MT32EMU_SHARED + static bool configured = false; + + if (configured) return; + configured = true; + std::locale::global(std::locale("")); +#endif +} + using std::ios_base; FileStream::FileStream() : ifsp(*new std::ifstream), data(NULL), size(0) @@ -70,6 +84,7 @@ const Bit8u *FileStream::getData() { } bool FileStream::open(const char *filename) { + configureSystemLocale(); ifsp.clear(); ifsp.open(filename, ios_base::in | ios_base::binary); return !ifsp.fail(); diff --git a/src/sound/munt/FileStream.h b/src/sound/munt/FileStream.h index ea5de6952..2279890b4 100644 --- a/src/sound/munt/FileStream.h +++ b/src/sound/munt/FileStream.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/LA32FloatWaveGenerator.cpp b/src/sound/munt/LA32FloatWaveGenerator.cpp index 6ff4aa37b..34ea1fbf4 100644 --- a/src/sound/munt/LA32FloatWaveGenerator.cpp +++ b/src/sound/munt/LA32FloatWaveGenerator.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/LA32FloatWaveGenerator.h b/src/sound/munt/LA32FloatWaveGenerator.h index 7e92d0a67..a21d68e2b 100644 --- a/src/sound/munt/LA32FloatWaveGenerator.h +++ b/src/sound/munt/LA32FloatWaveGenerator.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/LA32Ramp.cpp b/src/sound/munt/LA32Ramp.cpp index 9dcf143fb..122ee05ac 100644 --- a/src/sound/munt/LA32Ramp.cpp +++ b/src/sound/munt/LA32Ramp.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/LA32Ramp.h b/src/sound/munt/LA32Ramp.h index 959a1ad37..802b34aa4 100644 --- a/src/sound/munt/LA32Ramp.h +++ b/src/sound/munt/LA32Ramp.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/LA32WaveGenerator.cpp b/src/sound/munt/LA32WaveGenerator.cpp index f6f692880..f4f7eeccb 100644 --- a/src/sound/munt/LA32WaveGenerator.cpp +++ b/src/sound/munt/LA32WaveGenerator.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/LA32WaveGenerator.h b/src/sound/munt/LA32WaveGenerator.h index c206daa63..d2d74f48d 100644 --- a/src/sound/munt/LA32WaveGenerator.h +++ b/src/sound/munt/LA32WaveGenerator.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/MemoryRegion.h b/src/sound/munt/MemoryRegion.h index 807f14782..c8e85c7fb 100644 --- a/src/sound/munt/MemoryRegion.h +++ b/src/sound/munt/MemoryRegion.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/MidiEventQueue.h b/src/sound/munt/MidiEventQueue.h index c5174d6cc..846f47c51 100644 --- a/src/sound/munt/MidiEventQueue.h +++ b/src/sound/munt/MidiEventQueue.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -23,20 +23,6 @@ namespace MT32Emu { -/** - * Used to safely store timestamped MIDI events in a local queue. - */ -struct MidiEvent { - Bit32u shortMessageData; - const Bit8u *sysexData; - Bit32u sysexLength; - Bit32u timestamp; - - ~MidiEvent(); - void setShortMessage(Bit32u shortMessageData, Bit32u timestamp); - void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp); -}; - /** * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it. * It is intended to: @@ -48,22 +34,38 @@ struct MidiEvent { * and one performs only writing. More complicated usage requires external synchronisation. */ class MidiEventQueue { -private: - MidiEvent * const ringBuffer; - const Bit32u ringBufferMask; - volatile Bit32u startPosition; - volatile Bit32u endPosition; - public: - MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE); // Must be a power of 2 + class SysexDataStorage; + + struct MidiEvent { + const Bit8u *sysexData; + union { + Bit32u sysexLength; + Bit32u shortMessageData; + }; + Bit32u timestamp; + }; + + explicit MidiEventQueue( + // Must be a power of 2 + Bit32u ringBufferSize, + Bit32u storageBufferSize + ); ~MidiEventQueue(); void reset(); bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp); bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp); - const MidiEvent *peekMidiEvent(); + const volatile MidiEvent *peekMidiEvent(); void dropMidiEvent(); - bool isFull() const; - bool inline isEmpty() const; + inline bool isEmpty() const; + +private: + SysexDataStorage &sysexDataStorage; + + MidiEvent * const ringBuffer; + const Bit32u ringBufferMask; + volatile Bit32u startPosition; + volatile Bit32u endPosition; }; } // namespace MT32Emu diff --git a/src/sound/munt/MidiStreamParser.cpp b/src/sound/munt/MidiStreamParser.cpp index a426a20cc..e9fbf7690 100644 --- a/src/sound/munt/MidiStreamParser.cpp +++ b/src/sound/munt/MidiStreamParser.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/MidiStreamParser.h b/src/sound/munt/MidiStreamParser.h index 881ec032f..f26fe11b7 100644 --- a/src/sound/munt/MidiStreamParser.h +++ b/src/sound/munt/MidiStreamParser.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Part.cpp b/src/sound/munt/Part.cpp index 9c85ce559..465903a72 100644 --- a/src/sound/munt/Part.cpp +++ b/src/sound/munt/Part.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Part.h b/src/sound/munt/Part.h index a4de1060b..bc2e11416 100644 --- a/src/sound/munt/Part.h +++ b/src/sound/munt/Part.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Partial.cpp b/src/sound/munt/Partial.cpp index 0b7231122..877d93b45 100644 --- a/src/sound/munt/Partial.cpp +++ b/src/sound/munt/Partial.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -21,6 +21,7 @@ #include "Partial.h" #include "Part.h" +#include "PartialManager.h" #include "Poly.h" #include "Synth.h" #include "Tables.h" @@ -36,22 +37,22 @@ static const Bit8u PAN_NUMERATOR_SLAVE[] = {0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, // We assume the pan is applied using the same 13-bit multiplier circuit that is also used for ring modulation // because of the observed sample overflow, so the panSetting values are likely mapped in a similar way via a LUT. // FIXME: Sample analysis suggests that the use of panSetting is linear, but there are some quirks that still need to be resolved. -static Bit32s getPANFactor(Bit32s panSetting) { - static const Bit32s PAN_FACTORS_COUNT = 15; +static Bit32s getPanFactor(Bit32s panSetting) { + static const Bit32u PAN_FACTORS_COUNT = 15; static Bit32s PAN_FACTORS[PAN_FACTORS_COUNT]; static bool firstRun = true; if (firstRun) { firstRun = false; - for (Bit32u i = 1; i < (Bit32u)PAN_FACTORS_COUNT; i++) { + for (Bit32u i = 1; i < PAN_FACTORS_COUNT; i++) { PAN_FACTORS[i] = Bit32s(0.5 + i * 8192.0 / double(PAN_FACTORS_COUNT - 1)); } } return PAN_FACTORS[panSetting]; } -Partial::Partial(Synth *useSynth, int useDebugPartialNum) : - synth(useSynth), debugPartialNum(useDebugPartialNum), sampleNum(0), +Partial::Partial(Synth *useSynth, int usePartialIndex) : + synth(useSynth), partialIndex(usePartialIndex), sampleNum(0), floatMode(useSynth->getSelectedRendererType() == RendererType_FLOAT) { // Initialisation of tva, tvp and tvf uses 'this' pointer // and thus should not be in the initializer list to avoid a compiler warning @@ -82,7 +83,7 @@ Partial::~Partial() { // Only used for debugging purposes int Partial::debugGetPartialNum() const { - return debugPartialNum; + return partialIndex; } // Only used for debugging purposes @@ -112,11 +113,12 @@ void Partial::deactivate() { return; } ownerPart = -1; + synth->partialManager->partialDeactivated(partialIndex); if (poly != NULL) { poly->partialDeactivated(this); } #if MT32EMU_MONITOR_PARTIALS > 2 - synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, debugPartialNum); + synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, partialIndex); synth->printPartialUsage(sampleNum); #endif if (isRingModulatingSlave()) { @@ -135,7 +137,7 @@ void Partial::deactivate() { void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *usePatchCache, const MemParams::RhythmTemp *rhythmTemp, Partial *pairPartial) { if (usePoly == NULL || usePatchCache == NULL) { - synth->printDebug("[Partial %d] *** Error: Starting partial for owner %d, usePoly=%s, usePatchCache=%s", debugPartialNum, ownerPart, usePoly == NULL ? "*** NULL ***" : "OK", usePatchCache == NULL ? "*** NULL ***" : "OK"); + synth->printDebug("[Partial %d] *** Error: Starting partial for owner %d, usePoly=%s, usePatchCache=%s", partialIndex, ownerPart, usePoly == NULL ? "*** NULL ***" : "OK", usePatchCache == NULL ? "*** NULL ***" : "OK"); return; } patchCache = usePatchCache; @@ -153,20 +155,18 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us // Do a normal mix independent of any pair partial. mixType = 0; pairPartial = NULL; - } else { + } else if (!synth->isNicePanningEnabled()) { // Mok wanted an option for smoother panning, and we love Mok. -#ifndef INACCURATE_SMOOTH_PAN - // CONFIRMED by Mok: exactly bytes like this (right shifted?) are sent to the LA32. + // CONFIRMED by Mok: exactly bytes like this (right shifted) are sent to the LA32. panSetting &= 0x0E; -#endif } leftPanValue = synth->reversedStereoEnabled ? 14 - panSetting : panSetting; rightPanValue = 14 - leftPanValue; if (!floatMode) { - leftPanValue = getPANFactor(leftPanValue); - rightPanValue = getPANFactor(rightPanValue); + leftPanValue = getPanFactor(leftPanValue); + rightPanValue = getPanFactor(rightPanValue); } // SEMI-CONFIRMED: From sample analysis: @@ -174,7 +174,7 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us // Either partial pairs are added or subtracted, it depends on how the partial pairs are allocated. // It seems that partials are grouped into quarters and if the partial pairs are allocated in different quarters the subtraction happens. // Though, this matters little for the majority of timbres, it becomes crucial for timbres which contain several partials that sound very close. - // In this case that timbre can sound totally different depending of the way it is mixed up. + // In this case that timbre can sound totally different depending on the way it is mixed up. // Most easily this effect can be displayed with the help of a special timbre consisting of several identical square wave partials (3 or 4). // Say, it is 3-partial timbre. Just play any two notes simultaneously and the polys very probably are mixed differently. // Moreover, the partial allocator retains the last partial assignment it did and all the subsequent notes will sound the same as the last released one. @@ -182,8 +182,7 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us // whole-quarter assignment or after some partials got aborted, even 4-partial timbres can be found sounding differently. // This behaviour is also confirmed with two more special timbres: one with identical sawtooth partials, and one with PCM wave 02. // For my personal taste, this behaviour rather enriches the sounding and should be emulated. - // Also, the current partial allocator model probably needs to be refined. - if (debugPartialNum & 8) { + if (!synth->isNicePartialMixingEnabled() && (partialIndex & 4)) { leftPanValue = -leftPanValue; rightPanValue = -rightPanValue; } @@ -307,7 +306,7 @@ bool Partial::canProduceOutput() { return false; } if (poly == NULL) { - synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::produceOutput()!", debugPartialNum); + synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::produceOutput()!", partialIndex); return false; } return true; diff --git a/src/sound/munt/Partial.h b/src/sound/munt/Partial.h index 95f4c3fc2..0c4355742 100644 --- a/src/sound/munt/Partial.h +++ b/src/sound/munt/Partial.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -40,13 +40,14 @@ struct ControlROMPCMStruct; class Partial { private: Synth *synth; - const int debugPartialNum; // Only used for debugging + const int partialIndex; // Index of this Partial in the global partial table // Number of the sample currently being rendered by produceOutput(), or 0 if no run is in progress // This is only kept available for debugging purposes. Bit32u sampleNum; - // Actually, this is a 4-bit register but we abuse this to emulate inverted mixing. - // Also we double the value to enable INACCURATE_SMOOTH_PAN, with respect to MoK. + // Actually, LA-32 receives only 3 bits as a pan setting, but we abuse these to emulate + // the inverted partial mixing as well. Also we double the values (making them correspond + // to the panpot range) to enable NicePanning mode, with respect to MoK. Bit32s leftPanValue, rightPanValue; int ownerPart; // -1 if unassigned diff --git a/src/sound/munt/PartialManager.cpp b/src/sound/munt/PartialManager.cpp index 6c622a9aa..508d5fa6c 100644 --- a/src/sound/munt/PartialManager.cpp +++ b/src/sound/munt/PartialManager.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -31,11 +31,14 @@ namespace MT32Emu { PartialManager::PartialManager(Synth *useSynth, Part **useParts) { synth = useSynth; parts = useParts; - partialTable = new Partial *[synth->getPartialCount()]; + inactivePartialCount = synth->getPartialCount(); + partialTable = new Partial *[inactivePartialCount]; + inactivePartials = new int[inactivePartialCount]; freePolys = new Poly *[synth->getPartialCount()]; firstFreePolyIndex = 0; for (unsigned int i = 0; i < synth->getPartialCount(); i++) { partialTable[i] = new Partial(synth, i); + inactivePartials[i] = inactivePartialCount - i - 1; freePolys[i] = new Poly(); } } @@ -46,6 +49,7 @@ PartialManager::~PartialManager(void) { if (freePolys[i] != NULL) delete freePolys[i]; } delete[] partialTable; + delete[] inactivePartials; delete[] freePolys; } @@ -83,29 +87,21 @@ unsigned int PartialManager::setReserve(Bit8u *rset) { } Partial *PartialManager::allocPartial(int partNum) { - Partial *outPartial = NULL; - - // Get the first inactive partial - for (unsigned int partialNum = 0; partialNum < synth->getPartialCount(); partialNum++) { - if (!partialTable[partialNum]->isActive()) { - outPartial = partialTable[partialNum]; - break; - } + if (inactivePartialCount > 0) { + Partial *partial = partialTable[inactivePartials[--inactivePartialCount]]; + partial->activate(partNum); + return partial; } - if (outPartial != NULL) { - outPartial->activate(partNum); + synth->printDebug("PartialManager Error: No inactive partials to allocate for part %d, current partial state:\n", partNum); + for (Bit32u i = 0; i < synth->getPartialCount(); i++) { + const Partial *partial = partialTable[i]; + synth->printDebug("[Partial %d]: activation=%d, owner part=%d\n", i, partial->isActive(), partial->getOwnerPart()); } - return outPartial; + return NULL; } -unsigned int PartialManager::getFreePartialCount(void) { - int count = 0; - for (unsigned int i = 0; i < synth->getPartialCount(); i++) { - if (!partialTable[i]->isActive()) { - count++; - } - } - return count; +unsigned int PartialManager::getFreePartialCount() { + return inactivePartialCount; } // This function is solely used to gather data for debug output at the moment. @@ -279,7 +275,7 @@ Poly *PartialManager::assignPolyToPart(Part *part) { void PartialManager::polyFreed(Poly *poly) { if (0 == firstFreePolyIndex) { - synth->printDebug("Cannot return freed poly, currently active polys:\n"); + synth->printDebug("PartialManager Error: Cannot return freed poly, currently active polys:\n"); for (Bit32u partNum = 0; partNum < 9; partNum++) { const Poly *activePoly = synth->getPart(partNum)->getFirstActivePoly(); Bit32u polyCount = 0; @@ -289,10 +285,23 @@ void PartialManager::polyFreed(Poly *poly) { } synth->printDebug("Part: %i, active poly count: %i\n", partNum, polyCount); } + } else { + firstFreePolyIndex--; + freePolys[firstFreePolyIndex] = poly; } poly->setPart(NULL); - firstFreePolyIndex--; - freePolys[firstFreePolyIndex] = poly; +} + +void PartialManager::partialDeactivated(int partialIndex) { + if (inactivePartialCount < synth->getPartialCount()) { + inactivePartials[inactivePartialCount++] = partialIndex; + return; + } + synth->printDebug("PartialManager Error: Cannot return deactivated partial %d, current partial state:\n", partialIndex); + for (Bit32u i = 0; i < synth->getPartialCount(); i++) { + const Partial *partial = partialTable[i]; + synth->printDebug("[Partial %d]: activation=%d, owner part=%d\n", i, partial->isActive(), partial->getOwnerPart()); + } } } // namespace MT32Emu diff --git a/src/sound/munt/PartialManager.h b/src/sound/munt/PartialManager.h index 46d8eeb98..6b59857cc 100644 --- a/src/sound/munt/PartialManager.h +++ b/src/sound/munt/PartialManager.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -37,6 +37,8 @@ private: Partial **partialTable; Bit8u numReservedPartialsForPart[9]; Bit32u firstFreePolyIndex; + int *inactivePartials; // Holds indices of inactive Partials in the Partial table + Bit32u inactivePartialCount; bool abortFirstReleasingPolyWhereReserveExceeded(int minPart); bool abortFirstPolyPreferHeldWhereReserveExceeded(int minPart); @@ -45,7 +47,7 @@ public: PartialManager(Synth *synth, Part **parts); ~PartialManager(); Partial *allocPartial(int partNum); - unsigned int getFreePartialCount(void); + unsigned int getFreePartialCount(); void getPerPartPartialUsage(unsigned int perPartPartialUsage[9]); bool freePartials(unsigned int needed, int partNum); unsigned int setReserve(Bit8u *rset); @@ -57,6 +59,7 @@ public: const Partial *getPartial(unsigned int partialNum) const; Poly *assignPolyToPart(Part *part); void polyFreed(Poly *poly); + void partialDeactivated(int partialIndex); }; // class PartialManager } // namespace MT32Emu diff --git a/src/sound/munt/Poly.cpp b/src/sound/munt/Poly.cpp index 44b8d2446..f37e471d4 100644 --- a/src/sound/munt/Poly.cpp +++ b/src/sound/munt/Poly.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Poly.h b/src/sound/munt/Poly.h index b2d4eceaf..5b7cc30e4 100644 --- a/src/sound/munt/Poly.h +++ b/src/sound/munt/Poly.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/ROMInfo.cpp b/src/sound/munt/ROMInfo.cpp index 8c813a4e6..308d3eb1e 100644 --- a/src/sound/munt/ROMInfo.cpp +++ b/src/sound/munt/ROMInfo.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/ROMInfo.h b/src/sound/munt/ROMInfo.h index cd4a1c5ac..b695ba2a1 100644 --- a/src/sound/munt/ROMInfo.h +++ b/src/sound/munt/ROMInfo.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/SampleRateConverter.cpp b/src/sound/munt/SampleRateConverter.cpp index 2d7866ba6..9ae35e962 100644 --- a/src/sound/munt/SampleRateConverter.cpp +++ b/src/sound/munt/SampleRateConverter.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -14,13 +14,15 @@ * along with this program. If not, see . */ +#include + #include "SampleRateConverter.h" #if MT32EMU_WITH_LIBSOXR_RESAMPLER #include "srchelper/SoxrAdapter.h" #elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER #include "srchelper/SamplerateAdapter.h" -#else +#elif MT32EMU_WITH_INTERNAL_RESAMPLER #include "srchelper/InternalResampler.h" #endif @@ -33,8 +35,11 @@ static inline void *createDelegate(Synth &synth, double targetSampleRate, Sample return new SoxrAdapter(synth, targetSampleRate, quality); #elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER return new SamplerateAdapter(synth, targetSampleRate, quality); -#else +#elif MT32EMU_WITH_INTERNAL_RESAMPLER return new InternalResampler(synth, targetSampleRate, quality); +#else + (void)synth, (void)targetSampleRate, (void)quality; + return NULL; #endif } @@ -47,6 +52,15 @@ AnalogOutputMode SampleRateConverter::getBestAnalogOutputMode(double targetSampl return AnalogOutputMode_COARSE; } +double SampleRateConverter::getSupportedOutputSampleRate(double desiredSampleRate) { +#if MT32EMU_WITH_LIBSOXR_RESAMPLER || MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER || MT32EMU_WITH_INTERNAL_RESAMPLER + return desiredSampleRate > 0 ? desiredSampleRate : 0; +#else + (void)desiredSampleRate; + return 0; +#endif +} + SampleRateConverter::SampleRateConverter(Synth &useSynth, double targetSampleRate, SamplerateConversionQuality useQuality) : synthInternalToTargetSampleRateRatio(SAMPLE_RATE / targetSampleRate), useSynthDelegate(useSynth.getStereoOutputSampleRate() == targetSampleRate), @@ -59,7 +73,7 @@ SampleRateConverter::~SampleRateConverter() { delete static_cast(srcDelegate); #elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER delete static_cast(srcDelegate); -#else +#elif MT32EMU_WITH_INTERNAL_RESAMPLER delete static_cast(srcDelegate); #endif } @@ -75,8 +89,10 @@ void SampleRateConverter::getOutputSamples(float *buffer, unsigned int length) { static_cast(srcDelegate)->getOutputSamples(buffer, length); #elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER static_cast(srcDelegate)->getOutputSamples(buffer, length); -#else +#elif MT32EMU_WITH_INTERNAL_RESAMPLER static_cast(srcDelegate)->getOutputSamples(buffer, length); +#else + Synth::muteSampleBuffer(buffer, length); #endif } diff --git a/src/sound/munt/SampleRateConverter.h b/src/sound/munt/SampleRateConverter.h index 437f9b29f..96f3925e3 100644 --- a/src/sound/munt/SampleRateConverter.h +++ b/src/sound/munt/SampleRateConverter.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -37,6 +37,10 @@ public: // at the sample rate specified by the targetSampleRate argument. static AnalogOutputMode getBestAnalogOutputMode(double targetSampleRate); + // Returns the sample rate supported by the sample rate conversion implementation currently in effect + // that is closest to the one specified by the desiredSampleRate argument. + static double getSupportedOutputSampleRate(double desiredSampleRate); + // Creates a SampleRateConverter instance that converts output signal from the synth to the given sample rate // with the specified conversion quality. SampleRateConverter(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality); diff --git a/src/sound/munt/Structures.h b/src/sound/munt/Structures.h index d116aaeb4..de7281b16 100644 --- a/src/sound/munt/Structures.h +++ b/src/sound/munt/Structures.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Synth.cpp b/src/sound/munt/Synth.cpp index f4eda5c79..d61ad44a6 100644 --- a/src/sound/munt/Synth.cpp +++ b/src/sound/munt/Synth.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -195,6 +195,20 @@ public: RendererType selectedRendererType; Bit32s masterTunePitchDelta; bool niceAmpRamp; + bool nicePanning; + bool nicePartialMixing; + + // Here we keep the reverse mapping of assigned parts per MIDI channel. + // NOTE: value above 8 means that the channel is not assigned + Bit8u chantable[16][9]; + + // This stores the index of Part in chantable that failed to play and required partial abortion. + Bit32u abortingPartIx; + + bool preallocatedReverbMemory; + + Bit32u midiEventQueueSize; + Bit32u midiEventQueueSysexStorageBufferSize; }; Bit32u Synth::getLibraryVersionInt() { @@ -238,7 +252,8 @@ Synth::Synth(ReportHandler *useReportHandler) : isDefaultReportHandler = false; } - for (int i = 0; i < 4; i++) { + extensions.preallocatedReverbMemory = false; + for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) { reverbModels[i] = NULL; } reverbModel = NULL; @@ -250,6 +265,8 @@ Synth::Synth(ReportHandler *useReportHandler) : setReverbOutputGain(1.0f); setReversedStereoEnabled(false); setNiceAmpRampEnabled(true); + setNicePanningEnabled(false); + setNicePartialMixingEnabled(false); selectRendererType(RendererType_BIT16S); patchTempMemoryRegion = NULL; @@ -267,6 +284,8 @@ Synth::Synth(ReportHandler *useReportHandler) : pcmROMData = NULL; soundGroupNames = NULL; midiQueue = NULL; + extensions.midiEventQueueSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE; + extensions.midiEventQueueSysexStorageBufferSize = 0; lastReceivedMIDIEventTimestamp = 0; memset(parts, 0, sizeof(parts)); renderedSampleCount = 0; @@ -313,15 +332,26 @@ void Synth::newTimbreSet(Bit8u partNum, Bit8u timbreGroup, Bit8u timbreNumber, c reportHandler->onProgramChanged(partNum, soundGroupName, patchName); } -void Synth::printDebug(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); -#if MT32EMU_DEBUG_SAMPLESTAMPS > 0 - reportHandler->printDebug("[%u]", (va_list)&renderedSampleCount); -#endif - reportHandler->printDebug(fmt, ap); +#define MT32EMU_PRINT_DEBUG \ + va_list ap; \ + va_start(ap, fmt); \ + reportHandler->printDebug(fmt, ap); \ va_end(ap); + +#if MT32EMU_DEBUG_SAMPLESTAMPS > 0 +static inline void printSamplestamp(ReportHandler *reportHandler, const char *fmt, ...) { + MT32EMU_PRINT_DEBUG } +#endif + +void Synth::printDebug(const char *fmt, ...) { +#if MT32EMU_DEBUG_SAMPLESTAMPS > 0 + printSamplestamp(reportHandler, "[%u]", renderedSampleCount); +#endif + MT32EMU_PRINT_DEBUG +} + +#undef MT32EMU_PRINT_DEBUG void Synth::setReverbEnabled(bool newReverbEnabled) { if (!opened) return; @@ -332,9 +362,9 @@ void Synth::setReverbEnabled(bool newReverbEnabled) { refreshSystemReverbParameters(); reverbOverridden = oldReverbOverridden; } else { -#if MT32EMU_REDUCE_REVERB_MEMORY - reverbModel->close(); -#endif + if (!extensions.preallocatedReverbMemory) { + reverbModel->close(); + } reverbModel = NULL; } } @@ -355,7 +385,7 @@ void Synth::setReverbCompatibilityMode(bool mt32CompatibleMode) { if (!opened || (isMT32ReverbCompatibilityMode() == mt32CompatibleMode)) return; bool oldReverbEnabled = isReverbEnabled(); setReverbEnabled(false); - for (int i = 0; i < 4; i++) { + for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) { delete reverbModels[i]; } initReverbModels(mt32CompatibleMode); @@ -371,6 +401,19 @@ bool Synth::isDefaultReverbMT32Compatible() const { return opened && controlROMFeatures->defaultReverbMT32Compatible; } +void Synth::preallocateReverbMemory(bool enabled) { + if (extensions.preallocatedReverbMemory == enabled) return; + extensions.preallocatedReverbMemory = enabled; + if (!opened) return; + for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) { + if (enabled) { + reverbModels[i]->open(); + } else if (reverbModel != reverbModels[i]) { + reverbModels[i]->close(); + } + } +} + void Synth::setDACInputMode(DACInputMode mode) { dacInputMode = mode; } @@ -423,6 +466,22 @@ bool Synth::isNiceAmpRampEnabled() const { return extensions.niceAmpRamp; } +void Synth::setNicePanningEnabled(bool enabled) { + extensions.nicePanning = enabled; +} + +bool Synth::isNicePanningEnabled() const { + return extensions.nicePanning; +} + +void Synth::setNicePartialMixingEnabled(bool enabled) { + extensions.nicePartialMixing = enabled; +} + +bool Synth::isNicePartialMixingEnabled() const { + return extensions.nicePartialMixing; +} + bool Synth::loadControlROM(const ROMImage &controlROMImage) { File *file = controlROMImage.getFile(); const ROMInfo *controlROMInfo = controlROMImage.getROMInfo(); @@ -565,15 +624,13 @@ bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, Bit16u count, Bit16u s } void Synth::initReverbModels(bool mt32CompatibleMode) { - reverbModels[REVERB_MODE_ROOM] = BReverbModel::createBReverbModel(REVERB_MODE_ROOM, mt32CompatibleMode, getSelectedRendererType()); - reverbModels[REVERB_MODE_HALL] = BReverbModel::createBReverbModel(REVERB_MODE_HALL, mt32CompatibleMode, getSelectedRendererType()); - reverbModels[REVERB_MODE_PLATE] = BReverbModel::createBReverbModel(REVERB_MODE_PLATE, mt32CompatibleMode, getSelectedRendererType()); - reverbModels[REVERB_MODE_TAP_DELAY] = BReverbModel::createBReverbModel(REVERB_MODE_TAP_DELAY, mt32CompatibleMode, getSelectedRendererType()); -#if !MT32EMU_REDUCE_REVERB_MEMORY - for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) { - reverbModels[i]->open(); + for (int mode = REVERB_MODE_ROOM; mode <= REVERB_MODE_TAP_DELAY; mode++) { + reverbModels[mode] = BReverbModel::createBReverbModel(ReverbMode(mode), mt32CompatibleMode, getSelectedRendererType()); + + if (extensions.preallocatedReverbMemory) { + reverbModels[mode]->open(); + } } -#endif } void Synth::initSoundGroups(char newSoundGroupNames[][9]) { @@ -594,6 +651,7 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, B } partialCount = usePartialCount; abortingPoly = NULL; + extensions.abortingPartIx = 0; // This is to help detect bugs memset(&mt32ram, '?', sizeof(mt32ram)); @@ -751,7 +809,7 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, B // For resetting mt32 mid-execution mt32default = mt32ram; - midiQueue = new MidiEventQueue(); + midiQueue = new MidiEventQueue(extensions.midiEventQueueSize, extensions.midiEventQueueSysexStorageBufferSize); analog = Analog::createAnalog(analogOutputMode, controlROMFeatures->oldMT32AnalogLPF, getSelectedRendererType()); #if MT32EMU_MONITOR_INIT @@ -820,7 +878,7 @@ void Synth::dispose() { deleteMemoryRegions(); - for (int i = 0; i < 4; i++) { + for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) { delete reverbModels[i]; reverbModels[i] = NULL; } @@ -840,26 +898,24 @@ bool Synth::isOpen() const { } void Synth::flushMIDIQueue() { - if (midiQueue != NULL) { - for (;;) { - const MidiEvent *midiEvent = midiQueue->peekMidiEvent(); - if (midiEvent == NULL) break; - if (midiEvent->sysexData == NULL) { - playMsgNow(midiEvent->shortMessageData); - } else { - playSysexNow(midiEvent->sysexData, midiEvent->sysexLength); - } - midiQueue->dropMidiEvent(); + if (midiQueue == NULL) return; + for (;;) { + const volatile MidiEventQueue::MidiEvent *midiEvent = midiQueue->peekMidiEvent(); + if (midiEvent == NULL) break; + if (midiEvent->sysexData == NULL) { + playMsgNow(midiEvent->shortMessageData); + } else { + playSysexNow(midiEvent->sysexData, midiEvent->sysexLength); } - lastReceivedMIDIEventTimestamp = renderedSampleCount; + midiQueue->dropMidiEvent(); } + lastReceivedMIDIEventTimestamp = renderedSampleCount; } Bit32u Synth::setMIDIEventQueueSize(Bit32u useSize) { static const Bit32u MAX_QUEUE_SIZE = (1 << 24); // This results in about 256 Mb - much greater than any reasonable value - if (midiQueue == NULL) return 0; - flushMIDIQueue(); + if (extensions.midiEventQueueSize == useSize) return useSize; // Find a power of 2 that is >= useSize Bit32u binarySize = 1; @@ -869,11 +925,26 @@ Bit32u Synth::setMIDIEventQueueSize(Bit32u useSize) { } else { binarySize = MAX_QUEUE_SIZE; } - delete midiQueue; - midiQueue = new MidiEventQueue(binarySize); + extensions.midiEventQueueSize = binarySize; + if (midiQueue != NULL) { + flushMIDIQueue(); + delete midiQueue; + midiQueue = new MidiEventQueue(binarySize, extensions.midiEventQueueSysexStorageBufferSize); + } return binarySize; } +void Synth::configureMIDIEventQueueSysexStorage(Bit32u storageBufferSize) { + if (extensions.midiEventQueueSysexStorageBufferSize == storageBufferSize) return; + + extensions.midiEventQueueSysexStorageBufferSize = storageBufferSize; + if (midiQueue != NULL) { + flushMIDIQueue(); + delete midiQueue; + midiQueue = new MidiEventQueue(extensions.midiEventQueueSize, storageBufferSize); + } +} + Bit32u Synth::getShortMessageLength(Bit32u msg) { if ((msg & 0xF0) == 0xF0) { switch (msg & 0xFF) { @@ -955,14 +1026,24 @@ void Synth::playMsgNow(Bit32u msg) { //printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note); - Bit8u part = chantable[chan]; - if (part > 8) { + Bit8u *chanParts = extensions.chantable[chan]; + if (*chanParts > 8) { #if MT32EMU_MONITOR_MIDI > 0 - printDebug("Play msg on unreg chan %d (%d): code=0x%01x, vel=%d", chan, part, code, velocity); + printDebug("Play msg on unreg chan %d (%d): code=0x%01x, vel=%d", chan, *chanParts, code, velocity); #endif return; } - playMsgOnPart(part, code, note, velocity); + for (Bit32u i = extensions.abortingPartIx; i <= 8; i++) { + const Bit32u partNum = chanParts[i]; + if (partNum > 8) break; + playMsgOnPart(partNum, code, note, velocity); + if (isAbortingPoly()) { + extensions.abortingPartIx = i; + break; + } else if (extensions.abortingPartIx) { + extensions.abortingPartIx = 0; + } + } } void Synth::playMsgOnPart(Bit8u part, Bit8u code, Bit8u note, Bit8u velocity) { @@ -1153,7 +1234,7 @@ void Synth::playSysexWithoutHeader(Bit8u device, Bit8u command, const Bit8u *sys break; } */ - // Deliberate fall-through + // Fall-through case SYSEX_CMD_DT1: writeSysex(device, sysex, len); break; @@ -1163,7 +1244,7 @@ void Synth::playSysexWithoutHeader(Bit8u device, Bit8u command, const Bit8u *sys // FIXME: We should send SYSEX_CMD_RJC in this case break; } - // Deliberate fall-through + // Fall-through case SYSEX_CMD_RQ1: readSysex(device, sysex, len); break; @@ -1193,45 +1274,59 @@ void Synth::writeSysex(Bit8u device, const Bit8u *sysex, Bit32u len) { printDebug("WRITE-CHANNEL: Channel %d temp area 0x%06x", device, MT32EMU_SYSEXMEMADDR(addr)); #endif if (/*addr >= MT32EMU_MEMADDR(0x000000) && */addr < MT32EMU_MEMADDR(0x010000)) { - int offset; - if (chantable[device] > 8) { + addr += MT32EMU_MEMADDR(0x030000); + Bit8u *chanParts = extensions.chantable[device]; + if (*chanParts > 8) { #if MT32EMU_MONITOR_SYSEX > 0 printDebug(" (Channel not mapped to a part... 0 offset)"); #endif - offset = 0; - } else if (chantable[device] == 8) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Channel mapped to rhythm... 0 offset)"); -#endif - offset = 0; } else { - offset = chantable[device] * sizeof(MemParams::PatchTemp); + for (Bit32u partIx = 0; partIx <= 8; partIx++) { + if (chanParts[partIx] > 8) break; + int offset; + if (chanParts[partIx] == 8) { #if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Setting extra offset to %d)", offset); + printDebug(" (Channel mapped to rhythm... 0 offset)"); #endif + offset = 0; + } else { + offset = chanParts[partIx] * sizeof(MemParams::PatchTemp); +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Setting extra offset to %d)", offset); +#endif + } + writeSysexGlobal(addr + offset, sysex, len); + } + return; } - addr += MT32EMU_MEMADDR(0x030000) + offset; } else if (/*addr >= MT32EMU_MEMADDR(0x010000) && */ addr < MT32EMU_MEMADDR(0x020000)) { addr += MT32EMU_MEMADDR(0x030110) - MT32EMU_MEMADDR(0x010000); } else if (/*addr >= MT32EMU_MEMADDR(0x020000) && */ addr < MT32EMU_MEMADDR(0x030000)) { - int offset; - if (chantable[device] > 8) { + addr += MT32EMU_MEMADDR(0x040000) - MT32EMU_MEMADDR(0x020000); + Bit8u *chanParts = extensions.chantable[device]; + if (*chanParts > 8) { #if MT32EMU_MONITOR_SYSEX > 0 printDebug(" (Channel not mapped to a part... 0 offset)"); #endif - offset = 0; - } else if (chantable[device] == 8) { -#if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Channel mapped to rhythm... 0 offset)"); -#endif - offset = 0; } else { - offset = chantable[device] * sizeof(TimbreParam); + for (Bit32u partIx = 0; partIx <= 8; partIx++) { + if (chanParts[partIx] > 8) break; + int offset; + if (chanParts[partIx] == 8) { #if MT32EMU_MONITOR_SYSEX > 0 - printDebug(" (Setting extra offset to %d)", offset); + printDebug(" (Channel mapped to rhythm... 0 offset)"); #endif + offset = 0; + } else { + offset = chanParts[partIx] * sizeof(TimbreParam); +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Setting extra offset to %d)", offset); +#endif + } + writeSysexGlobal(addr + offset, sysex, len); + } + return; } - addr += MT32EMU_MEMADDR(0x040000) - MT32EMU_MEMADDR(0x020000) + offset; } else { #if MT32EMU_MONITOR_SYSEX > 0 printDebug(" Invalid channel"); @@ -1239,8 +1334,11 @@ void Synth::writeSysex(Bit8u device, const Bit8u *sysex, Bit32u len) { return; } } + writeSysexGlobal(addr, sysex, len); +} - // Process device-global sysex (possibly converted from channel-specific sysex above) +// Process device-global sysex (possibly converted from channel-specific sysex above) +void Synth::writeSysexGlobal(Bit32u addr, const Bit8u *sysex, Bit32u len) { for (;;) { // Find the appropriate memory region const MemoryRegion *region = findMemoryRegion(addr); @@ -1429,7 +1527,7 @@ void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u le char instrumentName[11]; memcpy(instrumentName, mt32ram.timbres[patchAbsTimbreNum].timbre.common.name, 10); instrumentName[10] = 0; - Bit8u *n = (Bit8u *)patch; + Bit8u *n = reinterpret_cast(patch); printDebug("WRITE-PATCH (%d-%d@%d..%d): %d; timbre=%d (%s) %02X%02X%02X%02X%02X%02X%02X%02X", first, last, off, off + len, i, patchAbsTimbreNum, instrumentName, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]); } #endif @@ -1614,18 +1712,18 @@ void Synth::refreshSystemReverbParameters() { reverbModel = reverbModels[mt32ram.system.reverbMode]; } if (reverbModel != oldReverbModel) { -#if MT32EMU_REDUCE_REVERB_MEMORY - if (oldReverbModel != NULL) { - oldReverbModel->close(); + if (extensions.preallocatedReverbMemory) { + if (isReverbEnabled()) { + reverbModel->mute(); + } + } else { + if (oldReverbModel != NULL) { + oldReverbModel->close(); + } + if (isReverbEnabled()) { + reverbModel->open(); + } } - if (isReverbEnabled()) { - reverbModel->open(); - } -#else - if (isReverbEnabled()) { - reverbModel->mute(); - } -#endif } if (isReverbEnabled()) { reverbModel->setParameters(mt32ram.system.reverbTime, mt32ram.system.reverbLevel); @@ -1641,9 +1739,10 @@ void Synth::refreshSystemReserveSettings() { } void Synth::refreshSystemChanAssign(Bit8u firstPart, Bit8u lastPart) { - memset(chantable, 0xFF, sizeof(chantable)); + memset(extensions.chantable, 0xFF, sizeof(extensions.chantable)); - // CONFIRMED: In the case of assigning a channel to multiple parts, the lower part wins. + // CONFIRMED: In the case of assigning a MIDI channel to multiple parts, + // the messages received on that MIDI channel are handled by all the parts. for (Bit32u i = 0; i <= 8; i++) { if (parts[i] != NULL && i >= firstPart && i <= lastPart) { // CONFIRMED: Decay is started for all polys, and all controllers are reset, for every part whose assignment was touched by the sysex write. @@ -1651,8 +1750,13 @@ void Synth::refreshSystemChanAssign(Bit8u firstPart, Bit8u lastPart) { parts[i]->resetAllControllers(); } Bit8u chan = mt32ram.system.chanAssign[i]; - if (chan < 16 && chantable[chan] > 8) { - chantable[chan] = Bit8u(i); + if (chan > 15) continue; + Bit8u *chanParts = extensions.chantable[chan]; + for (Bit32u j = 0; j <= 8; j++) { + if (chanParts[j] > 8) { + chanParts[j] = Bit8u(i); + break; + } } } @@ -1712,40 +1816,120 @@ Bit32s Synth::getMasterTunePitchDelta() const { return extensions.masterTunePitchDelta; } -MidiEvent::~MidiEvent() { - if (sysexData != NULL) { +/** Defines an interface of a class that maintains storage of variable-sized data of SysEx messages. */ +class MidiEventQueue::SysexDataStorage { +public: + static MidiEventQueue::SysexDataStorage *create(Bit32u storageBufferSize); + + virtual ~SysexDataStorage() {} + virtual Bit8u *allocate(Bit32u sysexLength) = 0; + virtual void reclaimUnused(const Bit8u *sysexData, Bit32u sysexLength) = 0; + virtual void dispose(const Bit8u *sysexData, Bit32u sysexLength) = 0; +}; + +/** Storage space for SysEx data is allocated dynamically on demand and is disposed lazily. */ +class DynamicSysexDataStorage : public MidiEventQueue::SysexDataStorage { +public: + Bit8u *allocate(Bit32u sysexLength) { + return new Bit8u[sysexLength]; + } + + void reclaimUnused(const Bit8u *, Bit32u) {} + + void dispose(const Bit8u *sysexData, Bit32u) { delete[] sysexData; } +}; + +/** + * SysEx data is stored in a preallocated buffer, that makes this kind of storage safe + * for use in a realtime thread. Additionally, the space retained by a SysEx event, + * that has been processed and thus is no longer necessary, is disposed instantly. + */ +class BufferedSysexDataStorage : public MidiEventQueue::SysexDataStorage { +public: + explicit BufferedSysexDataStorage(Bit32u useStorageBufferSize) : + storageBuffer(new Bit8u[useStorageBufferSize]), + storageBufferSize(useStorageBufferSize), + startPosition(), + endPosition() + {} + + ~BufferedSysexDataStorage() { + delete[] storageBuffer; + } + + Bit8u *allocate(Bit32u sysexLength) { + Bit32u myStartPosition = startPosition; + Bit32u myEndPosition = endPosition; + + // When the free space isn't contiguous, the data is allocated either right after the end position + // or at the buffer beginning, wherever it fits. + if (myStartPosition > myEndPosition) { + if (myStartPosition - myEndPosition <= sysexLength) return NULL; + } else if (storageBufferSize - myEndPosition < sysexLength) { + // There's not enough free space at the end to place the data block. + if (myStartPosition == myEndPosition) { + // The buffer is empty -> reset positions to the buffer beginning. + if (storageBufferSize <= sysexLength) return NULL; + if (myStartPosition != 0) { + myStartPosition = 0; + // It's OK to write startPosition here non-atomically. We don't expect any + // concurrent reads, as there must be no SysEx messages in the queue. + startPosition = myStartPosition; + } + } else if (myStartPosition <= sysexLength) return NULL; + myEndPosition = 0; + } + endPosition = myEndPosition + sysexLength; + return storageBuffer + myEndPosition; + } + + void reclaimUnused(const Bit8u *sysexData, Bit32u sysexLength) { + if (sysexData == NULL) return; + Bit32u allocatedPosition = startPosition; + if (storageBuffer + allocatedPosition == sysexData) { + startPosition = allocatedPosition + sysexLength; + } else if (storageBuffer == sysexData) { + // Buffer wrapped around. + startPosition = sysexLength; + } + } + + void dispose(const Bit8u *, Bit32u) {} + +private: + Bit8u * const storageBuffer; + const Bit32u storageBufferSize; + + volatile Bit32u startPosition; + volatile Bit32u endPosition; +}; + +MidiEventQueue::SysexDataStorage *MidiEventQueue::SysexDataStorage::create(Bit32u storageBufferSize) { + if (storageBufferSize > 0) { + return new BufferedSysexDataStorage(storageBufferSize); + } else { + return new DynamicSysexDataStorage; + } } -void MidiEvent::setShortMessage(Bit32u useShortMessageData, Bit32u useTimestamp) { - if (sysexData != NULL) { - delete[] sysexData; +MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize, Bit32u storageBufferSize) : + sysexDataStorage(*SysexDataStorage::create(storageBufferSize)), + ringBuffer(new MidiEvent[useRingBufferSize]), ringBufferMask(useRingBufferSize - 1) +{ + for (Bit32u i = 0; i <= ringBufferMask; i++) { + ringBuffer[i].sysexData = NULL; } - shortMessageData = useShortMessageData; - timestamp = useTimestamp; - sysexData = NULL; - sysexLength = 0; -} - -void MidiEvent::setSysex(const Bit8u *useSysexData, Bit32u useSysexLength, Bit32u useTimestamp) { - if (sysexData != NULL) { - delete[] sysexData; - } - shortMessageData = 0; - timestamp = useTimestamp; - sysexLength = useSysexLength; - Bit8u *dstSysexData = new Bit8u[sysexLength]; - sysexData = dstSysexData; - memcpy(dstSysexData, useSysexData, sysexLength); -} - -MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBuffer(new MidiEvent[useRingBufferSize]), ringBufferMask(useRingBufferSize - 1) { - memset(ringBuffer, 0, useRingBufferSize * sizeof(MidiEvent)); reset(); } MidiEventQueue::~MidiEventQueue() { + for (Bit32u i = 0; i <= ringBufferMask; i++) { + volatile MidiEvent ¤tEvent = ringBuffer[i]; + sysexDataStorage.dispose(currentEvent.sysexData, currentEvent.sysexLength); + } + delete &sysexDataStorage; delete[] ringBuffer; } @@ -1756,35 +1940,42 @@ void MidiEventQueue::reset() { bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp) { Bit32u newEndPosition = (endPosition + 1) & ringBufferMask; - // Is ring buffer full? + // If ring buffer is full, bail out. if (startPosition == newEndPosition) return false; - ringBuffer[endPosition].setShortMessage(shortMessageData, timestamp); + volatile MidiEvent &newEvent = ringBuffer[endPosition]; + sysexDataStorage.dispose(newEvent.sysexData, newEvent.sysexLength); + newEvent.sysexData = NULL; + newEvent.shortMessageData = shortMessageData; + newEvent.timestamp = timestamp; endPosition = newEndPosition; return true; } bool MidiEventQueue::pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp) { Bit32u newEndPosition = (endPosition + 1) & ringBufferMask; - // Is ring buffer full? + // If ring buffer is full, bail out. if (startPosition == newEndPosition) return false; - ringBuffer[endPosition].setSysex(sysexData, sysexLength, timestamp); + volatile MidiEvent &newEvent = ringBuffer[endPosition]; + sysexDataStorage.dispose(newEvent.sysexData, newEvent.sysexLength); + Bit8u *dstSysexData = sysexDataStorage.allocate(sysexLength); + if (dstSysexData == NULL) return false; + memcpy(dstSysexData, sysexData, sysexLength); + newEvent.sysexData = dstSysexData; + newEvent.sysexLength = sysexLength; + newEvent.timestamp = timestamp; endPosition = newEndPosition; return true; } -const MidiEvent *MidiEventQueue::peekMidiEvent() { +const volatile MidiEventQueue::MidiEvent *MidiEventQueue::peekMidiEvent() { return isEmpty() ? NULL : &ringBuffer[startPosition]; } void MidiEventQueue::dropMidiEvent() { - // Is ring buffer empty? - if (startPosition != endPosition) { - startPosition = (startPosition + 1) & ringBufferMask; - } -} - -bool MidiEventQueue::isFull() const { - return startPosition == ((endPosition + 1) & ringBufferMask); + if (isEmpty()) return; + volatile MidiEvent &unusedEvent = ringBuffer[startPosition]; + sysexDataStorage.reclaimUnused(unusedEvent.sysexData, unusedEvent.sysexLength); + startPosition = (startPosition + 1) & ringBufferMask; } bool MidiEventQueue::isEmpty() const { @@ -1923,7 +2114,7 @@ void RendererImpl::doRenderStreams(const DACOutputStreams &strea // We need to ensure zero-duration notes will play so add minimum 1-sample delay. Bit32u thisLen = 1; if (!isAbortingPoly()) { - const MidiEvent *nextEvent = getMidiQueue().peekMidiEvent(); + const volatile MidiEventQueue::MidiEvent *nextEvent = getMidiQueue().peekMidiEvent(); Bit32s samplesToNextEvent = (nextEvent != NULL) ? Bit32s(nextEvent->timestamp - getRenderedSampleCount()) : MAX_SAMPLES_PER_RUN; if (samplesToNextEvent > 0) { thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len; diff --git a/src/sound/munt/Synth.h b/src/sound/munt/Synth.h index cde080c9d..65f2656e6 100644 --- a/src/sound/munt/Synth.h +++ b/src/sound/munt/Synth.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -115,6 +115,7 @@ public: class Synth { friend class DefaultMidiStreamParser; +friend class MemoryRegion; friend class Part; friend class Partial; friend class PartialManager; @@ -153,7 +154,7 @@ private: const char (*soundGroupNames)[9]; // Array Bit32u partialCount; - Bit8u chantable[16]; // NOTE: value above 8 means that the channel is not assigned + Bit8u nukeme[16]; // FIXME: Nuke it. For binary compatibility only. MidiEventQueue *midiQueue; volatile Bit32u lastReceivedMIDIEventTimestamp; @@ -198,6 +199,7 @@ private: Bit32u addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp); bool isAbortingPoly() const { return abortingPoly != NULL; } + void writeSysexGlobal(Bit32u addr, const Bit8u *sysex, Bit32u len); void readSysex(Bit8u channel, const Bit8u *sysex, Bit32u len) const; void initMemoryRegions(); void deleteMemoryRegions(); @@ -310,7 +312,18 @@ public: // Sets size of the internal MIDI event queue. The queue size is set to the minimum power of 2 that is greater or equal to the size specified. // The queue is flushed before reallocation. // Returns the actual queue size being used. - MT32EMU_EXPORT Bit32u setMIDIEventQueueSize(Bit32u); + MT32EMU_EXPORT Bit32u setMIDIEventQueueSize(Bit32u requestedSize); + + // Configures the SysEx storage of the internal MIDI event queue. + // Supplying 0 in the storageBufferSize argument makes the SysEx data stored + // in multiple dynamically allocated buffers per MIDI event. These buffers are only disposed + // when a new MIDI event replaces the SysEx event in the queue, thus never on the rendering thread. + // This is the default behaviour. + // In contrast, when a positive value is specified, SysEx data will be stored in a single preallocated buffer, + // which makes this kind of storage safe for use in a realtime thread. Additionally, the space retained + // by a SysEx event, that has been processed and thus is no longer necessary, is disposed instantly. + // Note, the queue is flushed and recreated in the process so that its size remains intact. + MT32EMU_EXPORT void configureMIDIEventQueueSysexStorage(Bit32u storageBufferSize); // Returns current value of the global counter of samples rendered since the synth was created (at the native sample rate 32000 Hz). // This method helps to compute accurate timestamp of a MIDI message to use with the methods below. @@ -378,6 +391,10 @@ public: MT32EMU_EXPORT bool isMT32ReverbCompatibilityMode() const; // Returns whether default reverb compatibility mode is the old MT-32 compatibility mode. MT32EMU_EXPORT bool isDefaultReverbMT32Compatible() const; + // If enabled, reverb buffers for all modes are keept around allocated all the time to avoid memory + // allocating/freeing in the rendering thread, which may be required for realtime operation. + // Otherwise, reverb buffers that are not in use are deleted to save memory (the default behaviour). + MT32EMU_EXPORT void preallocateReverbMemory(bool enabled); // Sets new DAC input mode. See DACInputMode for details. MT32EMU_EXPORT void setDACInputMode(DACInputMode mode); // Returns current DAC input mode. See DACInputMode for details. @@ -421,6 +438,29 @@ public: // Returns whether NiceAmpRamp mode is enabled. MT32EMU_EXPORT bool isNiceAmpRampEnabled() const; + // Allows to toggle the NicePanning mode. + // Despite the Roland's manual specifies allowed panpot values in range 0-14, + // the LA-32 only receives 3-bit pan setting in fact. In particular, this + // makes it impossible to set the "middle" panning for a single partial. + // In the NicePanning mode, we enlarge the pan setting accuracy to 4 bits + // making it smoother thus sacrificing the emulation accuracy. + // This mode is disabled by default. + MT32EMU_EXPORT void setNicePanningEnabled(bool enabled); + // Returns whether NicePanning mode is enabled. + MT32EMU_EXPORT bool isNicePanningEnabled() const; + + // Allows to toggle the NicePartialMixing mode. + // LA-32 is known to mix partials either in-phase (so that they are added) + // or in counter-phase (so that they are subtracted instead). + // In some cases, this quirk isn't highly desired because a pair of closely + // sounding partials may occasionally cancel out. + // In the NicePartialMixing mode, the mixing is always performed in-phase, + // thus making the behaviour more predictable. + // This mode is disabled by default. + MT32EMU_EXPORT void setNicePartialMixingEnabled(bool enabled); + // Returns whether NicePartialMixing mode is enabled. + MT32EMU_EXPORT bool isNicePartialMixingEnabled() const; + // Selects new type of the wave generator and renderer to be used during subsequent calls to open(). // By default, RendererType_BIT16S is selected. // See RendererType for details. diff --git a/src/sound/munt/TVA.cpp b/src/sound/munt/TVA.cpp index 3f7064f9a..a49ad0193 100644 --- a/src/sound/munt/TVA.cpp +++ b/src/sound/munt/TVA.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/TVA.h b/src/sound/munt/TVA.h index cf9296d48..de6e61017 100644 --- a/src/sound/munt/TVA.h +++ b/src/sound/munt/TVA.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/TVF.cpp b/src/sound/munt/TVF.cpp index 7ba9c7f2e..3d5f26049 100644 --- a/src/sound/munt/TVF.cpp +++ b/src/sound/munt/TVF.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/TVF.h b/src/sound/munt/TVF.h index e637aa5b4..149b1d09b 100644 --- a/src/sound/munt/TVF.h +++ b/src/sound/munt/TVF.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/TVP.cpp b/src/sound/munt/TVP.cpp index a3b364048..3d5f492fd 100644 --- a/src/sound/munt/TVP.cpp +++ b/src/sound/munt/TVP.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -104,12 +104,12 @@ static Bit32u calcBasePitch(const Partial *partial, const TimbreParam::PartialPa // MT-32 GEN0 does 16-bit calculations here, allowing an integer overflow. // This quirk is observable playing the patch defined for timbre "HIT BOTTOM" in Larry 3. + // Note, the upper bound isn't checked either. if (controlROMFeatures->quirkBasePitchOverflow) { basePitch = basePitch & 0xffff; } else if (basePitch < 0) { basePitch = 0; - } - if (basePitch > 59392) { + } else if (basePitch > 59392) { basePitch = 59392; } return Bit32u(basePitch); @@ -151,6 +151,7 @@ void TVP::reset(const Part *usePart, const TimbreParam::PartialParam *usePartial // FIXME: We're using a per-TVP timer instead of a system-wide one for convenience. timeElapsed = 0; + processTimerIncrement = 0; basePitch = calcBasePitch(partial, partialParam, patchTemp, key, partial->getSynth()->controlROMFeatures); currentPitchOffset = calcTargetPitchOffsetWithoutLFO(partialParam, 0, velocity); @@ -194,6 +195,7 @@ void TVP::updatePitch() { } else if (newPitch < 0) { newPitch = 0; } + // This check is present in every unit. if (newPitch > 59392) { newPitch = 59392; } diff --git a/src/sound/munt/TVP.h b/src/sound/munt/TVP.h index 896e8c11a..c3dc314b4 100644 --- a/src/sound/munt/TVP.h +++ b/src/sound/munt/TVP.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Tables.cpp b/src/sound/munt/Tables.cpp index f12caa6b6..7fee467e8 100644 --- a/src/sound/munt/Tables.cpp +++ b/src/sound/munt/Tables.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Tables.h b/src/sound/munt/Tables.h index 47465097e..790ee17b9 100644 --- a/src/sound/munt/Tables.h +++ b/src/sound/munt/Tables.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/Types.h b/src/sound/munt/Types.h index f70e4795c..17c33e568 100644 --- a/src/sound/munt/Types.h +++ b/src/sound/munt/Types.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/c_interface/c_interface.cpp b/src/sound/munt/c_interface/c_interface.cpp index 24bb1460e..48eb2824a 100644 --- a/src/sound/munt/c_interface/c_interface.cpp +++ b/src/sound/munt/c_interface/c_interface.cpp @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -41,7 +41,7 @@ static mt32emu_service_version getSynthVersionID(mt32emu_service_i) { return MT32EMU_SERVICE_VERSION_CURRENT; } -static const mt32emu_service_i_v2 SERVICE_VTABLE = { +static const mt32emu_service_i_v3 SERVICE_VTABLE = { getSynthVersionID, mt32emu_get_supported_report_handler_version, mt32emu_get_supported_midi_receiver_version, @@ -112,7 +112,13 @@ static const mt32emu_service_i_v2 SERVICE_VTABLE = { mt32emu_convert_synth_to_output_timestamp, mt32emu_get_internal_rendered_sample_count, mt32emu_set_nice_amp_ramp_enabled, - mt32emu_is_nice_amp_ramp_enabled + mt32emu_is_nice_amp_ramp_enabled, + mt32emu_set_nice_panning_enabled, + mt32emu_is_nice_panning_enabled, + mt32emu_set_nice_partial_mixing_enabled, + mt32emu_is_nice_partial_mixing_enabled, + mt32emu_preallocate_reverb_memory, + mt32emu_configure_midi_event_queue_sysex_storage }; } // namespace MT32Emu @@ -323,7 +329,7 @@ extern "C" { mt32emu_service_i mt32emu_get_service_i() { mt32emu_service_i i; - i.v2 = &SERVICE_VTABLE; + i.v3 = &SERVICE_VTABLE; return i; } @@ -450,9 +456,7 @@ void mt32emu_set_analog_output_mode(mt32emu_context context, const mt32emu_analo } void mt32emu_set_stereo_output_samplerate(mt32emu_context context, const double samplerate) { - if (0.0 <= samplerate) { - context->srcState->outputSampleRate = samplerate; - } + context->srcState->outputSampleRate = SampleRateConverter::getSupportedOutputSampleRate(samplerate); } void mt32emu_set_samplerate_conversion_quality(mt32emu_context context, const mt32emu_samplerate_conversion_quality quality) { @@ -519,6 +523,10 @@ mt32emu_bit32u mt32emu_set_midi_event_queue_size(mt32emu_const_context context, return context->synth->setMIDIEventQueueSize(queue_size); } +void mt32emu_configure_midi_event_queue_sysex_storage(mt32emu_const_context context, const mt32emu_bit32u storage_buffer_size) { + return context->synth->configureMIDIEventQueueSysexStorage(storage_buffer_size); +} + void mt32emu_set_midi_receiver(mt32emu_context context, mt32emu_midi_receiver_i midi_receiver, void *instance_data) { delete context->midiParser; context->midiParser = (midi_receiver.v0 != NULL) ? new DelegatingMidiStreamParser(context, midi_receiver, instance_data) : new DefaultMidiStreamParser(*context->synth); @@ -612,6 +620,10 @@ mt32emu_boolean mt32emu_is_default_reverb_mt32_compatible(mt32emu_const_context return context->synth->isDefaultReverbMT32Compatible() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; } +void mt32emu_preallocate_reverb_memory(mt32emu_const_context context, const mt32emu_boolean enabled) { + return context->synth->preallocateReverbMemory(enabled != MT32EMU_BOOL_FALSE); +} + void mt32emu_set_dac_input_mode(mt32emu_const_context context, const mt32emu_dac_input_mode mode) { context->synth->setDACInputMode(static_cast(mode)); } @@ -660,6 +672,22 @@ mt32emu_boolean mt32emu_is_nice_amp_ramp_enabled(mt32emu_const_context context) return context->synth->isNiceAmpRampEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; } +MT32EMU_EXPORT void mt32emu_set_nice_panning_enabled(mt32emu_const_context context, const mt32emu_boolean enabled) { + context->synth->setNicePanningEnabled(enabled != MT32EMU_BOOL_FALSE); +} + +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_panning_enabled(mt32emu_const_context context) { + return context->synth->isNicePanningEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +MT32EMU_EXPORT void mt32emu_set_nice_partial_mixing_enabled(mt32emu_const_context context, const mt32emu_boolean enabled) { + context->synth->setNicePartialMixingEnabled(enabled != MT32EMU_BOOL_FALSE); +} + +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_partial_mixing_enabled(mt32emu_const_context context) { + return context->synth->isNicePartialMixingEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + void mt32emu_render_bit16s(mt32emu_const_context context, mt32emu_bit16s *stream, mt32emu_bit32u len) { if (context->srcState->src != NULL) { context->srcState->src->getOutputSamples(stream, len); diff --git a/src/sound/munt/c_interface/c_interface.h b/src/sound/munt/c_interface/c_interface.h index 2ca3a3b04..0924dcce5 100644 --- a/src/sound/munt/c_interface/c_interface.h +++ b/src/sound/munt/c_interface/c_interface.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -35,7 +35,7 @@ extern "C" { /* === Interface handling === */ /** Returns mt32emu_service_i interface. */ -MT32EMU_EXPORT mt32emu_service_i mt32emu_get_service_i(); +MT32EMU_EXPORT mt32emu_service_i mt32emu_get_service_i(void); #if MT32EMU_EXPORTS_TYPE == 2 #undef MT32EMU_EXPORT @@ -46,13 +46,13 @@ MT32EMU_EXPORT mt32emu_service_i mt32emu_get_service_i(); * Returns the version ID of mt32emu_report_handler_i interface the library has been compiled with. * This allows a client to fall-back gracefully instead of silently not receiving expected event reports. */ -MT32EMU_EXPORT mt32emu_report_handler_version mt32emu_get_supported_report_handler_version(); +MT32EMU_EXPORT mt32emu_report_handler_version mt32emu_get_supported_report_handler_version(void); /** * Returns the version ID of mt32emu_midi_receiver_version_i interface the library has been compiled with. * This allows a client to fall-back gracefully instead of silently not receiving expected MIDI messages. */ -MT32EMU_EXPORT mt32emu_midi_receiver_version mt32emu_get_supported_midi_receiver_version(); +MT32EMU_EXPORT mt32emu_midi_receiver_version mt32emu_get_supported_midi_receiver_version(void); /** * Returns library version as an integer in format: 0x00MMmmpp, where: @@ -60,12 +60,12 @@ MT32EMU_EXPORT mt32emu_midi_receiver_version mt32emu_get_supported_midi_receiver * mm - minor version number * pp - patch number */ -MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_library_version_int(); +MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_library_version_int(void); /** * Returns library version as a C-string in format: "MAJOR.MINOR.PATCH". */ -MT32EMU_EXPORT const char *mt32emu_get_library_version_string(); +MT32EMU_EXPORT const char *mt32emu_get_library_version_string(void); /** * Returns output sample rate used in emulation of stereo analog circuitry of hardware units for particular analog_output_mode. @@ -201,6 +201,19 @@ MT32EMU_EXPORT void mt32emu_flush_midi_queue(mt32emu_const_context context); */ MT32EMU_EXPORT mt32emu_bit32u mt32emu_set_midi_event_queue_size(mt32emu_const_context context, const mt32emu_bit32u queue_size); +/** + * Configures the SysEx storage of the internal MIDI event queue. + * Supplying 0 in the storage_buffer_size argument makes the SysEx data stored + * in multiple dynamically allocated buffers per MIDI event. These buffers are only disposed + * when a new MIDI event replaces the SysEx event in the queue, thus never on the rendering thread. + * This is the default behaviour. + * In contrast, when a positive value is specified, SysEx data will be stored in a single preallocated buffer, + * which makes this kind of storage safe for use in a realtime thread. Additionally, the space retained + * by a SysEx event, that has been processed and thus is no longer necessary, is disposed instantly. + * Note, the queue is flushed and recreated in the process so that its size remains intact. + */ +void mt32emu_configure_midi_event_queue_sysex_storage(mt32emu_const_context context, const mt32emu_bit32u storage_buffer_size); + /** * Installs custom MIDI receiver object intended for receiving MIDI messages generated by MIDI stream parser. * MIDI stream parser is involved when functions mt32emu_parse_stream() and mt32emu_play_short_message() or the likes are called. @@ -316,6 +329,13 @@ MT32EMU_EXPORT mt32emu_boolean mt32emu_is_mt32_reverb_compatibility_mode(mt32emu /** Returns whether default reverb compatibility mode is the old MT-32 compatibility mode. */ MT32EMU_EXPORT mt32emu_boolean mt32emu_is_default_reverb_mt32_compatible(mt32emu_const_context context); +/** + * If enabled, reverb buffers for all modes are keept around allocated all the time to avoid memory + * allocating/freeing in the rendering thread, which may be required for realtime operation. + * Otherwise, reverb buffers that are not in use are deleted to save memory (the default behaviour). + */ +MT32EMU_EXPORT void mt32emu_preallocate_reverb_memory(mt32emu_const_context context, const mt32emu_boolean enabled); + /** Sets new DAC input mode. See mt32emu_dac_input_mode for details. */ MT32EMU_EXPORT void mt32emu_set_dac_input_mode(mt32emu_const_context context, const mt32emu_dac_input_mode mode); /** Returns current DAC input mode. See mt32emu_dac_input_mode for details. */ @@ -366,6 +386,33 @@ MT32EMU_EXPORT void mt32emu_set_nice_amp_ramp_enabled(mt32emu_const_context cont /** Returns whether NiceAmpRamp mode is enabled. */ MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_amp_ramp_enabled(mt32emu_const_context context); +/** + * Allows to toggle the NicePanning mode. + * Despite the Roland's manual specifies allowed panpot values in range 0-14, + * the LA-32 only receives 3-bit pan setting in fact. In particular, this + * makes it impossible to set the "middle" panning for a single partial. + * In the NicePanning mode, we enlarge the pan setting accuracy to 4 bits + * making it smoother thus sacrificing the emulation accuracy. + * This mode is disabled by default. + */ +MT32EMU_EXPORT void mt32emu_set_nice_panning_enabled(mt32emu_const_context context, const mt32emu_boolean enabled); +/** Returns whether NicePanning mode is enabled. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_panning_enabled(mt32emu_const_context context); + +/** + * Allows to toggle the NicePartialMixing mode. + * LA-32 is known to mix partials either in-phase (so that they are added) + * or in counter-phase (so that they are subtracted instead). + * In some cases, this quirk isn't highly desired because a pair of closely + * sounding partials may occasionally cancel out. + * In the NicePartialMixing mode, the mixing is always performed in-phase, + * thus making the behaviour more predictable. + * This mode is disabled by default. + */ +MT32EMU_EXPORT void mt32emu_set_nice_partial_mixing_enabled(mt32emu_const_context context, const mt32emu_boolean enabled); +/** Returns whether NicePartialMixing mode is enabled. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_partial_mixing_enabled(mt32emu_const_context context); + /** * Renders samples to the specified output stream as if they were sampled at the analog stereo output at the desired sample rate. * If the output sample rate is not specified explicitly, the default output sample rate is used which depends on the current diff --git a/src/sound/munt/c_interface/c_types.h b/src/sound/munt/c_interface/c_types.h index db612e282..74bae8df4 100644 --- a/src/sound/munt/c_interface/c_types.h +++ b/src/sound/munt/c_interface/c_types.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -121,7 +121,8 @@ typedef enum { MT32EMU_SERVICE_VERSION_0 = 0, MT32EMU_SERVICE_VERSION_1 = 1, MT32EMU_SERVICE_VERSION_2 = 2, - MT32EMU_SERVICE_VERSION_CURRENT = MT32EMU_SERVICE_VERSION_2 + MT32EMU_SERVICE_VERSION_3 = 3, + MT32EMU_SERVICE_VERSION_CURRENT = MT32EMU_SERVICE_VERSION_3 } mt32emu_service_version; /* === Report Handler Interface === */ @@ -216,11 +217,11 @@ typedef union mt32emu_service_i mt32emu_service_i; #define MT32EMU_SERVICE_I_V0 \ /** Returns the actual interface version ID */ \ mt32emu_service_version (*getVersionID)(mt32emu_service_i i); \ - mt32emu_report_handler_version (*getSupportedReportHandlerVersionID)(); \ - mt32emu_midi_receiver_version (*getSupportedMIDIReceiverVersionID)(); \ + mt32emu_report_handler_version (*getSupportedReportHandlerVersionID)(void); \ + mt32emu_midi_receiver_version (*getSupportedMIDIReceiverVersionID)(void); \ \ - mt32emu_bit32u (*getLibraryVersionInt)(); \ - const char *(*getLibraryVersionString)(); \ + mt32emu_bit32u (*getLibraryVersionInt)(void); \ + const char *(*getLibraryVersionString)(void); \ \ mt32emu_bit32u (*getStereoOutputSamplerate)(const mt32emu_analog_output_mode analog_output_mode); \ \ @@ -303,6 +304,14 @@ typedef union mt32emu_service_i mt32emu_service_i; void (*setNiceAmpRampEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \ mt32emu_boolean (*isNiceAmpRampEnabled)(mt32emu_const_context context); +#define MT32EMU_SERVICE_I_V3 \ + void (*setNicePanningEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \ + mt32emu_boolean (*isNicePanningEnabled)(mt32emu_const_context context); \ + void (*setNicePartialMixingEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \ + mt32emu_boolean (*isNicePartialMixingEnabled)(mt32emu_const_context context); \ + void (*preallocateReverbMemory)(mt32emu_const_context context, const mt32emu_boolean enabled); \ + void (*configureMIDIEventQueueSysexStorage)(mt32emu_const_context context, const mt32emu_bit32u storage_buffer_size); + typedef struct { MT32EMU_SERVICE_I_V0 } mt32emu_service_i_v0; @@ -318,6 +327,13 @@ typedef struct { MT32EMU_SERVICE_I_V2 } mt32emu_service_i_v2; +typedef struct { + MT32EMU_SERVICE_I_V0 + MT32EMU_SERVICE_I_V1 + MT32EMU_SERVICE_I_V2 + MT32EMU_SERVICE_I_V3 +} mt32emu_service_i_v3; + /** * Extensible interface for all the library services. * Union intended to view an interface of any subsequent version as any parent interface not requiring a cast. @@ -327,10 +343,12 @@ union mt32emu_service_i { const mt32emu_service_i_v0 *v0; const mt32emu_service_i_v1 *v1; const mt32emu_service_i_v2 *v2; + const mt32emu_service_i_v3 *v3; }; #undef MT32EMU_SERVICE_I_V0 #undef MT32EMU_SERVICE_I_V1 #undef MT32EMU_SERVICE_I_V2 +#undef MT32EMU_SERVICE_I_V3 #endif /* #ifndef MT32EMU_C_TYPES_H */ diff --git a/src/sound/munt/c_interface/cpp_interface.h b/src/sound/munt/c_interface/cpp_interface.h index 3b02c0325..82fa44b2e 100644 --- a/src/sound/munt/c_interface/cpp_interface.h +++ b/src/sound/munt/c_interface/cpp_interface.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -60,6 +60,7 @@ mt32emu_service_i mt32emu_get_service_i(); #define mt32emu_convert_synth_to_output_timestamp iV1()->convertSynthToOutputTimestamp #define mt32emu_flush_midi_queue i.v0->flushMIDIQueue #define mt32emu_set_midi_event_queue_size i.v0->setMIDIEventQueueSize +#define mt32emu_configure_midi_event_queue_sysex_storage iV3()->configureMIDIEventQueueSysexStorage #define mt32emu_set_midi_receiver i.v0->setMIDIReceiver #define mt32emu_get_internal_rendered_sample_count iV2()->getInternalRenderedSampleCount #define mt32emu_parse_stream i.v0->parseStream @@ -81,6 +82,7 @@ mt32emu_service_i mt32emu_get_service_i(); #define mt32emu_set_reverb_compatibility_mode i.v0->setReverbCompatibilityMode #define mt32emu_is_mt32_reverb_compatibility_mode i.v0->isMT32ReverbCompatibilityMode #define mt32emu_is_default_reverb_mt32_compatible i.v0->isDefaultReverbMT32Compatible +#define mt32emu_preallocate_reverb_memory iV3()->preallocateReverbMemory #define mt32emu_set_dac_input_mode i.v0->setDACInputMode #define mt32emu_get_dac_input_mode i.v0->getDACInputMode #define mt32emu_set_midi_delay_mode i.v0->setMIDIDelayMode @@ -93,6 +95,10 @@ mt32emu_service_i mt32emu_get_service_i(); #define mt32emu_is_reversed_stereo_enabled i.v0->isReversedStereoEnabled #define mt32emu_set_nice_amp_ramp_enabled iV2()->setNiceAmpRampEnabled #define mt32emu_is_nice_amp_ramp_enabled iV2()->isNiceAmpRampEnabled +#define mt32emu_set_nice_panning_enabled iV3()->setNicePanningEnabled +#define mt32emu_is_nice_panning_enabled iV3()->isNicePanningEnabled +#define mt32emu_set_nice_partial_mixing_enabled iV3()->setNicePartialMixingEnabled +#define mt32emu_is_nice_partial_mixing_enabled iV3()->isNicePartialMixingEnabled #define mt32emu_render_bit16s i.v0->renderBit16s #define mt32emu_render_float i.v0->renderFloat #define mt32emu_render_bit16s_streams i.v0->renderBit16sStreams @@ -213,6 +219,7 @@ public: Bit32u convertSynthToOutputTimestamp(Bit32u synth_timestamp) { return mt32emu_convert_synth_to_output_timestamp(c, synth_timestamp); } void flushMIDIQueue() { mt32emu_flush_midi_queue(c); } Bit32u setMIDIEventQueueSize(const Bit32u queue_size) { return mt32emu_set_midi_event_queue_size(c, queue_size); } + void configureMIDIEventQueueSysexStorage(const Bit32u storage_buffer_size) { mt32emu_configure_midi_event_queue_sysex_storage(c, storage_buffer_size); } void setMIDIReceiver(mt32emu_midi_receiver_i midi_receiver, void *instance_data) { mt32emu_set_midi_receiver(c, midi_receiver, instance_data); } void setMIDIReceiver(IMidiReceiver &midi_receiver) { setMIDIReceiver(CppInterfaceImpl::getMidiReceiverThunk(), &midi_receiver); } @@ -238,6 +245,7 @@ public: void setReverbCompatibilityMode(const bool mt32_compatible_mode) { mt32emu_set_reverb_compatibility_mode(c, mt32_compatible_mode ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } bool isMT32ReverbCompatibilityMode() { return mt32emu_is_mt32_reverb_compatibility_mode(c) != MT32EMU_BOOL_FALSE; } bool isDefaultReverbMT32Compatible() { return mt32emu_is_default_reverb_mt32_compatible(c) != MT32EMU_BOOL_FALSE; } + void preallocateReverbMemory(const bool enabled) { mt32emu_preallocate_reverb_memory(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } void setDACInputMode(const DACInputMode mode) { mt32emu_set_dac_input_mode(c, static_cast(mode)); } DACInputMode getDACInputMode() { return static_cast(mt32emu_get_dac_input_mode(c)); } @@ -256,6 +264,12 @@ public: void setNiceAmpRampEnabled(const bool enabled) { mt32emu_set_nice_amp_ramp_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } bool isNiceAmpRampEnabled() { return mt32emu_is_nice_amp_ramp_enabled(c) != MT32EMU_BOOL_FALSE; } + void setNicePanningEnabled(const bool enabled) { mt32emu_set_nice_panning_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } + bool isNicePanningEnabled() { return mt32emu_is_nice_panning_enabled(c) != MT32EMU_BOOL_FALSE; } + + void setNicePartialMixingEnabled(const bool enabled) { mt32emu_set_nice_partial_mixing_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } + bool isNicePartialMixingEnabled() { return mt32emu_is_nice_partial_mixing_enabled(c) != MT32EMU_BOOL_FALSE; } + void renderBit16s(Bit16s *stream, Bit32u len) { mt32emu_render_bit16s(c, stream, len); } void renderFloat(float *stream, Bit32u len) { mt32emu_render_float(c, stream, len); } void renderBit16sStreams(const mt32emu_dac_output_bit16s_streams *streams, Bit32u len) { mt32emu_render_bit16s_streams(c, streams, len); } @@ -279,6 +293,7 @@ private: #if MT32EMU_API_TYPE == 2 const mt32emu_service_i_v1 *iV1() { return (getVersionID() < MT32EMU_SERVICE_VERSION_1) ? NULL : i.v1; } const mt32emu_service_i_v2 *iV2() { return (getVersionID() < MT32EMU_SERVICE_VERSION_2) ? NULL : i.v2; } + const mt32emu_service_i_v3 *iV3() { return (getVersionID() < MT32EMU_SERVICE_VERSION_3) ? NULL : i.v3; } #endif }; @@ -428,6 +443,7 @@ static mt32emu_midi_receiver_i getMidiReceiverThunk() { #undef mt32emu_convert_synth_to_output_timestamp #undef mt32emu_flush_midi_queue #undef mt32emu_set_midi_event_queue_size +#undef mt32emu_configure_midi_event_queue_sysex_storage #undef mt32emu_set_midi_receiver #undef mt32emu_get_internal_rendered_sample_count #undef mt32emu_parse_stream @@ -449,6 +465,7 @@ static mt32emu_midi_receiver_i getMidiReceiverThunk() { #undef mt32emu_set_reverb_compatibility_mode #undef mt32emu_is_mt32_reverb_compatibility_mode #undef mt32emu_is_default_reverb_mt32_compatible +#undef mt32emu_preallocate_reverb_memory #undef mt32emu_set_dac_input_mode #undef mt32emu_get_dac_input_mode #undef mt32emu_set_midi_delay_mode @@ -461,6 +478,10 @@ static mt32emu_midi_receiver_i getMidiReceiverThunk() { #undef mt32emu_is_reversed_stereo_enabled #undef mt32emu_set_nice_amp_ramp_enabled #undef mt32emu_is_nice_amp_ramp_enabled +#undef mt32emu_set_nice_panning_enabled +#undef mt32emu_is_nice_panning_enabled +#undef mt32emu_set_nice_partial_mixing_enabled +#undef mt32emu_is_nice_partial_mixing_enabled #undef mt32emu_render_bit16s #undef mt32emu_render_float #undef mt32emu_render_bit16s_streams diff --git a/src/sound/munt/config.h b/src/sound/munt/config.h index 5f5b6c9fb..e41d4664b 100644 --- a/src/sound/munt/config.h +++ b/src/sound/munt/config.h @@ -18,9 +18,9 @@ #ifndef MT32EMU_CONFIG_H #define MT32EMU_CONFIG_H -#define MT32EMU_VERSION "2.2.0" +#define MT32EMU_VERSION "2.4.0" #define MT32EMU_VERSION_MAJOR 2 -#define MT32EMU_VERSION_MINOR 2 +#define MT32EMU_VERSION_MINOR 4 #define MT32EMU_VERSION_PATCH 0 /* Library Exports Configuration @@ -37,4 +37,9 @@ #define MT32EMU_API_TYPE 0 +#define MT32EMU_WITH_LIBSOXR_RESAMPLER 0 +#define MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER 0 +#define MT32EMU_WITH_INTERNAL_RESAMPLER 1 + + #endif diff --git a/src/sound/munt/config.h.in b/src/sound/munt/config.h.in new file mode 100644 index 000000000..48dfb0076 --- /dev/null +++ b/src/sound/munt/config.h.in @@ -0,0 +1,38 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_CONFIG_H +#define MT32EMU_CONFIG_H + +#define MT32EMU_VERSION "@libmt32emu_VERSION@" +#define MT32EMU_VERSION_MAJOR @libmt32emu_VERSION_MAJOR@ +#define MT32EMU_VERSION_MINOR @libmt32emu_VERSION_MINOR@ +#define MT32EMU_VERSION_PATCH @libmt32emu_VERSION_PATCH@ + +/* Library Exports Configuration + * + * This reflects the API types actually provided by the library build. + * 0: The full-featured C++ API is only available in this build. The client application may ONLY use MT32EMU_API_TYPE 0. + * 1: The C-compatible API is only available. The library is built as a shared object, only C functions are exported, + * and thus the client application may NOT use MT32EMU_API_TYPE 0. + * 2: The C-compatible API is only available. The library is built as a shared object, only the factory function + * is exported, and thus the client application may ONLY use MT32EMU_API_TYPE 2. + * 3: All the available API types are provided by the library build. + */ +#define MT32EMU_EXPORTS_TYPE @libmt32emu_EXPORTS_TYPE@ + +#endif diff --git a/src/sound/munt/globals.h b/src/sound/munt/globals.h index 2d984c82b..243ff82ae 100644 --- a/src/sound/munt/globals.h +++ b/src/sound/munt/globals.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/internals.h b/src/sound/munt/internals.h index 0bae8d9f7..8a609546c 100644 --- a/src/sound/munt/internals.h +++ b/src/sound/munt/internals.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -81,12 +81,6 @@ // Configuration -// If non-zero, deletes reverb buffers that are not in use to save memory. -// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path. -#ifndef MT32EMU_REDUCE_REVERB_MEMORY -#define MT32EMU_REDUCE_REVERB_MEMORY 1 -#endif - // 0: Maximum speed at the cost of a bit lower emulation accuracy. // 1: Maximum achievable emulation accuracy. #ifndef MT32EMU_BOSS_REVERB_PRECISE_MODE diff --git a/src/sound/munt/mmath.h b/src/sound/munt/mmath.h index 9a9e642ba..a66fad566 100644 --- a/src/sound/munt/mmath.h +++ b/src/sound/munt/mmath.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/mt32emu.h b/src/sound/munt/mt32emu.h index 6b93121be..cfb50fb28 100644 --- a/src/sound/munt/mt32emu.h +++ b/src/sound/munt/mt32emu.h @@ -1,5 +1,5 @@ /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher - * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * Copyright (C) 2011-2020 Dean Beeler, Jerome Fisher, Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/InternalResampler.cpp b/src/sound/munt/srchelper/InternalResampler.cpp index 782d39bbe..56bd1ac05 100644 --- a/src/sound/munt/srchelper/InternalResampler.cpp +++ b/src/sound/munt/srchelper/InternalResampler.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -16,8 +16,8 @@ #include "InternalResampler.h" -#include -#include +#include "srctools/include/SincResampler.h" +#include "srctools/include/ResamplerModel.h" #include "../Synth.h" diff --git a/src/sound/munt/srchelper/InternalResampler.h b/src/sound/munt/srchelper/InternalResampler.h index 87f8ff25d..cf08c8261 100644 --- a/src/sound/munt/srchelper/InternalResampler.h +++ b/src/sound/munt/srchelper/InternalResampler.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -19,7 +19,7 @@ #include "../Enumerations.h" -#include "FloatSampleProvider.h" +#include "srctools/include/FloatSampleProvider.h" namespace MT32Emu { diff --git a/src/sound/munt/srchelper/SamplerateAdapter.cpp b/src/sound/munt/srchelper/SamplerateAdapter.cpp index 715d29872..2a417ed2e 100644 --- a/src/sound/munt/srchelper/SamplerateAdapter.cpp +++ b/src/sound/munt/srchelper/SamplerateAdapter.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/SamplerateAdapter.h b/src/sound/munt/srchelper/SamplerateAdapter.h index 0991fd771..eed9799a9 100644 --- a/src/sound/munt/srchelper/SamplerateAdapter.h +++ b/src/sound/munt/srchelper/SamplerateAdapter.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/SoxrAdapter.cpp b/src/sound/munt/srchelper/SoxrAdapter.cpp index 5e8dca97d..a88c133ec 100644 --- a/src/sound/munt/srchelper/SoxrAdapter.cpp +++ b/src/sound/munt/srchelper/SoxrAdapter.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/SoxrAdapter.h b/src/sound/munt/srchelper/SoxrAdapter.h index b97ca4da5..c6b9d3ade 100644 --- a/src/sound/munt/srchelper/SoxrAdapter.h +++ b/src/sound/munt/srchelper/SoxrAdapter.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/srctools/include/FIRResampler.h b/src/sound/munt/srchelper/srctools/include/FIRResampler.h index 7c09bf8de..9032131dc 100644 --- a/src/sound/munt/srchelper/srctools/include/FIRResampler.h +++ b/src/sound/munt/srchelper/srctools/include/FIRResampler.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/srctools/include/FloatSampleProvider.h b/src/sound/munt/srchelper/srctools/include/FloatSampleProvider.h index 9820769f7..4056db373 100644 --- a/src/sound/munt/srchelper/srctools/include/FloatSampleProvider.h +++ b/src/sound/munt/srchelper/srctools/include/FloatSampleProvider.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/srctools/include/IIR2xResampler.h b/src/sound/munt/srchelper/srctools/include/IIR2xResampler.h index 0bfe1c4c8..ea150f9db 100644 --- a/src/sound/munt/srchelper/srctools/include/IIR2xResampler.h +++ b/src/sound/munt/srchelper/srctools/include/IIR2xResampler.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/srctools/include/LinearResampler.h b/src/sound/munt/srchelper/srctools/include/LinearResampler.h index c81ff2a38..0e30ea2e9 100644 --- a/src/sound/munt/srchelper/srctools/include/LinearResampler.h +++ b/src/sound/munt/srchelper/srctools/include/LinearResampler.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/srctools/include/ResamplerModel.h b/src/sound/munt/srchelper/srctools/include/ResamplerModel.h index f0ac23707..b7a64f02e 100644 --- a/src/sound/munt/srchelper/srctools/include/ResamplerModel.h +++ b/src/sound/munt/srchelper/srctools/include/ResamplerModel.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/srctools/include/ResamplerStage.h b/src/sound/munt/srchelper/srctools/include/ResamplerStage.h index e335c0c38..edd7678c1 100644 --- a/src/sound/munt/srchelper/srctools/include/ResamplerStage.h +++ b/src/sound/munt/srchelper/srctools/include/ResamplerStage.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/srctools/include/SincResampler.h b/src/sound/munt/srchelper/srctools/include/SincResampler.h index 1551a1eda..bac844043 100644 --- a/src/sound/munt/srchelper/srctools/include/SincResampler.h +++ b/src/sound/munt/srchelper/srctools/include/SincResampler.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by diff --git a/src/sound/munt/srchelper/srctools/src/FIRResampler.cpp b/src/sound/munt/srchelper/srctools/src/FIRResampler.cpp index 2cded0c3d..b5ab5585c 100644 --- a/src/sound/munt/srchelper/srctools/src/FIRResampler.cpp +++ b/src/sound/munt/srchelper/srctools/src/FIRResampler.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -17,7 +17,7 @@ #include #include -#include "FIRResampler.h" +#include "../include/FIRResampler.h" using namespace SRCTools; diff --git a/src/sound/munt/srchelper/srctools/src/IIR2xResampler.cpp b/src/sound/munt/srchelper/srctools/src/IIR2xResampler.cpp index 0016f23c9..98f7a3a5b 100644 --- a/src/sound/munt/srchelper/srctools/src/IIR2xResampler.cpp +++ b/src/sound/munt/srchelper/srctools/src/IIR2xResampler.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -16,7 +16,7 @@ #include -#include "IIR2xResampler.h" +#include "../include/IIR2xResampler.h" namespace SRCTools { diff --git a/src/sound/munt/srchelper/srctools/src/LinearResampler.cpp b/src/sound/munt/srchelper/srctools/src/LinearResampler.cpp index 98b9c77c7..1ca143a38 100644 --- a/src/sound/munt/srchelper/srctools/src/LinearResampler.cpp +++ b/src/sound/munt/srchelper/srctools/src/LinearResampler.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -14,7 +14,7 @@ * along with this program. If not, see . */ -#include "LinearResampler.h" +#include "../include/LinearResampler.h" using namespace SRCTools; diff --git a/src/sound/munt/srchelper/srctools/src/ResamplerModel.cpp b/src/sound/munt/srchelper/srctools/src/ResamplerModel.cpp index 4d2d93083..2a7f75822 100644 --- a/src/sound/munt/srchelper/srctools/src/ResamplerModel.cpp +++ b/src/sound/munt/srchelper/srctools/src/ResamplerModel.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -17,12 +17,12 @@ #include #include -#include "ResamplerModel.h" +#include "../include/ResamplerModel.h" -#include "ResamplerStage.h" -#include "SincResampler.h" -#include "IIR2xResampler.h" -#include "LinearResampler.h" +#include "../include/ResamplerStage.h" +#include "../include/SincResampler.h" +#include "../include/IIR2xResampler.h" +#include "../include/LinearResampler.h" namespace SRCTools { diff --git a/src/sound/munt/srchelper/srctools/src/SincResampler.cpp b/src/sound/munt/srchelper/srctools/src/SincResampler.cpp index 38d0ebe45..60a18256c 100644 --- a/src/sound/munt/srchelper/srctools/src/SincResampler.cpp +++ b/src/sound/munt/srchelper/srctools/src/SincResampler.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2017 Sergey V. Mikayev +/* Copyright (C) 2015-2020 Sergey V. Mikayev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -20,7 +20,7 @@ #include #endif -#include "SincResampler.h" +#include "../include/SincResampler.h" #ifndef M_PI static const double M_PI = 3.1415926535897932; diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index d2edc6af8..4953da1a0 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -117,7 +117,7 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p) case 24: if (! (val & 0x70)) ad1848->status &= 0xfe; - break; + break; case 25: break; diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 19974cf6a..966044b77 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -14,7 +14,7 @@ #include <86box/device.h> #include <86box/sound.h> #include <86box/midi.h> -#include <86Box/snd_ad1848.h> +#include <86box/snd_ad1848.h> #include enum diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index f3f428f7e..09acdc3e0 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1136,6 +1136,40 @@ gd54xx_recalctimings(svga_t *svga) svga->map8 = video_8to32; svga->render = svga_render_8bpp_highres; break; + + case 0xf: + switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) { + case CIRRUS_SR7_BPP_32: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) { + svga->bpp = 32; + svga->render = svga_render_32bpp_highres; + svga->rowoffset *= 2; + } + break; + + case CIRRUS_SR7_BPP_24: + svga->bpp = 24; + svga->render = svga_render_24bpp_highres; + break; + + case CIRRUS_SR7_BPP_16: + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + } + break; + + case CIRRUS_SR7_BPP_16_DOUBLEVCLK: + svga->bpp = 16; + svga->render = svga_render_16bpp_highres; + break; + + case CIRRUS_SR7_BPP_8: + svga->bpp = 8; + svga->render = svga_render_8bpp_highres; + break; + } + break; } } else { svga->bpp = 15; @@ -3335,6 +3369,33 @@ static const device_config_t gd5428_config[] = } }; +static const device_config_t gd5428_a1g_config[] = +{ + { + .name = "memory", + .description = "Onboard Video RAM size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "" + } + }, + .default_int = 2 + }, + { + .type = -1 + } +}; + static const device_config_t gd5440_onboard_config[] = { { @@ -3392,7 +3453,7 @@ static const device_config_t gd5434_config[] = const device_t gd5401_isa_device = { "Cirrus Logic GD-5401 (ACUMOS AVGA1)", - DEVICE_AT | DEVICE_ISA, + DEVICE_ISA, CIRRUS_ID_CLGD5401, gd54xx_init, gd54xx_close, NULL, @@ -3405,7 +3466,7 @@ const device_t gd5401_isa_device = const device_t gd5402_isa_device = { "Cirrus Logic GD-5402 (ACUMOS AVGA2)", - DEVICE_AT | DEVICE_ISA, + DEVICE_ISA, CIRRUS_ID_CLGD5402, gd54xx_init, gd54xx_close, NULL, @@ -3523,6 +3584,20 @@ const device_t gd5428_mca_device = NULL }; +const device_t gd5428_a1g_device = +{ + "Cirrus Logic CL-GD 5428 (Onboard)", + DEVICE_AT | DEVICE_ISA, + CIRRUS_ID_CLGD5428, + gd54xx_init, + gd54xx_close, + NULL, + gd5428_isa_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd5428_a1g_config +}; + const device_t gd5429_isa_device = { "Cirrus Logic CL-GD 5429 (ISA)", diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 5e6337a48..0ab9b5b3f 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -76,6 +76,9 @@ ega_render_overscan_left(ega_t *ega) { int i; + if ((ega->displine + ega->y_add) < 0) + return; + if (ega->scrblank || (ega->hdisp == 0)) return; @@ -89,6 +92,9 @@ ega_render_overscan_right(ega_t *ega) { int i, right; + if ((ega->displine + ega->y_add) < 0) + return; + if (ega->scrblank || (ega->hdisp == 0)) return; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 450f0c94f..4cc3885d1 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -25,6 +25,7 @@ #include <86box/pci.h> #include <86box/rom.h> #include <86box/device.h> +#include <86box/dma.h> #include <86box/plat.h> #include <86box/video.h> #include <86box/vid_svga.h> @@ -2233,14 +2234,14 @@ run_dma(mystique_t *mystique) switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if (mystique->dma.pri_state == 0) { - mystique->dma.pri_header = *(uint32_t *)&ram[mystique->dma.primaddress & DMA_ADDR_MASK]; + dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; } if ((mystique->dma.pri_header & 0xff) != 0x15) { - uint32_t val = *(uint32_t *)&ram[mystique->dma.primaddress & DMA_ADDR_MASK]; - uint32_t reg_addr; + uint32_t val, reg_addr; + dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.primaddress += 4; reg_addr = (mystique->dma.pri_header & 0x7f) << 2; @@ -2276,13 +2277,13 @@ run_dma(mystique_t *mystique) switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if (mystique->dma.sec_state == 0) { - mystique->dma.sec_header = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; + dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; } - uint32_t val = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; - uint32_t reg_addr; + uint32_t val, reg_addr; + dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.secaddress += 4; reg_addr = (mystique->dma.sec_header & 0x7f) << 2; @@ -2310,7 +2311,9 @@ run_dma(mystique_t *mystique) break; case DMA_MODE_BLIT: { - uint32_t val = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; + uint32_t val; + + dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.secaddress += 4; if (mystique->busy) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 2140f7d7e..aedaf58a9 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -611,7 +611,6 @@ svga_poll(void *p) svga_t *svga = (svga_t *)p; uint32_t x, blink_delay; int wx, wy; - int skip = (svga->crtc[8] >> 5) & 0x03; int ret, old_ma; if (!svga->linepos) { @@ -812,9 +811,9 @@ svga_poll(void *p) 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) + (skip << 2); - svga->maback = (svga->maback << 2) + (skip << 2); - svga->ca = (svga->ca << 2) + (skip << 2); + svga->ma = (svga->ma << 2); + svga->maback = (svga->maback << 2); + svga->ca = (svga->ca << 2); if (svga->vsync_callback) svga->vsync_callback(svga); diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 30b274067..c76bf2d72 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -69,6 +69,9 @@ svga_render_overscan_left(svga_t *svga) { int i; + if ((svga->displine + svga->y_add) < 0) + return; + if (svga->scrblank || (svga->hdisp == 0)) return; @@ -82,6 +85,9 @@ svga_render_overscan_right(svga_t *svga) { int i, right; + if ((svga->displine + svga->y_add) < 0) + return; + if (svga->scrblank || (svga->hdisp == 0)) return; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 960fbe03e..fbac9453c 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -2663,7 +2663,6 @@ static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t #include <86box/vid_voodoo_codegen_x86-64.h> #else #define NO_CODEGEN -static int voodoo_recomp = 0; #endif static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int ystart, int yend, int odd_even) diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 3be96434c..6ceab5ab7 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -163,7 +163,7 @@ BEGIN #endif POPUP "&Help" BEGIN - MENUITEM "&About 86Box...", IDM_ABOUT + MENUITEM "&About " EMU_NAME "...", IDM_ABOUT END END @@ -274,19 +274,6 @@ END // // Dialog // -DLG_ABOUT DIALOG DISCARDABLE 0, 0, 209, 114 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "About 86Box" -FONT 9, "Segoe UI" -BEGIN - DEFPUSHBUTTON "OK",IDOK,129,94,71,12 - ICON 100,IDC_ABOUT_ICON,7,7,20,20 - LTEXT "86Box v" EMU_VERSION " - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", - IDC_ABOUT_ICON,54,7,146,73 - CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, - 86,208,1 -END - DLG_STATUS DIALOG DISCARDABLE 0, 0, 186, 386 STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Status" @@ -331,7 +318,7 @@ END DLG_CONFIG DIALOG DISCARDABLE 0, 0, 366, 251 STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "86Box Settings" +CAPTION EMU_NAME " Settings" FONT 9, "Segoe UI" BEGIN DEFPUSHBUTTON "OK",IDOK,246,230,50,14 @@ -347,41 +334,45 @@ BEGIN #endif END -DLG_CFG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 199 +DLG_CFG_MACHINE DIALOG DISCARDABLE 97, 0, 305, 199 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN - COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST | + COMBOBOX IDC_COMBO_MACHINE_TYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Machine:",IDT_1701,7,8,60,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12 - COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | + LTEXT "Machine type:",IDT_1708,7,8,60,10 + COMBOBOX IDC_COMBO_MACHINE,71,26,138,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "CPU type:",IDT_1702,7,26,59,10 - COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | + LTEXT "Machine:",IDT_1701,7,27,60,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,26,46,12 + COMBOBOX IDC_COMBO_CPU_TYPE,71,44,45,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "CPU:",IDT_1704,124,26,18,10 - COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "CPU type:",IDT_1702,7,45,59,10 + COMBOBOX IDC_COMBO_CPU,145,44,115,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU:",IDT_1704,124,45,18,10 + COMBOBOX IDC_COMBO_FPU,71,63,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Wait states:",IDT_1703,7,45,60,10 - EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "FPU:",IDT_1707,7,63,59,10 + COMBOBOX IDC_COMBO_WS,71,82,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Wait states:",IDT_1703,7,83,60,10 + EDITTEXT IDC_MEMTEXT,70,101,45,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,101, 12,12 - LTEXT "MB",IDT_1705,123,64,10,10 - LTEXT "Memory:",IDT_1706,7,64,30,10 - CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,7,81,113,10 - GROUPBOX "Time synchronization",IDC_TIME_SYNC,7,96,100,56 + LTEXT "MB",IDT_1705,123,102,10,10 + LTEXT "Memory:",IDT_1706,7,102,30,10 + GROUPBOX "Time synchronization",IDC_TIME_SYNC,7,134,100,56 CONTROL "Disabled",IDC_RADIO_TS_DISABLED,"Button", - BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,14,108,84,10 + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,14,146,84,10 CONTROL "Enabled (local time)", IDC_RADIO_TS_LOCAL,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,14,122,84,10 + BS_AUTORADIOBUTTON | WS_TABSTOP,14,160,84,10 CONTROL "Enabled (UTC)", IDC_RADIO_TS_UTC,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,14,136,84,10 + BS_AUTORADIOBUTTON | WS_TABSTOP,14,174,84,10 #ifdef USE_DYNAREC CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,81,94,10 + BS_AUTOCHECKBOX | WS_TABSTOP,7,119,94,10 #endif END @@ -498,7 +489,7 @@ BEGIN BS_AUTOCHECKBOX | WS_TABSTOP,7,100,94,10 END -DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 200 +DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 220 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN @@ -512,42 +503,47 @@ BEGIN WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure",IDC_CONFIGURE_HDC,222,25,38,12 + LTEXT "FD Controller:",IDT_1768,7,44,48,10 + COMBOBOX IDC_COMBO_FDC,64,43,155,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURE_FDC,222,43,38,12 + CONTROL "Tertiary IDE Controller",IDC_CHECK_IDE_TER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,44,199,10 - PUSHBUTTON "Configure",IDC_BUTTON_IDE_TER,222,43,38,12 + BS_AUTOCHECKBOX | WS_TABSTOP,7,62,199,10 + PUSHBUTTON "Configure",IDC_BUTTON_IDE_TER,222,61,38,12 CONTROL "Quaternary IDE Controller",IDC_CHECK_IDE_QUA,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,62,199,10 - PUSHBUTTON "Configure",IDC_BUTTON_IDE_QUA,222,61,38,12 + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,199,10 + PUSHBUTTON "Configure",IDC_BUTTON_IDE_QUA,222,79,38,12 CONTROL "ISABugger device",IDC_CHECK_BUGGER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 CONTROL "POST card",IDC_CHECK_POSTCARD,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 + BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 - LTEXT "ISA RTC",IDT_1767,7,99,48,10 - COMBOBOX IDC_COMBO_ISARTC,64,98,155,120, + LTEXT "ISA RTC",IDT_1767,7,117,48,10 + COMBOBOX IDC_COMBO_ISARTC,64,116,155,120, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURE_ISARTC,222,98,38,12 + PUSHBUTTON "Configure",IDC_CONFIGURE_ISARTC,222,116,38,12 - GROUPBOX "ISA Memory Expansion",IDC_GROUP_ISAMEM,7,118,255,70 - LTEXT "#1:",IDT_1763,12,130,21,10 - COMBOBOX IDC_COMBO_ISAMEM_1,25,129,190,120, + GROUPBOX "ISA Memory Expansion",IDC_GROUP_ISAMEM,7,136,255,70 + LTEXT "#1:",IDT_1763,12,148,21,10 + COMBOBOX IDC_COMBO_ISAMEM_1,25,147,190,120, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_1,217,129,38,12 - LTEXT "#2:",IDT_1764,12,144,21,10 - COMBOBOX IDC_COMBO_ISAMEM_2,25,143,190,120, + PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_1,217,147,38,12 + LTEXT "#2:",IDT_1764,12,163,21,10 + COMBOBOX IDC_COMBO_ISAMEM_2,25,162,190,120, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_2,217,143,38,12 - LTEXT "#3:",IDT_1765,12,158,21,10 - COMBOBOX IDC_COMBO_ISAMEM_3,25,157,190,120, + PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_2,217,162,38,12 + LTEXT "#3:",IDT_1765,12,177,21,10 + COMBOBOX IDC_COMBO_ISAMEM_3,25,176,190,120, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_3,217,157,38,12 - LTEXT "#4:",IDT_1766,12,172,21,10 - COMBOBOX IDC_COMBO_ISAMEM_4,25,171,190,120, + PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_3,217,176,38,12 + LTEXT "#4:",IDT_1766,12,191,21,10 + COMBOBOX IDC_COMBO_ISAMEM_4,25,190,190,120, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_4,217,171,38,12 + PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_4,217,190,38,12 END DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 @@ -881,27 +877,27 @@ END STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" - IDS_2049 "86Box Error" - IDS_2050 "86Box Fatal Error" - IDS_2051 "This will hard reset the emulated machine.\nAre you sure you want to save the settings?" - IDS_2052 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" + 2048 EMU_NAME + IDS_2049 "Error" + IDS_2050 "Fatal error" + IDS_2051 "Are you sure you want to save the settings?" + IDS_2052 "Press CTRL+ALT+PAGE DOWN to return to windowed mode." IDS_2053 "Speed" IDS_2054 "ZIP %03i %i (%s): %ls" IDS_2055 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box could not find any usable ROM images.\n\nPlease download a ROM set from https://github.com/86Box/roms/releases/latest and extract it into the ""roms"" directory." + IDS_2056 EMU_NAME " could not find any usable ROM images.\n\nPlease download a ROM set from " EMU_ROMS_URL " and extract it into the ""roms"" directory." IDS_2057 "(empty)" IDS_2058 "ZIP images (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0All files (*.*)\0*.*\0" IDS_2059 "Turbo" IDS_2060 "On" IDS_2061 "Off" IDS_2062 "All images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" - IDS_2063 "Configured ROM set not available.\nDefaulting to an available ROM set." + IDS_2063 "Machine ""%S"" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." END STRINGTABLE DISCARDABLE BEGIN - IDS_2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." + IDS_2064 "Video card ""%S"" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." IDS_2065 "Machine" IDS_2066 "Display" IDS_2067 "Input devices" @@ -921,7 +917,7 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_2080 "Unable to initialize FluidSynth, libfluidsynth.dll is required" + IDS_2080 "Unable to initialize FluidSynth" IDS_2081 "Bus" IDS_2082 "File" IDS_2083 "C" @@ -930,11 +926,11 @@ BEGIN IDS_2086 "MB" IDS_2087 "Check BPB" IDS_2088 "KB" - IDS_2089 "86Box could not initialize the video renderer." + IDS_2089 "Could not initialize the video renderer." IDS_2090 "Default" IDS_2091 "%i Wait state(s)" IDS_2092 "Type" - IDS_2093 "PCap failed to set up because it may not be initialized" + IDS_2093 "Failed to set up PCap" IDS_2094 "No PCap devices found" IDS_2095 "Invalid PCap device" IDS_2096 "Standard 2-button joystick(s)" @@ -945,20 +941,61 @@ BEGIN IDS_2101 "Microsoft SideWinder Pad" IDS_2102 "Thrustmaster Flight Control System" IDS_2103 "None" - IDS_2104 "Unable to load Keyboard Accelerators!" - IDS_2105 "Unable to register Raw Input!" + IDS_2104 "Unable to load keyboard accelerators." + IDS_2105 "Unable to register raw input." IDS_2106 "%u" IDS_2107 "%u MB (CHS: %i, %i, %i)" IDS_2108 "Floppy %i (%s): %ls" IDS_2109 "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0Advanced sector images (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0Surface images (*.86F;*.MFM)\0*.86F;*.MFM\0All files (*.*)\0*.*\0" - IDS_2110 "Unable to initialize FreeType, freetype.dll is required" + IDS_2110 "Unable to initialize FreeType" IDS_2111 "Unable to initialize SDL, SDL2.dll is required" IDS_2112 "Are you sure you want to hard reset the emulated machine?" - IDS_2113 "Are you sure you want to quit 86Box?" - IDS_2114 "Unable to initialize Ghostscript, gsdll32.dll is required for automatic convertion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript files (.ps)." + IDS_2113 "Are you sure you want to exit " EMU_NAME "?" + IDS_2114 "Unable to initialize Ghostscript" IDS_2115 "MO %i (%03i): %ls" IDS_2116 "MO images (*.IM?)\0*.IM?\0All files (*.*)\0*.*\0" - IDS_2117 "Welcome to 86Box!" + IDS_2117 "Welcome to " EMU_NAME "!" + IDS_2118 "Internal controller" + IDS_2119 "Exit" + IDS_2120 "No ROMs found" + IDS_2121 "Save changes\nThis will hard reset the emulated machine." + IDS_2122 "Discard changes\nAll changes made to the settings will be lost." + IDS_2123 "Cancel\nGo back to the Settings window." + IDS_2124 "About " EMU_NAME + IDS_2125 EMU_NAME " v" EMU_VERSION + IDS_2126 "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information." + IDS_2127 "OK" + IDS_2128 "Hardware not available" +#ifdef _WIN32 +#define LIB_NAME_PCAP "WinPcap" +#else +#define LIB_NAME_PCAP "libpcap" +#endif + IDS_2129 "Make sure " LIB_NAME_PCAP " is installed and that you are on a " LIB_NAME_PCAP "-compatible network connection." + IDS_2130 "Invalid configuration" +#ifdef _WIN32 +#define LIB_NAME_FREETYPE "freetype.dll" +#else +#define LIB_NAME_FREETYPE "libfreetype" +#endif + IDS_2131 LIB_NAME_FREETYPE " is required for ESC/P printer emulation." +#ifdef _WIN32 +#define LIB_NAME_GS "gsdll32.dll" +#else +#define LIB_NAME_GS "libgs" +#endif + IDS_2132 LIB_NAME_GS " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +#ifdef _WIN32 +#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" +#else +#define LIB_NAME_FLUIDSYNTH "libfluidsynth" +#endif + IDS_2133 LIB_NAME_FLUIDSYNTH " is required for FluidSynth MIDI output." + IDS_2134 "Entering fullscreen mode" + IDS_2135 "Don't show this message again" + IDS_2136 "Don't Exit" + IDS_2137 "Reset" + IDS_2138 "Don't Reset" END STRINGTABLE DISCARDABLE @@ -971,16 +1008,24 @@ BEGIN IDS_4101 "Custom (large)..." IDS_4102 "Add New Hard Disk" IDS_4103 "Add Existing Hard Disk" - IDS_4104 "Attempting to create a HDI image larger than 4 GB" - IDS_4105 "Attempting to create a hard disk image beyond the 28-bit LBA limit" + IDS_4104 "HDI disk images cannot be larger than 4 GB." + IDS_4105 "Disk images cannot be larger than 127 GB." IDS_4106 "Hard disk images (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0All files (*.*)\0*.*\0" - IDS_4107 "Unable to open the file for read" - IDS_4108 "Unable to open the file for write" - IDS_4109 "HDI or HDX images with a sector size that is not 512 are not supported" + IDS_4107 "Unable to read file" + IDS_4108 "Unable to write file" + IDS_4109 "HDI or HDX images with a sector size other than 512 are not supported." IDS_4110 "USB is not yet supported" - IDS_4111 "This image exists and will be overwritten.\nAre you sure you want to use it?" - IDS_4112 "Please enter a valid file name" - IDS_4113 "The image has been successfully created." + IDS_4111 "Disk image file already exists" + IDS_4112 "Please specify a valid file name." + IDS_4113 "Disk image created" + IDS_4114 "Make sure the file exists and is readable." + IDS_4115 "Make sure the file is being saved to a writable directory." + IDS_4116 "Disk image too large" + IDS_4117 "Remember to partition and format the newly-created drive." + IDS_4118 "The selected file will be overwritten. Are you sure you want to use it?" + IDS_4119 "Unsupported disk image" + IDS_4120 "Overwrite" + IDS_4121 "Don't Overwrite" IDS_4352 "MFM/RLL" IDS_4353 "XTA" diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 4fc57b182..3d48ac37a 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,8 +8,6 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.144 2020/06/06 -# # Authors: Miran Grca, # Fred N. van Kempen, # @@ -35,6 +33,9 @@ ifeq ($(DEV_BUILD), y) ifndef DEV_BRANCH DEV_BRANCH := y endif + ifndef 596B + 596B := y + endif ifndef AMD_K5 AMD_K5 := y endif @@ -63,14 +64,11 @@ ifeq ($(DEV_BUILD), y) VECTRA54 := y endif ifndef VPP60 - VP660 := y + VPP60 := y endif ifndef SIEMENS SIEMENS := y endif - ifndef 596B - 596B := y - endif ifndef VGAWONDER VGAWONDER := y endif @@ -96,6 +94,9 @@ else ifndef DEV_BRANCH DEV_BRANCH := n endif + ifndef 596B + 596B := n + endif ifndef AMD_K5 AMD_K5 := n endif @@ -124,10 +125,10 @@ else VECTRA54 := n endif ifndef VPP60 - VP660 := n + VPP60 := n endif - ifndef 596B - 596B := n + ifndef SIEMENS + SIEMENS := n endif ifndef VGAWONDER VGAWONDER := n @@ -171,11 +172,8 @@ endif ifndef WX WX := n endif -ifndef USB -USB := n -endif ifndef DINPUT - DINPUT := y + DINPUT := n endif ifndef OPENAL OPENAL := y @@ -186,13 +184,22 @@ endif ifndef MUNT MUNT := y endif +ifndef NEW_DYNAREC + NEW_DYNAREC := n +endif ifndef DYNAREC DYNAREC := y +endif +ifeq ($(DYNAREC), y) ifeq ($(ARM), y) - DYNAREC := n + ifeq ($(NEW_DYNAREC), n) + DYNAREC := n + endif endif ifeq ($(ARM64), y) - DYNAREC := n + ifeq ($(NEW_DYNAREC), n) + DYNAREC := n + endif endif endif ifndef DISCORD @@ -200,6 +207,14 @@ ifndef DISCORD endif +# Path to the dynamic recompiler code. +ifeq ($(NEW_DYNAREC), y) + CODEGEN := codegen_new +else + CODEGEN := codegen +endif + + # Name of the executable. ifndef PROG ifneq ($(WX), n) @@ -245,12 +260,12 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH := $(EXPATH) . cpu cpu_common \ - cdrom chipset disk floppy game machine \ - printer \ - sound \ +VPATH := $(EXPATH) . $(CODEGEN) cpu \ + cdrom chipset device disk floppy \ + game machine mem printer \ + sio sound \ sound/munt sound/munt/c_interface sound/munt/sha1 \ - sound/munt/srchelper \ + sound/munt/srchelper sound/munt/srchelper/srctools/src \ sound/resid-fp \ scsi video network network/slirp win ifeq ($(X64), y) @@ -259,7 +274,7 @@ else TOOL_PREFIX := i686-w64-mingw32- endif CPP := ${TOOL_PREFIX}g++ -CC := gcc +CC := ${TOOL_PREFIX}gcc WINDRES := windres STRIP := strip ifeq ($(ARM64), y) @@ -280,7 +295,7 @@ DEPFILE := win/.depends # Set up the correct toolchain flags. OPTS := $(EXTRAS) $(STUFF) OPTS += -Iinclude \ - -iquote cpu -iquote cpu_common + -iquote $(CODEGEN) -iquote cpu ifdef EXFLAGS OPTS += $(EXFLAGS) endif @@ -319,7 +334,7 @@ else endif endif endif -AFLAGS := -msse2 -mfpmath=387 +AFLAGS := -msse2 -mfpmath=sse ifeq ($(ARM), y) DFLAGS := -march=armv7-a AOPTIM := @@ -343,22 +358,54 @@ endif # Optional modules. ifeq ($(DYNAREC), y) -ifeq ($(X64), y) -PLATCG := codegen_x86-64.o codegen_accumulate_x86-64.o -else -PLATCG := codegen_x86.o codegen_accumulate_x86.o -endif - OPTS += -DUSE_DYNAREC RFLAGS += -DUSE_DYNAREC -DYNARECOBJ := 386_dynarec_ops.o \ - codegen.o \ - codegen_ops.o codegen_timing_486.o \ + + ifeq ($(NEW_DYNAREC), y) + OPTS += -DUSE_NEW_DYNAREC + RFLAGS += -DUSE_NEW_DYNAREC + + ifeq ($(X64), y) + PLATCG := codegen_backend_x86-64.o codegen_backend_x86-64_ops.o codegen_backend_x86-64_ops_sse.o \ + codegen_backend_x86-64_uops.o + else ifeq ($(ARM64), y) + PLATCG := codegen_backend_arm64.o codegen_backend_arm64_ops.o codegen_backend_arm64_uops.o \ + codegen_backend_arm64_imm.o + else ifeq ($(ARM), y) + PLATCG := codegen_backend_arm.o codegen_backend_arm_ops.o codegen_backend_arm_uops.o + else + PLATCG := codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o \ + codegen_backend_x86_ops_sse.o codegen_backend_x86_uops.o + endif + + DYNARECOBJ := codegen.o codegen_accumulate.o codegen_allocator.o codegen_block.o codegen_ir.o codegen_ops.o \ + codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ + codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_helpers.o \ + codegen_ops_jump.o codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ + codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ + codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o $(PLATCG) + else + ifeq ($(X64), y) + PLATCG := codegen_x86-64.o codegen_accumulate_x86-64.o + else + PLATCG := codegen_x86.o codegen_accumulate_x86.o + endif + + DYNARECOBJ := codegen.o \ + codegen_ops.o $(PLATCG) + endif + + CGTOBJ := codegen_timing_486.o \ codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ - codegen_timing_p6.o codegen_timing_winchip.o codegen_timing_winchip2.o $(PLATCG) + codegen_timing_p6.o codegen_timing_winchip.o codegen_timing_winchip2.o +else + ifeq ($(NEW_DYNAREC), y) + OPTS += -DUSE_NEW_DYNAREC + RFLAGS += -DUSE_NEW_DYNAREC + endif endif -ifneq ($(WX), n) +ifeq ($(WX), y) OPTS += -DUSE_WX $(WX_FLAGS) LIBS += $(WX_LIBS) UIOBJ := wx_main.o wx_ui.o wx_stbar.o wx_render.o @@ -384,8 +431,10 @@ MUNTOBJ := midi_mt32.o \ Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \ LA32FloatWaveGenerator.o LA32WaveGenerator.o \ MidiStreamParser.o Part.o Partial.o PartialManager.o \ - Poly.o ROMInfo.o SampleRateConverter_dummy.o Synth.o \ - Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o + Poly.o ROMInfo.o SampleRateConverter.o \ + FIRResampler.o IIR2xResampler.o LinearResampler.o ResamplerModel.o \ + SincResampler.o InternalResampler.o \ + Synth.o Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o endif ifeq ($(VNC), y) @@ -484,24 +533,13 @@ endif endif -# Options for works-in-progress. -ifndef SERIAL -SERIAL := serial.o -endif - - # Final versions of the toolchain flags. CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ - $(AFLAGS) -pipe -fomit-frame-pointer -mstackrealign -Wall \ + $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ -fno-strict-aliasing -# -funroll-loops # Add freetyp2 references through pkgconfig -ifeq ($(DEBUG), y) -CFLAGS := $(CFLAGS) -fstack-protector-all `pkg-config --cflags freetype2` -else CFLAGS := $(CFLAGS) `pkg-config --cflags freetype2` -endif CXXFLAGS := $(CFLAGS) @@ -510,24 +548,22 @@ CXXFLAGS := $(CFLAGS) # Create the (final) list of objects to build. # ######################################################################### MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ - nmi.o pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o rom.o \ - usb.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \ - via_vt82c596b.o $(VNCOBJ) + nmi.o pic.o pit.o port_92.o ppi.o pci.o mca.o \ + usb.o device.o nvr.o nvr_at.o nvr_ps2.o \ + $(VNCOBJ) -INTELOBJ := intel_flash.o \ - intel_sio.o intel_piix.o +MEMOBJ := intel_flash.o mem.o rom.o spd.o sst_flash.o CPUOBJ := cpu.o cpu_table.o \ - 808x.o \ - 386.o 386_common.o \ - 386_dynarec.o \ - x86seg.o x87.o \ + 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o $(CGTOBJ) \ + x86seg.o x87.o x87_timings.o \ $(DYNARECOBJ) CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \ - intel_4x0.o neat.o opti495.o opti5x7.o scamp.o scat.o \ - rabbit.o sis_85c471.o sis_85c496.o \ - via_apollo.o via_vpx.o wd76c10.o + intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ + neat.o opti495.o opti5x7.o scamp.o scat.o \ + sis_85c310.o sis_85c471.o sis_85c496.o \ + via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o MCHOBJ := machine.o machine_table.o \ m_xt.o m_xt_compaq.o \ @@ -542,33 +578,36 @@ MCHOBJ := machine.o machine_table.o \ m_ps2_isa.o m_ps2_mca.o \ m_at_compaq.o \ m_at_286_386sx.o m_at_386dx_486.o \ - m_at_socket4_5.o m_at_socket7_s7.o m_at_super7_ss7.o \ - m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o + m_at_socket4_5.o m_at_socket7_s7.o m_at_sockets7.o \ + m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ - sio_detect.o sio_acc3221.o \ - sio_f82c710.o \ - sio_fdc37c66x.o sio_fdc37c669.o \ - sio_fdc37c93x.o \ - sio_pc87306.o \ - sio_w83787f.o \ - sio_w83877f.o sio_w83977f.o \ - sio_um8669f.o \ - smbus.o smbus_piix4.o spd.o \ +DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o serial.o \ + smbus.o smbus_piix4.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ - gameport.o \ - joystick_standard.o joystick_ch_flightstick_pro.o \ - joystick_sw_pad.o joystick_tm_fcs.o \ mouse.o \ mouse_bus.o \ mouse_serial.o mouse_ps2.o -FDDOBJ := fdd.o fdc.o fdi2raw.o \ +SIOOBJ := sio_acc3221.o \ + sio_f82c710.o \ + sio_fdc37c66x.o sio_fdc37c669.o \ + sio_fdc37c93x.o \ + sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87332.o \ + sio_w83787f.o \ + sio_w83877f.o sio_w83977f.o \ + sio_um8669f.o + +FDDOBJ := fdd.o fdc.o fdc_pii15xb.o \ + fdi2raw.o \ fdd_common.o fdd_86f.o \ fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \ fdd_mfm.o fdd_td0.o +GAMEOBJ := gameport.o \ + joystick_standard.o joystick_ch_flightstick_pro.o \ + joystick_sw_pad.o joystick_tm_fcs.o + HDDOBJ := hdd.o \ hdd_image.o hdd_table.o \ hdc.o \ @@ -585,10 +624,6 @@ ZIPOBJ := zip.o MOOBJ := mo.o -ifeq ($(USB), y) -USBOBJ := usb.o -endif - SCSIOBJ := scsi.o scsi_device.o \ scsi_cdrom.o scsi_disk.o \ scsi_x54x.o \ @@ -679,9 +714,9 @@ else PLATOBJ += win_joystick_rawinput.o endif -OBJ := $(MAINOBJ) $(INTELOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) \ - $(DEVOBJ) $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) \ - $(USBOBJ) $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) \ +OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ + $(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) \ + $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) \ $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) \ $(DISCORDOBJ) ifdef EXOBJ @@ -690,9 +725,6 @@ endif LIBS := -mwindows -lcomctl32 \ -lopenal -lole32 -ifeq ($(DEBUG), y) - LIBS += -lssp -endif ifeq ($(VNC), y) LIBS += $(VNCLIB) -lws2_32 @@ -770,10 +802,8 @@ pcap_if.res: pcap_if.rc pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res @echo Linking pcap_if.exe .. -ifeq ($(DEBUG), y) - @$(CC) $(LDFLAGS) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res -lssp -else @$(CC) $(LDFLAGS) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res +ifneq ($(DEBUG), y) @$(STRIP) pcap_if.exe endif diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw deleted file mode 100644 index 606ecf2e4..000000000 --- a/src/win/Makefile_ndr.mingw +++ /dev/null @@ -1,821 +0,0 @@ -# -# 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. -# -# Makefile for Win32 (MinGW32) environment. -# -# Version: @(#)Makefile.mingw 1.0.143 2020/06/06 -# -# Authors: Miran Grca, -# Fred N. van Kempen, -# - -# Various compile-time options. -ifndef STUFF -STUFF := -endif - -# Add feature selections here. -ifndef EXTRAS -EXTRAS := -endif - -ifndef DEV_BUILD -DEV_BUILD := n -endif - -ifeq ($(DEV_BUILD), y) - ifndef DEBUG - DEBUG := y - endif - ifndef DEV_BRANCH - DEV_BRANCH := y - endif - ifndef AMD_K5 - AMD_K5 := y - endif - ifndef CL5422 - CL5422 := y - endif - ifndef LASERXT - LASERXT := y - endif - ifndef MGA - MGA := y - endif - ifndef PAS16 - PAS16 := n - endif - ifndef PORTABLE3 - PORTABLE3 := y - endif - ifndef PS1M2133 - PS1M2133 := y - endif - ifndef PS2M70T4 - PS2M70T4 := y - endif - ifndef VECTRA54 - VECTRA54 := y - endif - ifndef VPP60 - VPP60 := y - endif - ifndef SIEMENS - SIEMENS := y - endif - ifndef 596B - 596B := y - endif - ifndef VGAWONDER - VGAWONDER := y - endif - ifndef VNC - VNC := y - endif - ifndef WIN471 - WIN471 := y - endif - ifndef XL24 - XL24 := y - endif - ifndef NO_SIO - NO_SIO := y - endif - ifndef GUSMAX - GUSMAX := y - endif -else - ifndef DEBUG - DEBUG := n - endif - ifndef DEV_BRANCH - DEV_BRANCH := n - endif - ifndef AMD_K5 - AMD_K5 := n - endif - ifndef CL5422 - CL5422 := n - endif - ifndef LASERXT - LASERXT := n - endif - ifndef MGA - MGA := n - endif - ifndef PAS16 - PAS16 := n - endif - ifndef PORTABLE3 - PORTABLE3 := n - endif - ifndef PS1M2133 - PS1M2133 := n - endif - ifndef PS2M70T4 - PS2M70T4 := n - endif - ifndef VECTRA54 - VECTRA54 := n - endif - ifndef VPP60 - VPP60 := n - endif - ifndef SIEMENS - SIEMENS := n - endif - ifndef 596B - 596B := n - endif - ifndef VGAWONDER - VGAWONDER := n - endif - ifndef VNC - VNC := n - endif - ifndef WIN471 - WIN471 := n - endif - ifndef XL24 - XL24 := n - endif - ifndef NO_SIO - NO_SIO := n - endif - ifndef GUSMAX - GUSMAX := n - endif -endif - -# Defaults for several build options (possibly defined in a chained file.) -ifndef AUTODEP -AUTODEP := n -endif -ifndef OPTIM -OPTIM := n -endif -ifndef RELEASE -RELEASE := n -endif -ifndef X64 -X64 := n -endif -ifndef ARM -ARM := n -endif -ifndef ARM64 -ARM64 := n -endif -ifndef WX -WX := n -endif -ifndef USB -USB := n -endif -ifndef DINPUT - DINPUT := y -endif -ifndef OPENAL -OPENAL := y -endif -ifndef FLUIDSYNTH -FLUIDSYNTH := y -endif -ifndef MUNT -MUNT := y -endif -ifndef DYNAREC - DYNAREC := y -endif -ifndef DISCORD - DISCORD := y -endif - - -# Name of the executable. -ifndef PROG - ifneq ($(WX), n) - PROG := Wx86Box - else - PROG := 86Box - endif -endif - -# WxWidgets basic info. Extract using the config program. -ifneq ($(WX), n) - EXPATH += wx - WX_CONFIG := wx-config.exe - ifeq ($(WX), y) - WX_PATH := C:/MinGW32/WxWidgets - WX_FLAGS := -I$(WX_PATH)/lib/wx/include/msw-unicode-3.0 \ - -I$(WX_PATH)/include/wx-3.0 \ - -D__WXMSW__ -DWX_PRECOMP -D_FILE_OFFSET_BITS=64 -pthread -# -lwx_mswu_gl-3.0 -lwxtiff-3.0 -llzma - WX_LIBS := -mwindows -mthreads -L$(WX_PATH)/lib \ - -lwx_mswu-3.0.dll \ - -lrpcrt4 -loleaut32 -lole32 -luuid \ - -lwinspool -lwinmm -lshell32 -lcomctl32 \ - -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 - endif - ifeq ($(WX), static) - WX_PATH := C:/MinGW32/WxWidgets - WX_FLAGS := -I$(WX_PATH)/lib/wx/include/msw-unicode-3.0 \ - -I$(WX_PATH)/include/wx-3.0 \ - -D__WXMSW__ -DWX_PRECOMP -D_FILE_OFFSET_BITS=64 -pthread -# -lwx_mswu_gl-3.0 -lwxtiff-3.0 -llzma - WX_LIBS := -mwindows -mthreads -L$(WX_PATH)/lib \ - -lwx_mswu-3.0 -lwxscintilla-3.0 \ - -lwxjpeg-3.0 -lwxpng-3.0 -lwxzlib-3.0 \ - -lwxregexu-3.0 -lwxexpat-3.0 \ - -lrpcrt4 -loleaut32 -lole32 -luuid \ - -lwinspool -lwinmm -lshell32 -lcomctl32 \ - -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 - endif -endif - - -######################################################################### -# Nothing should need changing from here on.. # -######################################################################### -VPATH := $(EXPATH) . cpu_new cpu_common \ - cdrom chipset disk floppy game machine \ - printer \ - sound \ - sound/munt sound/munt/c_interface sound/munt/sha1 \ - sound/munt/srchelper \ - sound/resid-fp \ - scsi video network network/slirp win -ifeq ($(X64), y) -TOOL_PREFIX := x86_64-w64-mingw32- -else -TOOL_PREFIX := i686-w64-mingw32- -endif -CPP := ${TOOL_PREFIX}g++ -CC := ${TOOL_PREFIX}gcc -WINDRES := windres -STRIP := strip -ifeq ($(ARM64), y) -CPP := aarch64-w64-mingw32-g++ -CC := aarch64-w64-mingw32-gcc -WINDRES := aarch64-w64-mingw32-windres -STRIP := aarch64-w64-mingw32-strip -endif -ifeq ($(ARM), y) -CPP := armv7-w64-mingw32-g++ -CC := armv7-w64-mingw32-gcc -WINDRES := armv7-w64-mingw32-windres -STRIP := armv7-w64-mingw32-strip -endif -DEPS = -MMD -MF $*.d -c $< -DEPFILE := win/.depends - -# Set up the correct toolchain flags. -OPTS := $(EXTRAS) $(STUFF) -OPTS += -Iinclude \ - -iquote cpu_new -iquote cpu_common -ifdef EXFLAGS -OPTS += $(EXFLAGS) -endif -ifdef EXINC -OPTS += -I$(EXINC) -endif -ifeq ($(X64), y) - ifeq ($(OPTIM), y) - DFLAGS := -march=native - else - DFLAGS := - endif -else - ifeq ($(OPTIM), y) - DFLAGS := -march=native - else - DFLAGS := -march=i686 - endif -endif -ifeq ($(DEBUG), y) - DFLAGS += -ggdb -DDEBUG - AOPTIM := - ifndef COPTIM - COPTIM := -Og - endif -else - DFLAGS += -g0 - ifeq ($(OPTIM), y) - AOPTIM := -mtune=native - ifndef COPTIM - COPTIM := -O3 -ffp-contract=fast -flto - endif - else - ifndef COPTIM - COPTIM := -O3 - endif - endif -endif -AFLAGS := -msse2 -mfpmath=sse -ifeq ($(ARM), y) - DFLAGS := -march=armv7-a - AOPTIM := - AFLAGS := -mfloat-abi=hard -endif -ifeq ($(ARM64), y) - DFLAGS := -march=armv8-a - AOPTIM := - AFLAGS := -mfloat-abi=hard -endif -RFLAGS := --input-format=rc -O coff -Iinclude -OPTS += -DUSE_NEW_DYNAREC -ifeq ($(RELEASE), y) -OPTS += -DRELEASE_BUILD -RFLAGS += -DRELEASE_BUILD -endif -ifeq ($(VRAMDUMP), y) -OPTS += -DENABLE_VRAM_DUMP -RFLAGS += -DENABLE_VRAM_DUMP -endif - - -# Optional modules. -ifeq ($(DYNAREC), y) -ifeq ($(X64), y) -PLATCG := codegen_backend_x86-64.o codegen_backend_x86-64_ops.o codegen_backend_x86-64_ops_sse.o \ - codegen_backend_x86-64_uops.o -else ifeq ($(ARM64), y) -PLATCG := codegen_backend_arm64.o codegen_backend_arm64_ops.o codegen_backend_arm64_uops.o \ - codegen_backend_arm64_imm.o -else ifeq ($(ARM), y) -PLATCG := codegen_backend_arm.o codegen_backend_arm_ops.o codegen_backend_arm_uops.o -else -PLATCG := codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ - codegen_backend_x86_uops.o -endif - -OPTS += -DUSE_DYNAREC -RFLAGS += -DUSE_DYNAREC -DYNARECOBJ := 386_dynarec_ops.o \ - codegen.o codegen_accumulate.o codegen_allocator.o codegen_block.o codegen_ir.o codegen_ops.o \ - codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ - codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_helpers.o codegen_ops_jump.o \ - codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ - codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ - codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ - codegen_timing_p6.o codegen_timing_winchip.o codegen_timing_winchip2.o $(PLATCG) -endif - -ifneq ($(WX), n) - OPTS += -DUSE_WX $(WX_FLAGS) - LIBS += $(WX_LIBS) - UIOBJ := wx_main.o wx_ui.o wx_stbar.o wx_render.o -else - UIOBJ := win_ui.o win_stbar.o \ - win_sdl.o \ - win_dialog.o win_about.o \ - win_settings.o win_devconf.o win_snd_gain.o \ - win_new_floppy.o win_jsconf.o win_media_menu.o -endif - -ifeq ($(OPENAL), y) -OPTS += -DUSE_OPENAL -endif -ifeq ($(FLUIDSYNTH), y) -OPTS += -DUSE_FLUIDSYNTH -FSYNTHOBJ := midi_fluidsynth.o -endif - -ifeq ($(MUNT), y) -OPTS += -DUSE_MUNT -MUNTOBJ := midi_mt32.o \ - Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \ - LA32FloatWaveGenerator.o LA32WaveGenerator.o \ - MidiStreamParser.o Part.o Partial.o PartialManager.o \ - Poly.o ROMInfo.o SampleRateConverter_dummy.o Synth.o \ - Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o -endif - -ifeq ($(VNC), y) -OPTS += -DUSE_VNC -RFLAGS += -DUSE_VNC - ifneq ($(VNC_PATH), ) - OPTS += -I$(VNC_PATH)\INCLUDE - VNCLIB := -L$(VNC_PATH)\LIB - endif -VNCLIB += -lvncserver -VNCOBJ := vnc.o vnc_keymap.o -endif - -ifeq ($(DISCORD), y) -OPTS += -DUSE_DISCORD -RFLAGS += -DUSE_DISCORD -DISCORDOBJ := win_discord.o -endif - -# Options for the DEV branch. -ifeq ($(DEV_BRANCH), y) -OPTS += -DDEV_BRANCH -DEVBROBJ := - -ifeq ($(AMD_K5), y) -OPTS += -DUSE_AMD_K5 -endif - -ifeq ($(CL5422), y) -OPTS += -DUSE_CL5422 -endif - -ifeq ($(LASERXT), y) -OPTS += -DUSE_LASERXT -DEVBROBJ += m_xt_laserxt.o -endif - -ifeq ($(MGA), y) -OPTS += -DUSE_MGA -DEVBROBJ += vid_mga.o -endif - -ifeq ($(PAS16), y) -OPTS += -DUSE_PAS16 -DEVBROBJ += snd_pas16.o -endif - -ifeq ($(PORTABLE3), y) -OPTS += -DUSE_PORTABLE3 -endif - -ifeq ($(PS1M2133), y) -OPTS += -DUSE_PS1M2133 -endif - -ifeq ($(PS2M70T4), y) -OPTS += -DUSE_PS2M70T4 -endif - -ifeq ($(VECTRA54), y) -OPTS += -DUSE_VECTRA54 -endif - -ifeq ($(VPP60), y) -OPTS += -DUSE_VPP60 -endif - -ifeq ($(SIEMENS), y) -OPTS += -DUSE_SIEMENS -endif - -ifeq ($(596B), y) -OPTS += -DUSE_596B -endif - -ifeq ($(VGAWONDER), y) -OPTS += -DUSE_VGAWONDER -endif - -ifeq ($(WIN471), y) -OPTS += -DUSE_WIN471 -endif - -ifeq ($(XL24), y) -OPTS += -DUSE_XL24 -endif - -ifeq ($(NO_SIO), y) -OPTS += -DNO_SIO -endif - -ifeq ($(GUSMAX), y) -OPTS += -DUSE_GUSMAX -endif - -endif - - -# Options for works-in-progress. -ifndef SERIAL -SERIAL := serial.o -endif - - -# Final versions of the toolchain flags. -CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ - -fno-strict-aliasing - -# Add freetyp2 references through pkgconfig -CFLAGS := $(CFLAGS) `pkg-config --cflags freetype2` - -CXXFLAGS := $(CFLAGS) - - -######################################################################### -# Create the (final) list of objects to build. # -######################################################################### -MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ - nmi.o pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o rom.o \ - usb.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \ - via_vt82c596b.o $(VNCOBJ) - -INTELOBJ := intel_flash.o \ - intel_sio.o intel_piix.o - -CPUOBJ := cpu.o cpu_table.o \ - 808x.o \ - 386.o 386_common.o \ - 386_dynarec.o \ - x86seg.o x87.o \ - $(DYNARECOBJ) - -CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \ - intel_4x0.o neat.o opti495.o opti5x7.o scamp.o scat.o \ - rabbit.o sis_85c471.o sis_85c496.o \ - via_apollo.o via_vpx.o wd76c10.o - -MCHOBJ := machine.o machine_table.o \ - m_xt.o m_xt_compaq.o \ - m_xt_t1000.o m_xt_t1000_vid.o \ - m_xt_xi8088.o m_xt_zenith.o \ - m_pcjr.o \ - m_amstrad.o m_europc.o \ - m_olivetti_m24.o m_tandy.o \ - m_at.o m_at_commodore.o \ - m_at_t3100e.o m_at_t3100e_vid.o \ - m_ps1.o m_ps1_hdc.o \ - m_ps2_isa.o m_ps2_mca.o \ - m_at_compaq.o \ - m_at_286_386sx.o m_at_386dx_486.o \ - m_at_socket4_5.o m_at_socket7_s7.o m_at_super7_ss7.o \ - m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o - -DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ - sio_acc3221.o \ - sio_f82c710.o \ - sio_fdc37c66x.o sio_fdc37c669.o \ - sio_fdc37c93x.o \ - sio_pc87306.o \ - sio_w83787f.o \ - sio_w83877f.o sio_w83977f.o \ - sio_um8669f.o \ - smbus.o smbus_piix4.o spd.o \ - keyboard.o \ - keyboard_xt.o keyboard_at.o \ - gameport.o \ - joystick_standard.o joystick_ch_flightstick_pro.o \ - joystick_sw_pad.o joystick_tm_fcs.o \ - mouse.o \ - mouse_bus.o \ - mouse_serial.o mouse_ps2.o - -FDDOBJ := fdd.o fdc.o fdi2raw.o \ - fdd_common.o fdd_86f.o \ - fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \ - fdd_mfm.o fdd_td0.o - -HDDOBJ := hdd.o \ - hdd_image.o hdd_table.o \ - hdc.o \ - hdc_st506_xt.o hdc_st506_at.o \ - hdc_xta.o \ - hdc_esdi_at.o hdc_esdi_mca.o \ - hdc_xtide.o hdc_ide.o \ - hdc_ide_sff8038i.o - -CDROMOBJ := cdrom.o \ - cdrom_image_backend.o cdrom_image.o - -ZIPOBJ := zip.o - -MOOBJ := mo.o - -ifeq ($(USB), y) -USBOBJ := usb.o -endif - -SCSIOBJ := scsi.o scsi_device.o \ - scsi_cdrom.o scsi_disk.o \ - scsi_x54x.o \ - scsi_aha154x.o scsi_buslogic.o \ - scsi_ncr5380.o scsi_ncr53c8xx.o \ - scsi_spock.o - -NETOBJ := network.o \ - net_pcap.o \ - net_slirp.o \ - bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ - ip_input.o queue.o tcp_input.o debug.o ip_output.o \ - sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o \ - net_dp8390.o \ - net_3c503.o net_ne2000.o \ - net_pcnet.o net_wd8003.o - -PRINTOBJ := png.o prt_cpmap.o \ - prt_escp.o prt_text.o prt_ps.o - -SNDOBJ := sound.o \ - openal.o \ - snd_opl.o snd_opl_backend.o \ - nukedopl.o \ - snd_resid.o \ - convolve.o convolve-sse.o envelope.o extfilt.o \ - filter.o pot.o sid.o voice.o wave6581__ST.o \ - wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ - wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o \ - midi.o midi_system.o \ - snd_speaker.o \ - snd_pssj.o \ - snd_lpt_dac.o snd_lpt_dss.o \ - snd_adlib.o snd_adlibgold.o snd_ad1848.o snd_audiopci.o \ - snd_azt2316a.o \ - snd_cms.o \ - snd_gus.o \ - snd_sb.o snd_sb_dsp.o \ - snd_emu8k.o snd_mpu401.o \ - snd_sn76489.o snd_ssi2001.o \ - snd_wss.o \ - snd_ym7128.o - -VIDOBJ := video.o \ - vid_table.o \ - vid_cga.o vid_cga_comp.o \ - vid_compaq_cga.o \ - vid_mda.o \ - vid_hercules.o vid_herculesplus.o vid_incolor.o \ - vid_colorplus.o \ - vid_genius.o \ - vid_pgc.o vid_im1024.o \ - vid_sigma.o \ - vid_wy700.o \ - vid_ega.o vid_ega_render.o \ - vid_svga.o vid_svga_render.o \ - vid_vga.o \ - vid_ati_eeprom.o \ - vid_ati18800.o vid_ati28800.o \ - vid_ati_mach64.o vid_ati68860_ramdac.o \ - vid_bt48x_ramdac.o \ - vid_av9194.o \ - vid_icd2061.o vid_ics2595.o \ - vid_cl54xx.o \ - vid_et4000.o vid_sc1502x_ramdac.o \ - vid_et4000w32.o vid_stg_ramdac.o \ - vid_ht216.o \ - vid_oak_oti.o \ - vid_paradise.o \ - vid_ti_cf62011.o \ - vid_tvga.o \ - vid_tgui9440.o vid_tkd8001_ramdac.o \ - vid_att20c49x_ramdac.o \ - vid_s3.o vid_s3_virge.o \ - vid_sdac_ramdac.o \ - vid_voodoo.o - -PLATOBJ := win.o \ - win_dynld.o win_thread.o \ - win_cdrom.o win_keyboard.o \ - win_crashdump.o win_midi.o \ - win_mouse.o - -ifeq ($(DINPUT), y) - PLATOBJ += win_joystick.o -else - PLATOBJ += win_joystick_rawinput.o -endif - -OBJ := $(MAINOBJ) $(INTELOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) \ - $(DEVOBJ) $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) \ - $(USBOBJ) $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) \ - $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) \ - $(DISCORDOBJ) -ifdef EXOBJ -OBJ += $(EXOBJ) -endif - -LIBS := -mwindows -lcomctl32 \ - -lopenal -lole32 - -ifeq ($(VNC), y) -LIBS += $(VNCLIB) -lws2_32 -endif -ifneq ($(WX), n) -LIBS += $(WX_LIBS) -lm -endif -LIBS += -lpng -lz -lwsock32 -lshell32 -liphlpapi -lpsapi -lSDL2 -limm32 -lhid -lsetupapi -loleaut32 -lversion -lwinmm -static -lstdc++ -ifneq ($(X64), y) -LIBS += -Wl,--large-address-aware -endif -ifeq ($(DINPUT), y) - LIBS += -ldinput8 -endif - -LIBS += -static - -# Build module rules. -ifeq ($(AUTODEP), y) -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< -else -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) -c $< - -%.d: %.c $(wildcard $*.d) - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -E $< >NUL - -%.d: %.cc $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >NUL - -%.d: %.cpp $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >NUL -endif - - -all: $(PROG).exe - - -86Box.res: 86Box.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) $(EXTRAS) -i $< -o 86Box.res - -$(PROG).exe: $(OBJ) 86Box.res - @echo Linking $(PROG).exe .. - @$(CC) $(LDFLAGS) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -ifneq ($(DEBUG), y) - @$(STRIP) $(PROG).exe -endif - -pcap_if.res: pcap_if.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) -i $< -o pcap_if.res - -pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res - @echo Linking pcap_if.exe .. - @$(CC) $(LDFLAGS) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res -ifneq ($(DEBUG), y) - @$(STRIP) pcap_if.exe -endif - -hello.exe: hello.o - $(CXX) $(LDFLAGS) -o hello.exe hello.o $(WXLIBS) $(LIBS) -ifneq ($(DEBUG), y) - @$(STRIP) hello.exe -endif - - -clean: - @echo Cleaning objects.. - @-rm -f *.o 2>NUL - @-rm -f *.res 2>NUL - -clobber: clean - @echo Cleaning executables.. - @-rm -f *.d 2>NUL - @-rm -f *.exe 2>NUL -# @-rm -f $(DEPFILE) 2>NUL - -ifneq ($(AUTODEP), y) -depclean: - @-rm -f $(DEPFILE) 2>NUL - @echo Creating dependencies.. - @echo # Run "make depends" to re-create this file. >$(DEPFILE) - -depends: DEPOBJ=$(OBJ:%.o=%.d) -depends: depclean $(OBJ:%.o=%.d) - @-cat $(DEPOBJ) >>$(DEPFILE) - @-rm -f $(DEPOBJ) - -$(DEPFILE): -endif - - -# Module dependencies. -ifeq ($(AUTODEP), y) -#-include $(OBJ:%.o=%.d) (better, but sloooowwwww) --include *.d -else -include $(wildcard $(DEPFILE)) -endif - - -# End of Makefile.mingw. diff --git a/src/win/win.c b/src/win/win.c index 9bdb91a56..c109c9b8b 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -789,8 +789,8 @@ plat_setfullscreen(int on) if (on && video_fullscreen) return; if (on && video_fullscreen_first) { - video_fullscreen_first = 0; - ui_msgbox(MBX_INFO, (wchar_t *)IDS_2052); + if (ui_msgbox_header(MBX_INFO | MBX_DONTASK, (wchar_t *) IDS_2134, (wchar_t *) IDS_2052) == 10) + video_fullscreen_first = 0; } /* OK, claim the video. */ diff --git a/src/win/win_about.c b/src/win/win_about.c index 0c57c346d..b09efa478 100644 --- a/src/win/win_about.c +++ b/src/win/win_about.c @@ -21,6 +21,7 @@ #include #include #undef BITMAP +#include #include #include #include @@ -31,45 +32,29 @@ #include <86box/win.h> -#if defined(__amd64__) || defined(__aarch64__) -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -AboutDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - HANDLE ih; - - switch (message) { - case WM_INITDIALOG: - plat_pause(1); - h = GetDlgItem(hdlg, IDC_ABOUT_ICON); - ih = LoadImage(hinstance,(PCTSTR)10,IMAGE_ICON,64,64,0); - SendMessage(h, STM_SETIMAGE, (WPARAM)IMAGE_ICON, - (LPARAM)ih); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - case IDCANCEL: - EndDialog(hdlg, 0); - plat_pause(0); - return TRUE; - - default: - break; - } - break; - } - - return(FALSE); -} - - void AboutDialogCreate(HWND hwnd) { - DialogBox(hinstance, (LPCTSTR)DLG_ABOUT, hwnd, AboutDialogProcedure); + int i; + TASKDIALOGCONFIG tdconfig = {0}; + TASKDIALOG_BUTTON tdbuttons[] = { + {IDOK, EMU_SITE}, + {IDCANCEL, MAKEINTRESOURCE(IDS_2127)} + }; + + tdconfig.cbSize = sizeof(tdconfig); + tdconfig.hwndParent = hwnd; + tdconfig.hInstance = hinstance; + tdconfig.dwCommonButtons = 0; + tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_2124); + tdconfig.pszMainIcon = (PCWSTR) 10; + tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2125); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2126); + tdconfig.cButtons = ARRAYSIZE(tdbuttons); + tdconfig.pButtons = tdbuttons; + tdconfig.nDefaultButton = IDCANCEL; + TaskDialogIndirect(&tdconfig, &i, NULL, NULL); + + if (i == IDOK) + ShellExecute(hwnd, L"open", L"https://" EMU_SITE, NULL, NULL, SW_SHOW); } diff --git a/src/win/win_dialog.c b/src/win/win_dialog.c index 7844e1c8c..bc8964f95 100644 --- a/src/win/win_dialog.c +++ b/src/win/win_dialog.c @@ -34,93 +34,122 @@ #include <86box/win.h> + +#define STRING_OR_RESOURCE(s) ((!(s)) ? (NULL) : ((((uintptr_t)s) < ((uintptr_t)65636)) ? (MAKEINTRESOURCE(s)) : (s))) + + WCHAR wopenfilestring[512]; char openfilestring[512]; uint8_t filterindex = 0; int -ui_msgbox(int flags, void *arg) +ui_msgbox(int flags, void *message) { - WCHAR temp[512]; - DWORD fl = 0; - WCHAR *str = NULL; - WCHAR *cap = NULL; + return ui_msgbox_ex(flags, NULL, message, NULL, NULL, NULL); +} + +int +ui_msgbox_header(int flags, void *header, void *message) +{ + return ui_msgbox_ex(flags, header, message, NULL, NULL, NULL); +} + + +int +ui_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) { + WCHAR temp[512]; + TASKDIALOGCONFIG tdconfig = {0}; + TASKDIALOG_BUTTON tdbuttons[3], + tdb_yes = {IDYES, STRING_OR_RESOURCE(btn1)}, + tdb_no = {IDNO, STRING_OR_RESOURCE(btn2)}, + tdb_cancel = {IDCANCEL, STRING_OR_RESOURCE(btn3)}, + tdb_exit = {IDCLOSE, MAKEINTRESOURCE(IDS_2119)}; + int ret = 0, checked = 0; + + /* Configure the default OK button. */ + tdconfig.cButtons = 0; + if (btn1) + tdbuttons[tdconfig.cButtons++] = tdb_yes; + else + tdconfig.dwCommonButtons = TDCBF_OK_BUTTON; + + /* Configure the message type. */ switch(flags & 0x1f) { case MBX_INFO: /* just an informational message */ - fl = (MB_OK | MB_ICONINFORMATION); - cap = plat_get_string(IDS_STRINGS); /* "86Box" */ + tdconfig.pszMainIcon = TD_INFORMATION_ICON; break; case MBX_ERROR: /* error message */ if (flags & MBX_FATAL) { - fl = (MB_OK | MB_ICONERROR); - cap = plat_get_string(IDS_2050); /* "Fatal Error"*/ + tdconfig.pszMainIcon = TD_ERROR_ICON; + tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2050); /* "Fatal error" */ + + /* replace default "OK" button with "Exit" button */ + if (btn1) + tdconfig.cButtons = 0; + else + tdconfig.dwCommonButtons = 0; + tdbuttons[tdconfig.cButtons++] = tdb_exit; } else { - fl = (MB_OK | MB_ICONWARNING); - cap = plat_get_string(IDS_2049); /* "Error" */ + tdconfig.pszMainIcon = TD_WARNING_ICON; + tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2049); /* "Error" */ } break; case MBX_QUESTION: /* question */ - fl = (MB_YESNOCANCEL | MB_ICONQUESTION); - cap = plat_get_string(IDS_STRINGS); /* "86Box" */ - break; + case MBX_QUESTION_YN: + if (!btn1) /* replace default "OK" button with "Yes" button */ + tdconfig.dwCommonButtons = TDCBF_YES_BUTTON; - case MBX_QUESTION_YN: /* question */ - fl = (MB_YESNO | MB_ICONQUESTION); - cap = plat_get_string(IDS_STRINGS); /* "86Box" */ + if (btn2) /* "No" button */ + tdbuttons[tdconfig.cButtons++] = tdb_no; + else + tdconfig.dwCommonButtons |= TDCBF_NO_BUTTON; + + if (flags & MBX_QUESTION) { + if (btn3) /* "Cancel" button */ + tdbuttons[tdconfig.cButtons++] = tdb_cancel; + else + tdconfig.dwCommonButtons |= TDCBF_CANCEL_BUTTON; + } break; } - /* If ANSI string, convert it. */ - str = (WCHAR *)arg; + /* If the message is an ANSI string, convert it. */ + tdconfig.pszContent = (WCHAR *) STRING_OR_RESOURCE(message); if (flags & MBX_ANSI) { - mbstowcs(temp, (char *)arg, strlen((char *)arg)+1); - str = temp; - } else { - /* - * It's a Unicode string. - * - * Well, no, maybe not. It could also be one of the - * strings stored in the Resources. Those are wide, - * but referenced by a numeric ID. - * - * The good news is, that strings are usually stored - * in the executable near the end of the code/rodata - * segment. This means, that *real* string pointers - * usually have a pretty high (numeric) value, much - * higher than the numeric ID's. So, we guesswork - * that if the value of 'arg' is low, its an ID.. - */ - if (((uintptr_t)arg) < ((uintptr_t)65636)) - str = plat_get_string((intptr_t)arg); + mbstowcs(temp, (char *)message, strlen((char *)message)+1); + tdconfig.pszContent = temp; } - /* At any rate, we do have a valid (wide) string now. */ - fl = MessageBox(hwndMain, /* our main window */ - str, /* error message etc */ - cap, /* window caption */ - fl); + /* Configure the rest of the TaskDialog. */ + tdconfig.cbSize = sizeof(tdconfig); + tdconfig.hwndParent = hwndMain; + if (flags & MBX_LINKS) + tdconfig.dwFlags = TDF_USE_COMMAND_LINKS; + tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_STRINGS); + if (header) + tdconfig.pszMainInstruction = STRING_OR_RESOURCE(header); + tdconfig.pButtons = tdbuttons; + if (flags & MBX_DONTASK) + tdconfig.pszVerificationText = MAKEINTRESOURCE(IDS_2135); + + /* Run the TaskDialog. */ + TaskDialogIndirect(&tdconfig, &ret, NULL, &checked); /* Convert return values to generic ones. */ - if (fl == IDNO) fl = 1; - else if (fl == IDCANCEL) fl = -1; - else fl = 0; + if (ret == IDNO) ret = 1; + else if (ret == IDCANCEL) ret = -1; + else ret = 0; - return(fl); + if (checked) ret += 10; + + return(ret); } -#if 0 -int -msgbox_reset_yn(HWND hwnd) -{ - return(MessageBox(hwnd, plat_get_string(IDS_2051), -#endif - - int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save) { diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c index fe3d6153d..6340d36b4 100644 --- a/src/win/win_media_menu.c +++ b/src/win/win_media_menu.c @@ -429,7 +429,7 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) plat_pause(1); ret = d86f_export(id, wopenfilestring); if (!ret) - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4108); + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4108, (wchar_t *) IDS_4115); plat_pause(0); } break; diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index 78c51b497..33c83299f 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -515,7 +515,7 @@ static wchar_t fd_file_name[1024]; /* Show a MessageBox dialog. This is nasty, I know. --FvK */ static int -new_floppy_msgbox(HWND hwnd, int type, void *arg) +new_floppy_msgbox_header(HWND hwnd, int flags, void *header, void *message) { HWND h; int i; @@ -523,7 +523,24 @@ new_floppy_msgbox(HWND hwnd, int type, void *arg) h = hwndMain; hwndMain = hwnd; - i = ui_msgbox(type, arg); + i = ui_msgbox_header(flags, header, message); + + hwndMain = h; + + return(i); +} + + +static int +new_floppy_msgbox_ex(HWND hwnd, int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) +{ + HWND h; + int i; + + h = hwndMain; + hwndMain = hwnd; + + i = ui_msgbox_ex(flags, header, message, btn1, btn2, btn3); hwndMain = h; @@ -607,7 +624,7 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) //ui_sb_mount_floppy_img(fdd_id, sb_part, 0, fd_file_name); floppy_mount(fdd_id, fd_file_name, 0); } else { - new_floppy_msgbox(hdlg, MBX_ERROR, (wchar_t *)IDS_4108); + new_floppy_msgbox_header(hdlg, MBX_ERROR, (wchar_t *) IDS_4108, (wchar_t *) IDS_4115); return TRUE; } /*FALLTHROUGH*/ @@ -637,7 +654,7 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) f = _wfopen(wopenfilestring, L"rb"); if (f != NULL) { fclose(f); - if (new_floppy_msgbox(hdlg, MBX_QUESTION, (wchar_t *)IDS_4111) != 0) /* yes */ + if (new_floppy_msgbox_ex(hdlg, MBX_QUESTION, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) /* yes */ return FALSE; } SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 413fe2daf..8eb444253 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -52,6 +52,8 @@ #include <86box/hdc_ide.h> #include <86box/zip.h> #include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/network.h> #include <86box/sound.h> #include <86box/midi.h> @@ -70,7 +72,7 @@ static int first_cat = 0; /* Machine category */ -static int temp_machine, temp_cpu_m, temp_cpu, temp_wait_states, temp_fpu, temp_sync; +static int temp_machine_type, temp_machine, temp_cpu_m, temp_cpu, temp_wait_states, temp_fpu, temp_sync; static uint32_t temp_mem_size; #ifdef USE_DYNAREC static int temp_dynarec; @@ -95,7 +97,7 @@ static int temp_lpt_devices[3]; static int temp_serial[2], temp_lpt[3]; /* Other peripherals category */ -static int temp_hdc, temp_scsi_card, temp_ide_ter, temp_ide_qua; +static int temp_fdc_card, temp_hdc, temp_scsi_card, temp_ide_ter, temp_ide_qua; static int temp_bugger; static int temp_postcard; static int temp_isartc; @@ -120,8 +122,10 @@ static HWND hwndParentDialog, hwndChildDialog; static uint32_t displayed_category = 0; extern int is486; +static int listtomachinetype[256], machinetypetolist[256]; static int listtomachine[256], machinetolist[256]; static int settings_device_to_list[2][20], settings_list_to_device[2][20]; +static int settings_fdc_to_list[2][20], settings_list_to_fdc[2][20]; static int settings_midi_to_list[20], settings_list_to_midi[20]; static int settings_midi_in_to_list[20], settings_list_to_midi_in[20]; @@ -174,7 +178,7 @@ image_list_init(HWND hwndList, const uint8_t *icon_ids) /* Show a MessageBox dialog. This is nasty, I know. --FvK */ static int -settings_msgbox(int type, void *arg) +settings_msgbox_header(int flags, void *header, void *message) { HWND h; int i; @@ -182,7 +186,24 @@ settings_msgbox(int type, void *arg) h = hwndMain; hwndMain = hwndParentDialog; - i = ui_msgbox(type, arg); + i = ui_msgbox_header(flags, header, message); + + hwndMain = h; + + return(i); +} + + +static int +settings_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3) +{ + HWND h; + int i; + + h = hwndMain; + hwndMain = hwndParentDialog; + + i = ui_msgbox_ex(flags, header, message, btn1, btn2, btn3); hwndMain = h; @@ -197,6 +218,7 @@ win_settings_init(void) int i = 0; /* Machine category */ + temp_machine_type = machines[machine].type; temp_machine = machine; temp_cpu_m = cpu_manufacturer; temp_wait_states = cpu_waitstates; @@ -205,7 +227,7 @@ win_settings_init(void) #ifdef USE_DYNAREC temp_dynarec = cpu_use_dynarec; #endif - temp_fpu = enable_external_fpu; + temp_fpu = fpu_type; temp_sync = time_sync; /* Video category */ @@ -245,6 +267,7 @@ win_settings_init(void) /* Other peripherals category */ temp_scsi_card = scsi_card_current; + temp_fdc_card = fdc_type; temp_hdc = hdc_current; temp_ide_ter = ide_ter_enabled; temp_ide_qua = ide_qua_enabled; @@ -318,7 +341,7 @@ win_settings_changed(void) #ifdef USE_DYNAREC i = i || (temp_dynarec != cpu_use_dynarec); #endif - i = i || (temp_fpu != enable_external_fpu); + i = i || (temp_fpu != fpu_type); i = i || (temp_sync != time_sync); /* Video category */ @@ -354,6 +377,7 @@ win_settings_changed(void) /* Peripherals category */ i = i || (scsi_card_current != temp_scsi_card); + i = i || (fdc_type != temp_fdc_card); i = i || (hdc_current != temp_hdc); i = i || (temp_ide_ter != ide_ter_enabled); i = i || (temp_ide_qua != ide_qua_enabled); @@ -389,15 +413,21 @@ static int settings_msgbox_reset(void) { int changed, i = 0; + HWND h; changed = win_settings_changed(); if (changed) { - i = settings_msgbox(MBX_QUESTION, (wchar_t *)IDS_2051); + h = hwndMain; + hwndMain = hwndParentDialog; + + i = ui_msgbox_ex(MBX_QUESTION | MBX_LINKS, (wchar_t *) IDS_2051, NULL, (wchar_t *) IDS_2121, (wchar_t *) IDS_2122, (wchar_t *) IDS_2123); + + hwndMain = h; if (i == 1) return(1); /* no */ - if (i < 0) return(0); /* cancel */ + if (i == -1) return(0); /* cancel */ return(2); /* yes */ } else @@ -422,7 +452,7 @@ win_settings_save(void) #ifdef USE_DYNAREC cpu_use_dynarec = temp_dynarec; #endif - enable_external_fpu = temp_fpu; + fpu_type = temp_fpu; time_sync = temp_sync; /* Video category */ @@ -460,6 +490,7 @@ win_settings_save(void) /* Peripherals category */ scsi_card_current = temp_scsi_card; hdc_current = temp_hdc; + fdc_type = temp_fdc_card; ide_ter_enabled = temp_ide_ter; ide_qua_enabled = temp_ide_qua; bugger_enabled = temp_bugger; @@ -507,6 +538,40 @@ win_settings_save(void) } +static void +win_settings_machine_recalc_fpu(HWND hdlg) +{ + HWND h; + int c, type; + LPTSTR lptsTemp; + const char *stransi; + + lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); + + h = GetDlgItem(hdlg, IDC_COMBO_FPU); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = 0; + while (1) { + stransi = (char *) fpu_get_name_from_index(temp_machine, temp_cpu_m, temp_cpu, c); + type = fpu_get_type_from_index(temp_machine, temp_cpu_m, temp_cpu, c); + if (!stransi) + break; + + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + if (!c || (type == temp_fpu)) + SendMessage(h, CB_SETCURSEL, c, 0); + + c++; + } + + if (c > 1) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); +} + + static void win_settings_machine_recalc_cpu(HWND hdlg) { @@ -539,15 +604,7 @@ win_settings_machine_recalc_cpu(HWND hdlg) EnableWindow(h, TRUE); #endif - h = GetDlgItem(hdlg, IDC_CHECK_FPU); - cpu_type = machines[temp_machine].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if (cpu_type < CPU_i486DX) - EnableWindow(h, TRUE); - else { - temp_fpu = 1; - EnableWindow(h, FALSE); - } - SendMessage(h, BM_SETCHECK, temp_fpu, 0); + win_settings_machine_recalc_fpu(hdlg); } @@ -644,7 +701,8 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h, h2; - int c, d; + int c, d, e, f; + int old_machine_type; LPTSTR lptsTemp; char *stransi; @@ -652,10 +710,35 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE_TYPE); + f = 0; + memset(machinetypetolist, 0x00, sizeof(machinetypetolist)); + memset(listtomachinetype, 0x00, sizeof(listtomachinetype)); + for (c = 1; c < MACHINE_TYPE_MAX; c++) { + d = e = 0; + while (machine_get_internal_name_ex(d) != NULL) { + if (machine_available(d) && (machines[d].type == c)) + e++; + d++; + } + + if (e > 0) { + stransi = (char *)machine_types[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + machinetypetolist[c] = f; + listtomachinetype[f] = c; + f++; + } + } + SendMessage(h, CB_SETCURSEL, machinetypetolist[temp_machine_type], 0); + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); c = d = 0; + memset(machinetolist, 0x00, sizeof(machinetolist)); + memset(listtomachine, 0x00, sizeof(listtomachine)); while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c)) { + if (machine_available(c) && (machines[c].type == temp_machine_type)) { stransi = (char *)machines[c].name; mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); @@ -713,6 +796,40 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_COMMAND: switch (LOWORD(wParam)) { + case IDC_COMBO_MACHINE_TYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) { + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE_TYPE); + old_machine_type = temp_machine_type; + temp_machine_type = listtomachinetype[SendMessage(h,CB_GETCURSEL,0,0)]; + + lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); + + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = d = 0; + memset(machinetolist, 0x00, sizeof(machinetolist)); + memset(listtomachine, 0x00, sizeof(listtomachine)); + while (machine_get_internal_name_ex(c) != NULL) { + if (machine_available(c) && (machines[c].type == temp_machine_type)) { + stransi = (char *)machines[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + machinetolist[c] = d; + listtomachine[d] = c; + d++; + } + c++; + } + if (old_machine_type == temp_machine_type) + SendMessage(h, CB_SETCURSEL, machinetolist[temp_machine], 0); + else { + SendMessage(h, CB_SETCURSEL, 0, 0); + temp_machine = listtomachine[0]; + + win_settings_machine_recalc_machine(hdlg); + } + } + break; case IDC_COMBO_MACHINE: if (HIWORD(wParam) == CBN_SELCHANGE) { h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); @@ -738,6 +855,12 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) win_settings_machine_recalc_cpu(hdlg); } break; + case IDC_COMBO_FPU: + if (HIWORD(wParam) == CBN_SELCHANGE) { + h = GetDlgItem(hdlg, IDC_COMBO_FPU); + temp_fpu = fpu_get_type_from_index(temp_machine, temp_cpu_m, temp_cpu, SendMessage(h, CB_GETCURSEL, 0, 0)); + } + break; case IDC_CONFIGURE_MACHINE: h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); temp_machine = listtomachine[SendMessage(h, CB_GETCURSEL, 0, 0)]; @@ -769,9 +892,6 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if(SendMessage(h, BM_GETCHECK, 0, 0)) temp_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC; - h=GetDlgItem(hdlg, IDC_CHECK_FPU); - temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_WS); temp_wait_states = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -1493,7 +1613,6 @@ win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) return FALSE; } - static void recalc_hdc_list(HWND hdlg) { @@ -1550,6 +1669,7 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa char *stransi; const device_t *scsi_dev; const device_t *dev; + const device_t *fdc_dev; char *s; switch (message) { @@ -1566,6 +1686,43 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa else EnableWindow(h, FALSE); + + /*FD controller config*/ + h = GetDlgItem(hdlg, IDC_COMBO_FDC); + c = d = 0; + while (1) { + char *s = fdc_card_getname(c); + + if (!s[0]) + break; + + settings_fdc_to_list[0][c] = d; + + if (fdc_card_available(c)) { + fdc_dev = fdc_card_getdevice(c); + + if (device_is_valid(fdc_dev, machines[temp_machine].flags)) { + if (c == 0) + SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2118)); + else { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_fdc[0][d] = c; + d++; + } + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_fdc_to_list[0][temp_fdc_card], 0); + + EnableWindow(h, d ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_FDC); + EnableWindow(h, fdc_card_has_config(temp_fdc_card) ? TRUE : FALSE); + + /*SCSI config*/ h = GetDlgItem(hdlg, IDC_COMBO_SCSI); c = d = 0; @@ -1685,6 +1842,24 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa case WM_COMMAND: switch (LOWORD(wParam)) { + case IDC_CONFIGURE_FDC: + h = GetDlgItem(hdlg, IDC_COMBO_FDC); + temp_fdc_card = settings_list_to_fdc[0][SendMessage(h, CB_GETCURSEL, 0, 0)]; + + temp_deviceconfig |= deviceconfig_open(hdlg, (void *)fdc_card_getdevice(temp_fdc_card)); + break; + + case IDC_COMBO_FDC: + h = GetDlgItem(hdlg, IDC_COMBO_FDC); + temp_fdc_card = settings_list_to_fdc[0][SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURE_FDC); + if (fdc_card_has_config(temp_fdc_card)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); + break; + case IDC_CONFIGURE_HDC: lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR)); stransi = (char *) malloc(512); @@ -1812,6 +1987,9 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa wcstombs(stransi, lptsTemp, 512); temp_hdc = hdc_get_id(stransi); + h = GetDlgItem(hdlg, IDC_COMBO_FDC); + temp_fdc_card = settings_list_to_fdc[0][SendMessage(h, CB_GETCURSEL, 0, 0)]; + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); temp_scsi_card = settings_list_to_device[0][SendMessage(h, CB_GETCURSEL, 0, 0)]; @@ -2707,7 +2885,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM /* Make sure no file name is allowed with removable SCSI hard disks. */ if (wcslen(hd_file_name) == 0) { hdd_ptr->bus = HDD_BUS_DISABLED; - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4112); + settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2130, (wchar_t *) IDS_4112); return TRUE; } @@ -2751,14 +2929,14 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM if (size > 0x1FFFFFFE00ll) { fclose(f); - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4105); + settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4105); return TRUE; } if (image_is_hdi(hd_file_name)) { if (size >= 0x100000000ll) { fclose(f); - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4104); + settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4104); return TRUE; } @@ -2853,7 +3031,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM free(big_buf); fclose(f); - settings_msgbox(MBX_INFO, (wchar_t *)IDS_4113); + settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117); } hard_disk_added = 1; @@ -2882,7 +3060,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM f = _wfopen(wopenfilestring, L"rb"); if (f != NULL) { fclose(f); - if (settings_msgbox(MBX_QUESTION, (wchar_t *)IDS_4111) != 0) /* yes */ + if (settings_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) /* yes */ return FALSE; } } @@ -2891,7 +3069,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM if (f == NULL) { hdd_add_file_open_error: fclose(f); - settings_msgbox(MBX_ERROR, (existing & 1) ? (wchar_t *)IDS_4107 : (wchar_t *)IDS_4108); + settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108); return TRUE; } if (existing & 1) { @@ -2899,7 +3077,7 @@ hdd_add_file_open_error: fseeko64(f, 0x10, SEEK_SET); fread(§or_size, 1, 4, f); if (sector_size != 512) { - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4109); + settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4119, (wchar_t *) IDS_4109); fclose(f); return TRUE; } @@ -3171,7 +3349,7 @@ hdd_add_file_open_error: case HDD_BUS_MFM: max_spt = 26; /* 17 for MFM, 26 for RLL. */ max_hpc = 15; - max_tracks = 1023; + max_tracks = 2047; break; case HDD_BUS_XTA: max_spt = 63; diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 1dfc57527..b2f01e215 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -312,7 +312,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_ACTION_HRESET: win_notify_dlg_open(); - i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2112); + i = ui_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_2112, NULL, (wchar_t *) IDS_2137, (wchar_t *) IDS_2138, NULL); if (i == 0) pc_reset_hard(); win_notify_dlg_closed(); @@ -327,7 +327,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (no_quit_confirm) i = 0; else - i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2113); + i = ui_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2119, (wchar_t *) IDS_2136, NULL); if (i == 0) { UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); @@ -695,7 +695,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (no_quit_confirm) i = 0; else - i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2113); + i = ui_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2119, (wchar_t *) IDS_2136, NULL); if (i == 0) { UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); @@ -731,7 +731,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (manager_wm) break; win_notify_dlg_open(); - i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2112); + i = ui_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_2112, NULL, (wchar_t *) IDS_2137, (wchar_t *) IDS_2138, NULL); if (i == 0) pc_reset_hard(); win_notify_dlg_closed(); @@ -744,7 +744,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (no_quit_confirm) i = 0; else - i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2113); + i = ui_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_2113, NULL, (wchar_t *) IDS_2119, (wchar_t *) IDS_2136, NULL); if (i == 0) { UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); @@ -819,6 +819,20 @@ SubWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } +static HRESULT CALLBACK +TaskDialogProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData) +{ + switch (message) { + case TDN_HYPERLINK_CLICKED: + /* open linked URL */ + ShellExecute(hwnd, L"open", (LPCWSTR) lParam, NULL, NULL, SW_SHOW); + break; + } + + return S_OK; +} + + int ui_init(int nCmdShow) { @@ -826,18 +840,31 @@ ui_init(int nCmdShow) WNDCLASSEX wincl; /* buffer for main window's class */ RAWINPUTDEVICE ridev; /* RawInput device */ MSG messages; /* received-messages buffer */ - HWND hwnd = NULL; /* handle for our window */ + HWND hwnd = NULL; /* handle for our window */ HACCEL haccel; /* handle to accelerator table */ - RECT sbar_rect; /* RECT of the status bar */ + RECT sbar_rect; /* RECT of the status bar */ int bRet; + TASKDIALOGCONFIG tdconfig = {0}; + TASKDIALOG_BUTTON tdbuttons[] = {{IDCANCEL, MAKEINTRESOURCE(IDS_2119)}}; + /* Set up TaskDialog configuration. */ + tdconfig.cbSize = sizeof(tdconfig); + tdconfig.dwFlags = TDF_ENABLE_HYPERLINKS; + tdconfig.dwCommonButtons = 0; + tdconfig.pszWindowTitle = MAKEINTRESOURCE(IDS_STRINGS); + tdconfig.pszMainIcon = TD_ERROR_ICON; + tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2050); + tdconfig.cButtons = ARRAYSIZE(tdbuttons); + tdconfig.pButtons = tdbuttons; + tdconfig.pfCallback = TaskDialogProcedure; + + /* Start settings-only mode if requested. */ if (settings_only) { if (! pc_init_modules()) { /* Dang, no ROMs found at all! */ - MessageBox(hwnd, - plat_get_string(IDS_2056), - plat_get_string(IDS_2050), - MB_OK | MB_ICONERROR); + tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2120); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); + TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return(6); } @@ -895,7 +922,7 @@ ui_init(int nCmdShow) menuMain, /* menu */ hinstance, /* Program Instance handler */ NULL); /* no Window Creation data */ - hwndMain = hwnd; + hwndMain = tdconfig.hwndParent = hwnd; ui_window_title(title); @@ -925,10 +952,8 @@ ui_init(int nCmdShow) ridev.dwFlags = RIDEV_NOHOTKEYS; ridev.hwndTarget = NULL; /* current focus window */ if (! RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) { - MessageBox(hwndMain, - plat_get_string(IDS_2105), - plat_get_string(IDS_2050), - MB_OK | MB_ICONERROR); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2105); + TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return(4); } keyboard_getkeymap(); @@ -939,10 +964,8 @@ ui_init(int nCmdShow) /* Load the accelerator table */ haccel = LoadAccelerators(hinstance, ACCEL_NAME); if (haccel == NULL) { - MessageBox(hwndMain, - plat_get_string(IDS_2104), - plat_get_string(IDS_2050), - MB_OK | MB_ICONERROR); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2104); + TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return(3); } @@ -972,19 +995,16 @@ ui_init(int nCmdShow) /* All done, fire up the actual emulated machine. */ if (! pc_init_modules()) { /* Dang, no ROMs found at all! */ - MessageBox(hwnd, - plat_get_string(IDS_2056), - plat_get_string(IDS_2050), - MB_OK | MB_ICONERROR); + tdconfig.pszMainInstruction = MAKEINTRESOURCE(IDS_2120); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2056); + TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return(6); } /* Initialize the configured Video API. */ if (! plat_setvid(vid_api)) { - MessageBox(hwnd, - plat_get_string(IDS_2089), - plat_get_string(IDS_2050), - MB_OK | MB_ICONERROR); + tdconfig.pszContent = MAKEINTRESOURCE(IDS_2089); + TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); return(5); }