From ad44c454c99a4f31aff04740b47be0e7c64fee35 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 30 Apr 2023 21:52:58 +0200 Subject: [PATCH 01/10] Re-added the IBM PS/2 model 70 type 4 (Softfloat is always used in this machine). --- src/include/86box/machine.h | 1 + src/machine/m_ps2_mca.c | 21 +++++++++++++++++++ src/machine/machine_table.c | 42 +++++++++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4d1effe9a..4477c4781 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -770,6 +770,7 @@ extern int machine_ps2_model_65sx_init(const machine_t *); extern int machine_ps2_model_70_type3_init(const machine_t *); extern int machine_ps2_model_80_init(const machine_t *); extern int machine_ps2_model_80_axx_init(const machine_t *); +extern int machine_ps2_model_70_type4_init(const machine_t *); /* m_tandy.c */ extern int tandy1k_eeprom_read(void); diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 328de216b..d867ddb24 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -1495,3 +1495,24 @@ machine_ps2_model_80_axx_init(const machine_t *model) return ret; } + +int +machine_ps2_model_70_type4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/ibmps2_m70_type4/64F3126.BIN", + "roms/machines/ibmps2_m70_type4/64F3125.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_ps2_common_init(model); + + ps2.planar_id = 0xf9ff; + + ps2_mca_board_model_70_type34_init(1, 4); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 244af7623..f089fe93e 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5470,7 +5470,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[MCA] IBM PS/2 model 70 (type 4)", + .internal_name = "ibmps2_m70_type4", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_model_70_type4_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO, + .ram = { + .min = 2048, + .max = 65536, + .step = 2048 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 486 machines - Socket 2 */ /* 486 machines with just the ISA slot */ /* Uses some variant of Phoenix MultiKey/42 as the BIOS sends keyboard controller @@ -12517,7 +12555,7 @@ const machine_t machines[] = { .min_voltage = 1300, .max_voltage = 3500, .min_multi = 1.5, - .max_multi = 8.0 /* limits assumed */ + .max_multi = 8.0 /* limits assumed */ }, .bus_flags = MACHINE_PS2_AGP, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, From ea5b9cdbf887766a29663ceae20b72b4d0206a0d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 May 2023 16:55:49 +0600 Subject: [PATCH 02/10] usb: Port reset logic is now on a timer --- src/include/86box/usb.h | 2 ++ src/usb.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/include/86box/usb.h b/src/include/86box/usb.h index 987eb1314..a20f1b2a2 100644 --- a/src/include/86box/usb.h +++ b/src/include/86box/usb.h @@ -39,6 +39,8 @@ typedef struct usb_t int uhci_enable, ohci_enable; uint32_t ohci_mem_base; mem_mapping_t ohci_mmio_mapping; + pc_timer_t ohci_frame_timer; + pc_timer_t ohci_port_reset_timer[2]; usb_params_t* usb_params; } usb_t; diff --git a/src/usb.c b/src/usb.c index ca8ee1d38..8ac16edd1 100644 --- a/src/usb.c +++ b/src/usb.c @@ -26,8 +26,8 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/mem.h> +#include <86box/timer.h> #include <86box/usb.h> -#include "cpu.h" #ifdef ENABLE_USB_LOG int usb_do_log = ENABLE_USB_LOG; @@ -189,6 +189,28 @@ ohci_mmio_read(uint32_t addr, void *p) return ret; } +void +ohci_update_frame_counter(void* priv) +{ + usb_t *dev = (usb_t *) priv; +} + +void +ohci_port_reset_callback(void* priv) +{ + usb_t *dev = (usb_t *) priv; + + dev->ohci_mmio[OHCI_HcRhPortStatus1] &= ~0x10; +} + +void +ohci_port_reset_callback_2(void* priv) +{ + usb_t *dev = (usb_t *) priv; + + dev->ohci_mmio[OHCI_HcRhPortStatus2] &= ~0x10; +} + static void ohci_mmio_write(uint32_t addr, uint8_t val, void *p) { @@ -331,8 +353,7 @@ ohci_mmio_write(uint32_t addr, uint8_t val, void *p) if (val & 0x10) { if (old & 0x01) { dev->ohci_mmio[addr] |= 0x10; - /* TODO: The clear should be on a 10 ms timer. */ - dev->ohci_mmio[addr] &= ~0x10; + timer_on_auto(&dev->ohci_port_reset_timer[(addr - OHCI_HcRhPortStatus1) / 4], 10000.); dev->ohci_mmio[addr + 2] |= 0x10; } else dev->ohci_mmio[addr + 2] |= 0x01; @@ -388,7 +409,6 @@ ohci_mmio_write(uint32_t addr, uint8_t val, void *p) dev->ohci_mmio[addr] = val; } - void ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, int enable) { @@ -447,6 +467,9 @@ usb_init_ext(const device_t *info, void* params) ohci_mmio_read, NULL, NULL, ohci_mmio_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, dev); + timer_add(&dev->ohci_frame_timer, ohci_update_frame_counter, dev, 0); /* Unused for now, to be used for frame counting. */ + timer_add(&dev->ohci_port_reset_timer[0], ohci_port_reset_callback, dev, 0); + timer_add(&dev->ohci_port_reset_timer[1], ohci_port_reset_callback_2, dev, 0); usb_reset(dev); return dev; From c289872cd63e9b9ad7d879a019d34e7ead9dc9f6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 May 2023 16:19:02 +0200 Subject: [PATCH 03/10] Allow 8 MB VRAM on the Number Nine 771 since it turns out it correctly supports that much. --- src/video/vid_s3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 68b84d9db..346de2ebb 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -8928,7 +8928,7 @@ const device_t s3_9fx_771_pci_device = { { .available = s3_9fx_771_available }, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, - .config = s3_standard_config + .config = s3_968_config }; const device_t s3_phoenix_vision968_pci_device = { From 927c26f496450e68fbb29cbdf0740f6d7add8845 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 2 May 2023 02:18:17 -0400 Subject: [PATCH 04/10] Fix some variant type comparisons --- src/cpu/808x.c | 4 ++-- src/floppy/fdd_86f.c | 12 ++++++------ src/sound/snd_adlibgold.c | 3 +-- src/sound/snd_audiopci.c | 3 +-- src/sound/snd_gus.c | 3 +-- src/sound/snd_sb_dsp.c | 5 ++--- src/video/vid_ht216.c | 2 +- 7 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index d7e50b0b5..925594a11 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -440,10 +440,10 @@ pfq_write(void) static uint8_t pfq_read(void) { - uint8_t temp, i; + uint8_t temp; temp = pfq[0]; - for (i = 0; i < (pfq_size - 1); i++) + for (int i = 0; i < (pfq_size - 1); i++) pfq[i] = pfq[i + 1]; pfq_pos--; cpu_state.pc = (cpu_state.pc + 1) & 0xffff; diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 0267cfe81..ff4acb989 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -2550,7 +2550,7 @@ uint16_t d86f_prepare_pretrack(int drive, int side, int iso) { d86f_t *dev = d86f[drive]; - uint16_t i, pos; + uint16_t pos; int mfm; int real_gap0_len; int sync_len; @@ -2575,22 +2575,22 @@ d86f_prepare_pretrack(int drive, int side, int iso) d86f_destroy_linked_lists(drive, side); - for (i = 0; i < raw_size; i++) + for (uint32_t i = 0; i < raw_size; i++) d86f_write_direct_common(drive, side, gap_fill, 0, i); pos = 0; if (!iso) { - for (i = 0; i < real_gap0_len; i++) { + for (int i = 0; i < real_gap0_len; i++) { d86f_write_direct_common(drive, side, gap_fill, 0, pos); pos = (pos + 1) % raw_size; } - for (i = 0; i < sync_len; i++) { + for (int i = 0; i < sync_len; i++) { d86f_write_direct_common(drive, side, 0, 0, pos); pos = (pos + 1) % raw_size; } if (mfm) { - for (i = 0; i < 3; i++) { + for (uint8_t i = 0; i < 3; i++) { d86f_write_direct_common(drive, side, 0x2452, 1, pos); pos = (pos + 1) % raw_size; } @@ -2600,7 +2600,7 @@ d86f_prepare_pretrack(int drive, int side, int iso) pos = (pos + 1) % raw_size; } - for (i = 0; i < real_gap1_len; i++) { + for (int i = 0; i < real_gap1_len; i++) { d86f_write_direct_common(drive, side, gap_fill, 0, pos); pos = (pos + 1) % raw_size; } diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 0616e8fa6..5c95194a3 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -842,7 +842,6 @@ static void adgold_input_msg(void *p, uint8_t *msg, uint32_t len) { adgold_t *adgold = (adgold_t *) p; - uint8_t i; if (adgold->sysex) return; @@ -850,7 +849,7 @@ adgold_input_msg(void *p, uint8_t *msg, uint32_t len) if (adgold->uart_in) { adgold->adgold_mma_status |= 0x04; - for (i = 0; i < len; i++) { + for (uint32_t i = 0; i < len; i++) { adgold->midi_queue[adgold->midi_w++] = msg[i]; adgold->midi_w &= 0x0f; } diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 105907ede..47812d84a 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -1969,9 +1969,8 @@ static void es1371_input_msg(void *p, uint8_t *msg, uint32_t len) { es1371_t *dev = (es1371_t *) p; - uint8_t i; - for (i = 0; i < len; i++) + for (uint32_t i = 0; i < len; i++) es1371_write_fifo(dev, msg[i]); } diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 2bef7edac..1557f97ba 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -1085,7 +1085,6 @@ static void gus_input_msg(void *p, uint8_t *msg, uint32_t len) { gus_t *gus = (gus_t *) p; - uint8_t i; if (gus->sysex) return; @@ -1093,7 +1092,7 @@ gus_input_msg(void *p, uint8_t *msg, uint32_t len) if (gus->uart_in) { gus->midi_status |= MIDI_INT_RECEIVE; - for (i = 0; i < len; i++) { + for (uint32_t i = 0; i < len; i++) { gus->midi_queue[gus->midi_w++] = msg[i]; gus->midi_w &= 63; } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index e6a7b8312..e340c1482 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -1055,7 +1055,6 @@ void sb_dsp_input_msg(void *p, uint8_t *msg, uint32_t len) { sb_dsp_t *dsp = (sb_dsp_t *) p; - uint8_t i = 0; sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, len); @@ -1068,11 +1067,11 @@ sb_dsp_input_msg(void *p, uint8_t *msg, uint32_t len) return; if (dsp->uart_irq) { - for (i = 0; i < len; i++) + for (uint32_t i = 0; i < len; i++) sb_add_data(dsp, msg[i]); sb_irq(dsp, 1); } else if (dsp->midi_in_poll) { - for (i = 0; i < len; i++) + for (uint32_t i = 0; i < len; i++) sb_add_data(dsp, msg[i]); } } diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 255a9e8b8..91c542164 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -1347,7 +1347,7 @@ ht216_read_common(ht216_t *ht216, uint32_t addr) temp = 0xff; for (pixel = 0; pixel < 8; pixel++) { - for (plane = 0; plane < (1 << count); plane++) { + for (plane = 0; plane < (uint8_t)(1 << count); plane++) { if (svga->colournocare & (1 << plane)) { /* If we care about a plane, and the pixel has a mismatch on it, clear its bit. */ if (((svga->latch.b[plane] >> pixel) & 1) != ((svga->colourcompare >> plane) & 1)) From 7ebdd1c74be6a2099d0748238a8f3e9d419a44d7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 May 2023 15:18:05 +0200 Subject: [PATCH 05/10] Re-added the 32-bit address variants of FXTRACT, should fix OpenStep again. --- src/cpu/x87_ops.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 742ed3e5d..e321df959 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -851,8 +851,8 @@ const OpFn OP_TABLE(fpu_8087_d9)[256] = { ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/ opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16 + opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16 // clang-format on }; @@ -2414,7 +2414,7 @@ const OpFn OP_TABLE(fpu_287_d9_a32)[256] = { ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, /*Invalid*/ opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS // clang-format on }; @@ -2494,7 +2494,7 @@ const OpFn OP_TABLE(fpu_d9_a32)[256] = { opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS // clang-format on }; From 5f384427fc4d21e698176149d9c2496f2e48b620 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 May 2023 15:20:15 +0200 Subject: [PATCH 06/10] A small warning fix to shut up the compiler. --- src/cpu/x87_ops_sf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x87_ops_sf.h b/src/cpu/x87_ops_sf.h index 4de3b1c90..ad12b6515 100644 --- a/src/cpu/x87_ops_sf.h +++ b/src/cpu/x87_ops_sf.h @@ -2,7 +2,7 @@ static uint32_t fpu_save_environment(void) { int tag; - unsigned offset; + unsigned offset = 0; /* read all registers in stack order and update x87 tag word */ for (int n = 0; n < 8; n++) { From 10bf8884b87d40f79b63f4e18a119f4b74ef921d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 May 2023 15:22:30 +0200 Subject: [PATCH 07/10] And another such warning (how is GCC unaware that it has literally evaluated every possible case?!). --- src/cpu/x87_ops_sf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x87_ops_sf.h b/src/cpu/x87_ops_sf.h index ad12b6515..e70556fea 100644 --- a/src/cpu/x87_ops_sf.h +++ b/src/cpu/x87_ops_sf.h @@ -109,7 +109,7 @@ fpu_save_environment(void) static uint32_t fpu_load_environment(void) { - unsigned offset; + unsigned offset = 0; switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { case 0x000: { /*16-bit real mode*/ From 5a342c0a8046ccff8852b86ba62e8fce257290c5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 May 2023 15:23:27 +0200 Subject: [PATCH 08/10] Two unused variables. --- src/cpu/x87_ops_sf_load_store.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cpu/x87_ops_sf_load_store.h b/src/cpu/x87_ops_sf_load_store.h index c6dab1b44..69bc5598c 100644 --- a/src/cpu/x87_ops_sf_load_store.h +++ b/src/cpu/x87_ops_sf_load_store.h @@ -768,7 +768,6 @@ sf_FBSTP_PACKED_BCD_a16(uint32_t fetchdat) floatx80 reg; int64_t save_val; int sign; - int c; FP_ENTER(); FPU_check_pending_exceptions(); @@ -833,7 +832,6 @@ sf_FBSTP_PACKED_BCD_a32(uint32_t fetchdat) floatx80 reg; int64_t save_val; int sign; - int c; FP_ENTER(); FPU_check_pending_exceptions(); From fcd1d3f354568c847dc688f8351299ad74ec1d79 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 May 2023 15:25:53 +0200 Subject: [PATCH 09/10] And another unused variable removed. Only the bitwise comparison warning is left now. --- src/cpu/x87_ops_sf_trans.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cpu/x87_ops_sf_trans.h b/src/cpu/x87_ops_sf_trans.h index 7ecbbe4ec..5289b2bbf 100644 --- a/src/cpu/x87_ops_sf_trans.h +++ b/src/cpu/x87_ops_sf_trans.h @@ -131,7 +131,6 @@ next_ins: static int sf_FXTRACT(uint32_t fetchdat) { - const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction); struct float_status_t status; floatx80 a, b; From 18f96d28231c64a24111cd51832f9b39d5de42a4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 May 2023 15:27:20 +0200 Subject: [PATCH 10/10] And that's the last softfloat warning fixed. --- src/cpu/x87_ops_sf_const.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x87_ops_sf_const.h b/src/cpu/x87_ops_sf_const.h index 5e722ede4..708c6ff7a 100644 --- a/src/cpu/x87_ops_sf_const.h +++ b/src/cpu/x87_ops_sf_const.h @@ -21,7 +21,7 @@ sf_FLDL2T(uint32_t fetchdat) FPU_stack_overflow(fetchdat); else { FPU_push(); - FPU_save_regi(FPU_round_const(Const_L2T, (fpu_state.cwd & FPU_CW_RC) == X87_ROUNDING_UP), 0); + FPU_save_regi(FPU_round_const(Const_L2T, (fpu_state.cwd & FPU_CW_RC) == FPU_RC_UP), 0); } CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi));