diff --git a/src/acpi.c b/src/acpi.c index d8555cb95..a1eb5f260 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -125,6 +125,8 @@ 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; + if (cpu_use_dynarec) + update_tsc(); break; case 0x0c: case 0x0d: /* GPSTS - General Purpose Status Register (IO) */ @@ -211,6 +213,8 @@ 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; + if (cpu_use_dynarec) + update_tsc(); break; case 0x10: case 0x11: case 0x12: case 0x13: /* PCNTRL - Processor Control Register (IO) */ diff --git a/src/chipset/via_vpx.c b/src/chipset/via_vpx.c index 5985f8493..c9798e319 100644 --- a/src/chipset/via_vpx.c +++ b/src/chipset/via_vpx.c @@ -1,22 +1,25 @@ /* - - 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. - - - -VIA Apollo VPX North Bridge emulation - -VT82C585VPX used in the Zida Tomato TX100 board -based on the model of VIA MVP3 by mooch & Sarah - -Authors: Sarah Walker, -Copyright(C) 2020 Tiseno100 -Copyright(C) 2020 Melissa Goad -Copyright(C) 2020 Miran Grca - +* +* 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. +* +* +* +* VIA Apollo VPX North Bridge emulation +* +* VT82C585VPX used in the FIC VA-502 board +* based on the model of VIA MVP3 by mooch & Sarah +* +* There's also a SOYO board using the ETEQ chipset which is a rebranded +* VPX + 586B but fails to save on CMOS properly. +* +* Authors: Sarah Walker, +* Copyright(C) 2020 Tiseno100 +* Copyright(C) 2020 Melissa Goad +* Copyright(C) 2020 Miran Grca +* */ #include @@ -35,7 +38,7 @@ Copyright(C) 2020 Miran Grca typedef struct via_vpx_t { - uint8_t pci_conf[2][256]; + uint8_t pci_conf[256]; } via_vpx_t; static void @@ -60,109 +63,73 @@ vpx_map(uint32_t addr, uint32_t size, int state) } static void -via_vpx_pci_regs(via_vpx_t *dev) -{ - memset(dev, 0, sizeof(via_vpx_t)); - -// Host Bridge registers - - dev->pci_conf[0][0x00] = 0x06; // VIA - dev->pci_conf[0][0x01] = 0x11; - - dev->pci_conf[0][0x02] = 0x85; // VT82C585VPX - dev->pci_conf[0][0x03] = 0x05; - - dev->pci_conf[0][0x04] = 7; // Command - dev->pci_conf[0][0x05] = 0; - - dev->pci_conf[0][0x06] = 0xa0; // Status - dev->pci_conf[0][0x07] = 2; - - dev->pci_conf[0][0x09] = 0; // Program Interface - - dev->pci_conf[0][0x0a] = 0; // Sub Class Code - - dev->pci_conf[0][0x0b] = 6; // Base Class Code - - dev->pci_conf[0][0x0c] = 0; // reserved - - dev->pci_conf[0][0x0d] = 0; // Latency Timer - - dev->pci_conf[0][0x0e] = 0; // Header Type - - dev->pci_conf[0][0x0f] = 0; // Built-in Self test - - dev->pci_conf[0][0x58] = 0x40; // DRAM Configuration 1 - dev->pci_conf[0][0x59] = 5; // DRAM Configuration 2 - - dev->pci_conf[0][0x5a] = 1; // Bank 0 Ending - dev->pci_conf[0][0x5b] = 1; // Bank 1 Ending - dev->pci_conf[0][0x5c] = 1; // Bank 2 Ending - dev->pci_conf[0][0x5d] = 1; // Bank 3 Ending - dev->pci_conf[0][0x5e] = 1; // Bank 4 Ending - dev->pci_conf[0][0x5f] = 1; // Bank 5 Ending - - dev->pci_conf[0][0x64] = 0xab; // DRAM reference timing - -} - -static void -host_bridge_write(int func, int addr, uint8_t val, void *priv) +via_vpx_write(int func, int addr, uint8_t val, void *priv) { via_vpx_t *dev = (via_vpx_t *) priv; - // Read-Only registers. Exact same as MVP3 - if ((addr < 4) || ((addr >= 5) && (addr < 7)) || ((addr >= 8) && (addr < 0xd)) || ((addr >= 0xe) && (addr < 0x12)) || - ((addr >= 0x14) && (addr < 0x50)) || ((addr >= 0x79) && (addr < 0x7e)) || ((addr >= 0x85) && (addr < 0x88)) || - ((addr >= 0x8c) && (addr < 0xa8)) || ((addr >= 0xad) && (addr < 0xfd))) - return; + // Read-Only registers + switch(addr){ + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0e: case 0x0f: + return; + } switch(addr){ - case 0x04: // Command - dev->pci_conf[0][0x04] = (dev->pci_conf[0][0x04] & ~0x40) | (val & 0x40); + case 0x04: + // Bitfield 6: Parity Error Response + // Bitfield 8: SERR# Enable + // Bitfield 9: Fast Back-to-Back Cycle Enable + if(dev->pci_conf[0x04] && 0x40){ //Bitfield 6 + dev->pci_conf[0x04] = (dev->pci_conf[0x04] & ~0x40) | (val & 0x40); + } else if(dev->pci_conf[0x04] && 0x100){ //Bitfield 8 + dev->pci_conf[0x04] = (dev->pci_conf[0x04] & ~0x100) | (val & 0x100); + } else if(dev->pci_conf[0x04] && 0x200){ //Bitfield 9 + dev->pci_conf[0x04] = (dev->pci_conf[0x04] & ~0x200) | (val & 0x200); + } + break; case 0x07: // Status - dev->pci_conf[0][0x07] &= ~(val & 0xb0); + dev->pci_conf[0x07] &= ~(val & 0xb0); break; case 0x61: // Shadow RAM control 1 - if ((dev->pci_conf[0][0x61] ^ val) & 0x03) + if ((dev->pci_conf[0x61] ^ val) & 0x03) vpx_map(0xc0000, 0x04000, val & 0x03); - if ((dev->pci_conf[0][0x61] ^ val) & 0x0c) + if ((dev->pci_conf[0x61] ^ val) & 0x0c) vpx_map(0xc4000, 0x04000, (val & 0x0c) >> 2); - if ((dev->pci_conf[0][0x61] ^ val) & 0x30) + if ((dev->pci_conf[0x61] ^ val) & 0x30) vpx_map(0xc8000, 0x04000, (val & 0x30) >> 4); - if ((dev->pci_conf[0][0x61] ^ val) & 0xc0) + if ((dev->pci_conf[0x61] ^ val) & 0xc0) vpx_map(0xcc000, 0x04000, (val & 0xc0) >> 6); - dev->pci_conf[0][0x61] = val; + dev->pci_conf[0x61] = val; return; case 0x62: // Shadow RAM Control 2 - if ((dev->pci_conf[0][0x62] ^ val) & 0x03) + if ((dev->pci_conf[0x62] ^ val) & 0x03) vpx_map(0xd0000, 0x04000, val & 0x03); - if ((dev->pci_conf[0][0x62] ^ val) & 0x0c) + if ((dev->pci_conf[0x62] ^ val) & 0x0c) vpx_map(0xd4000, 0x04000, (val & 0x0c) >> 2); - if ((dev->pci_conf[0][0x62] ^ val) & 0x30) + if ((dev->pci_conf[0x62] ^ val) & 0x30) vpx_map(0xd8000, 0x04000, (val & 0x30) >> 4); - if ((dev->pci_conf[0][0x62] ^ val) & 0xc0) + if ((dev->pci_conf[0x62] ^ val) & 0xc0) vpx_map(0xdc000, 0x04000, (val & 0xc0) >> 6); - dev->pci_conf[0][0x62] = val; + dev->pci_conf[0x62] = val; return; case 0x63: // Shadow RAM Control 3 - if ((dev->pci_conf[0][0x63] ^ val) & 0x30) { + if ((dev->pci_conf[0x63] ^ val) & 0x30) { vpx_map(0xf0000, 0x10000, (val & 0x30) >> 4); shadowbios = (((val & 0x30) >> 4) & 0x02); } - if ((dev->pci_conf[0][0x63] ^ val) & 0xc0) + if ((dev->pci_conf[0x63] ^ val) & 0xc0) vpx_map(0xe0000, 0x10000, (val & 0xc0) >> 6); - dev->pci_conf[0][0x63] = val; + dev->pci_conf[0x63] = val; return; - //In case we throw somewhere default: - dev->pci_conf[0][addr] = val; + dev->pci_conf[addr] = val; break; } } @@ -175,19 +142,13 @@ via_vpx_read(int func, int addr, void *priv) switch(func) { case 0: - ret = dev->pci_conf[0][addr]; + ret = dev->pci_conf[addr]; break; } return ret; } -static void -via_vpx_write(int func, int addr, uint8_t val, void *priv) -{ - host_bridge_write(func, addr, val, priv); -} - static void via_vpx_reset(void *priv) { @@ -198,10 +159,49 @@ static void * via_vpx_init(const device_t *info) { via_vpx_t *dev = (via_vpx_t *) malloc(sizeof(via_vpx_t)); + memset(dev, 0, sizeof(via_vpx_t)); pci_add_card(PCI_ADD_NORTHBRIDGE, via_vpx_read, via_vpx_write, dev); - via_vpx_pci_regs(dev); + dev->pci_conf[0x00] = 0x06; // VIA + dev->pci_conf[0x01] = 0x11; + + dev->pci_conf[0x02] = 0x85; // VT82C585VPX + dev->pci_conf[0x03] = 0x05; + + dev->pci_conf[0x04] = 7; // Command + dev->pci_conf[0x05] = 0; + + dev->pci_conf[0x06] = 0xa0; // Status + dev->pci_conf[0x07] = 2; + + dev->pci_conf[0x08] = 0; // Silicon Rev. + + dev->pci_conf[0x09] = 0; // Program Interface + + dev->pci_conf[0x0a] = 0; // Sub Class Code + + dev->pci_conf[0x0b] = 6; // Base Class Code + + dev->pci_conf[0x0c] = 0; // reserved + + dev->pci_conf[0x0d] = 0; // Latency Timer + + dev->pci_conf[0x0e] = 0; // Header Type + + dev->pci_conf[0x0f] = 0; // Built-in Self test + + dev->pci_conf[0x58] = 0x40; // DRAM Configuration 1 + dev->pci_conf[0x59] = 0x05; // DRAM Configuration 2 + + dev->pci_conf[0x5a] = 1; // Bank 0 Ending + dev->pci_conf[0x5b] = 1; // Bank 1 Ending + dev->pci_conf[0x5c] = 1; // Bank 2 Ending + dev->pci_conf[0x5d] = 1; // Bank 3 Ending + dev->pci_conf[0x5e] = 1; // Bank 4 Ending + dev->pci_conf[0x5f] = 1; // Bank 5 Ending + + dev->pci_conf[0x64] = 0xab; // DRAM reference timing return dev; } diff --git a/src/cpu/codegen_ops.h b/src/cpu/codegen_ops.h index 53f5b34d2..fe54cb9a4 100644 --- a/src/cpu/codegen_ops.h +++ b/src/cpu/codegen_ops.h @@ -15,8 +15,8 @@ extern RecompOpFn recomp_opcodes_dc[512]; extern RecompOpFn recomp_opcodes_dd[512]; extern RecompOpFn recomp_opcodes_de[512]; extern RecompOpFn recomp_opcodes_df[512]; -RecompOpFn recomp_opcodes_REPE[512]; -RecompOpFn recomp_opcodes_REPNE[512]; +extern RecompOpFn recomp_opcodes_REPE[512]; +extern RecompOpFn recomp_opcodes_REPNE[512]; #define REG_EAX 0 #define REG_ECX 1 diff --git a/src/cpu/codegen_timing_p6.c b/src/cpu/codegen_timing_p6.c index ec5c54640..a69f68f04 100644 --- a/src/cpu/codegen_timing_p6.c +++ b/src/cpu/codegen_timing_p6.c @@ -19,8 +19,8 @@ typedef enum uop_type_t { - UOP_ALU = 0, /*Executes in Integer X or Y units*/ - UOP_ALUX, /*Executes in Integer X unit*/ + 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*/ @@ -31,11 +31,11 @@ typedef enum uop_type_t 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 Integer X or Y units as MMX*/ - UOP_MMX_SHIFT, /*Executes in Integer Y unit. Uses MMX shifter*/ - UOP_MMX_MUL, /*Executes in Integer X unit. Uses MMX multiplier*/ + 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_LIMM /*Does not require an execution unit*/ + UOP_FXCH /*Does not require an execution unit*/ } uop_type_t; typedef enum decode_type_t @@ -46,46 +46,46 @@ typedef enum decode_type_t #define MAX_UOPS 10 -typedef struct risc86_uop_t +typedef struct p6_uop_t { uop_type_t type; - double latency; -} risc86_uop_t; + int latency; +} p6_uop_t; -typedef struct risc86_instruction_t +typedef struct macro_op_t { int nr_uops; decode_type_t decode_type; - risc86_uop_t uop[MAX_UOPS]; -} risc86_instruction_t; + p6_uop_t uop[MAX_UOPS]; +} macro_op_t; -static const risc86_instruction_t alu_op = +static const macro_op_t alu_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t alux_op = +static const macro_op_t alup0_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1} + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t load_alu_op = +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 risc86_instruction_t load_alux_op = +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_ALUX, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t alu_store_op = +static const macro_op_t alu_store_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -94,38 +94,38 @@ static const risc86_instruction_t alu_store_op = .uop[2] = {.type = UOP_STORED, .latency = 1}, .uop[3] = {.type = UOP_STOREA, .latency = 1} }; -static const risc86_instruction_t alux_store_op = +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_ALUX, .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 risc86_instruction_t branch_op = +static const macro_op_t branch_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_BRANCH, .latency = 1} + .uop[0] = {.type = UOP_BRANCH, .latency = 2} }; -static const risc86_instruction_t limm_op = +static const macro_op_t fxch_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_LIMM, .latency = 1} + .uop[0] = {.type = UOP_FXCH, .latency = 1} }; -static const risc86_instruction_t load_op = +static const macro_op_t load_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, + .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_LOAD, .latency = 1} }; -static const risc86_instruction_t store_op = +static const macro_op_t store_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, @@ -134,14 +134,14 @@ static const risc86_instruction_t store_op = }; -static const risc86_instruction_t bswap_op = +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 risc86_instruction_t leave_op = +static const macro_op_t leave_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -149,27 +149,27 @@ static const risc86_instruction_t leave_op = .uop[1] = {.type = UOP_ALU, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t lods_op = +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 risc86_instruction_t loop_op = +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 = 1} + .uop[1] = {.type = UOP_BRANCH, .latency = 2} }; -static const risc86_instruction_t mov_reg_seg_op = +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 risc86_instruction_t movs_op = +static const macro_op_t movs_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -178,14 +178,14 @@ static const risc86_instruction_t movs_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t pop_reg_op = +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 risc86_instruction_t pop_mem_op = +static const macro_op_t pop_mem_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -194,14 +194,14 @@ static const risc86_instruction_t pop_mem_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t push_imm_op = +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 risc86_instruction_t push_mem_op = +static const macro_op_t push_mem_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -209,7 +209,7 @@ static const risc86_instruction_t push_mem_op = .uop[1] = {.type = UOP_STORED, .latency = 1}, .uop[2] = {.type = UOP_STOREA, .latency = 1} }; -static const risc86_instruction_t push_seg_op = +static const macro_op_t push_seg_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -218,7 +218,7 @@ static const risc86_instruction_t push_seg_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t stos_op = +static const macro_op_t stos_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -226,33 +226,33 @@ static const risc86_instruction_t stos_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t test_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALU, .latency = 1} -}; -static const risc86_instruction_t test_reg_b_op = +static const macro_op_t test_reg_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t test_mem_imm_op = +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 risc86_instruction_t test_mem_imm_b_op = +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_ALUX, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t xchg_op = +static const macro_op_t xchg_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -262,98 +262,98 @@ static const risc86_instruction_t xchg_op = }; -static const risc86_instruction_t mmx_op = +static const macro_op_t mmx_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX, .latency = 1.5} + .uop[0] = {.type = UOP_MMX, .latency = 1} }; -static const risc86_instruction_t mmx_mul_op = +static const macro_op_t mmx_mul_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_MUL, .latency = 1.5} + .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} }; -static const risc86_instruction_t mmx_shift_op = +static const macro_op_t mmx_shift_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_SHIFT, .latency = 1.5} + .uop[0] = {.type = UOP_MMX_SHIFT, .latency = 1} }; -static const risc86_instruction_t load_mmx_op = +static const macro_op_t load_mmx_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_MMX, .latency = 1.5} + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = {.type = UOP_MMX, .latency = 2} }; -static const risc86_instruction_t load_mmx_mul_op = +static const macro_op_t load_mmx_mul_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_MMX_MUL, .latency = 1.5} + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = {.type = UOP_MMX_MUL, .latency = 2} }; -static const risc86_instruction_t load_mmx_shift_op = +static const macro_op_t load_mmx_shift_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_MMX_SHIFT, .latency = 1.5} + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = {.type = UOP_MMX_SHIFT, .latency = 2} }; -static const risc86_instruction_t mload_op = +static const macro_op_t mload_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_MLOAD, .latency = 3}, + .uop[0] = {.type = UOP_MLOAD, .latency = 1}, }; -static const risc86_instruction_t mstore_op = +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 risc86_instruction_t pmul_op = +static const macro_op_t pmul_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_MUL, .latency = 1.5} + .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} }; -static const risc86_instruction_t pmul_mem_op = +static const macro_op_t pmul_mem_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_MMX_MUL, .latency = 1.5} + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = {.type = UOP_MMX_MUL, .latency = 2} }; -static const risc86_instruction_t float_op = +static const macro_op_t float_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_FLOAT, .latency = 1} }; -static const risc86_instruction_t fadd_op = +static const macro_op_t fadd_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 3} + .uop[0] = {.type = UOP_FLOAT, .latency = 2} }; -static const risc86_instruction_t fmul_op = +static const macro_op_t fmul_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALU, .latency = 5} + .uop[0] = {.type = UOP_ALUP0, .latency = 3} }; -static const risc86_instruction_t float2_op = +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 risc86_instruction_t fchs_op = +static const macro_op_t fchs_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -361,35 +361,35 @@ static const risc86_instruction_t fchs_op = .uop[1] = {.type = UOP_FLOAT, .latency = 2}, .uop[2] = {.type = UOP_FLOAT, .latency = 2} }; -static const risc86_instruction_t load_float_op = +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 risc86_instruction_t load_fadd_op = +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 = 3} + .uop[1] = {.type = UOP_FLOAT, .latency = 2} }; -static const risc86_instruction_t load_fmul_op = +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 = 5} + .uop[1] = {.type = UOP_ALU, .latency = 4} }; -static const risc86_instruction_t fstore_op = +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 risc86_instruction_t load_fiadd_op = +static const macro_op_t load_fiadd_op = { .nr_uops = 7, .decode_type = DECODE_COMPLEX, @@ -401,51 +401,51 @@ static const risc86_instruction_t load_fiadd_op = .uop[5] = {.type = UOP_FLOAT, .latency = 1}, .uop[6] = {.type = UOP_FLOAT, .latency = 1} }; -static const risc86_instruction_t fdiv_op = +static const macro_op_t fdiv_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 32} + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 37} }; -static const risc86_instruction_t fdiv_mem_op = +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 = 38} + .uop[1] = {.type = UOP_FLOAT, .latency = 37} }; -static const risc86_instruction_t fsin_op = +static const macro_op_t fsin_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 60} + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 62} }; -static const risc86_instruction_t fsqrt_op = +static const macro_op_t fsqrt_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, + .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_FLOAT, .latency = 69} }; -static const risc86_instruction_t complex_fldcw_op = +static const macro_op_t fldcw_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, + .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_FLOAT, .latency = 10} }; -static const risc86_instruction_t complex_float_op = +static const macro_op_t complex_float_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_FLOAT, .latency = 1} }; -static const risc86_instruction_t complex_float_l_op = +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 risc86_instruction_t complex_flde_op = +static const macro_op_t flde_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -453,7 +453,7 @@ static const risc86_instruction_t complex_flde_op = .uop[1] = {.type = UOP_FLOAD, .latency = 1}, .uop[2] = {.type = UOP_FLOAT, .latency = 2} }; -static const risc86_instruction_t complex_fste_op = +static const macro_op_t fste_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -462,20 +462,20 @@ static const risc86_instruction_t complex_fste_op = .uop[2] = {.type = UOP_FSTOREA, .latency = 1} }; -static const risc86_instruction_t complex_alu1_op = +static const macro_op_t complex_alu1_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_alu2_op = +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 risc86_instruction_t complex_alu3_op = +static const macro_op_t alu3_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -483,7 +483,7 @@ static const risc86_instruction_t complex_alu3_op = .uop[1] = {.type = UOP_ALU, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_alu6_op = +static const macro_op_t alu6_op = { .nr_uops = 6, .decode_type = DECODE_COMPLEX, @@ -494,57 +494,39 @@ static const risc86_instruction_t complex_alu6_op = .uop[4] = {.type = UOP_ALU, .latency = 1}, .uop[5] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_alux1_op = +static const macro_op_t complex_alup0_1_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_alux3_op = +static const macro_op_t alup0_3_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1}, + .uop[2] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_alux6_op = +static const macro_op_t alup0_6_op = { .nr_uops = 6, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .latency = 1}, - .uop[4] = {.type = UOP_ALUX, .latency = 1}, - .uop[5] = {.type = UOP_ALUX, .latency = 1} + .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 risc86_instruction_t complex_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 risc86_instruction_t complex_alux_store_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} -}; -static const risc86_instruction_t complex_arpl_op = +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 risc86_instruction_t complex_bound_op = +static const macro_op_t bound_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -553,13 +535,13 @@ static const risc86_instruction_t complex_bound_op = .uop[2] = {.type = UOP_ALU, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_bsx_op = +static const macro_op_t bsx_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 10} }; -static const risc86_instruction_t complex_call_far_op = +static const macro_op_t call_far_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -568,13 +550,13 @@ static const risc86_instruction_t complex_call_far_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_BRANCH, .latency = 1} }; -static const risc86_instruction_t complex_cli_sti_op = +static const macro_op_t cli_sti_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 7} }; -static const risc86_instruction_t complex_cmps_op = +static const macro_op_t cmps_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -582,15 +564,15 @@ static const risc86_instruction_t complex_cmps_op = .uop[1] = {.type = UOP_ALU, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_cmpsb_op = +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_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_cmpxchg_op = +static const macro_op_t cmpxchg_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -599,54 +581,62 @@ static const risc86_instruction_t complex_cmpxchg_op = .uop[2] = {.type = UOP_STORED, .latency = 1}, .uop[3] = {.type = UOP_STOREA, .latency = 1} }; -static const risc86_instruction_t complex_cmpxchg_b_op = +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_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} + .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 risc86_instruction_t complex_cpuid_op = +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 risc86_instruction_t complex_div16_op = +static const macro_op_t div16_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 10} + .uop[0] = {.type = UOP_ALUP0, .latency = 21} }; -static const risc86_instruction_t complex_div16_mem_op = +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_ALUX, .latency = 10} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 21} }; -static const risc86_instruction_t complex_div32_op = +static const macro_op_t div32_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 18} + .uop[0] = {.type = UOP_ALUP0, .latency = 37} }; -static const risc86_instruction_t complex_div32_mem_op = +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_ALUX, .latency = 18} + .uop[1] = {.type = UOP_ALUP0, .latency = 37} }; -static const risc86_instruction_t complex_emms_op = +static const macro_op_t emms_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 25} + .uop[0] = {.type = UOP_ALU, .latency = 50} }; -static const risc86_instruction_t complex_enter_op = +static const macro_op_t enter_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -654,28 +644,28 @@ static const risc86_instruction_t complex_enter_op = .uop[1] = {.type = UOP_STOREA, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 10} }; -static const risc86_instruction_t complex_femms_op = +static const macro_op_t femms_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 6} }; -static const risc86_instruction_t complex_in_op = +static const macro_op_t in_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 10} + .uop[0] = {.type = UOP_LOAD, .latency = 18} }; -static const risc86_instruction_t complex_ins_op = +static const macro_op_t ins_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 10}, + .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 risc86_instruction_t complex_int_op = +static const macro_op_t int_op = { .nr_uops = 8, .decode_type = DECODE_COMPLEX, @@ -688,7 +678,7 @@ static const risc86_instruction_t complex_int_op = .uop[6] = {.type = UOP_STOREA, .latency = 1}, .uop[7] = {.type = UOP_BRANCH, .latency = 1} }; -static const risc86_instruction_t complex_iret_op = +static const macro_op_t iret_op = { .nr_uops = 5, .decode_type = DECODE_COMPLEX, @@ -698,41 +688,20 @@ static const risc86_instruction_t complex_iret_op = .uop[3] = {.type = UOP_ALU, .latency = 20}, .uop[4] = {.type = UOP_BRANCH, .latency = 1} }; -static const risc86_instruction_t complex_invd_op = +static const macro_op_t invd_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 500} }; -static const risc86_instruction_t complex_jmp_far_op = +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 risc86_instruction_t complex_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 risc86_instruction_t complex_load_alux_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1} -}; -static const risc86_instruction_t complex_loop_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .latency = 1} -}; -static const risc86_instruction_t complex_lss_op = +static const macro_op_t lss_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -740,7 +709,7 @@ static const risc86_instruction_t complex_lss_op = .uop[1] = {.type = UOP_LOAD, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 3} }; -static const risc86_instruction_t complex_mov_mem_seg_op = +static const macro_op_t mov_mem_seg_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -748,68 +717,63 @@ static const risc86_instruction_t complex_mov_mem_seg_op = .uop[1] = {.type = UOP_STORED, .latency = 1}, .uop[2] = {.type = UOP_STOREA, .latency = 1}, }; -static const risc86_instruction_t complex_mov_seg_mem_op = +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 risc86_instruction_t complex_mov_seg_reg_op = +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 risc86_instruction_t complex_mul_op = +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_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_mul_mem_op = +static const macro_op_t mul64_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1}, + .uop[2] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_mul64_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1} -}; -static const risc86_instruction_t complex_mul64_mem_op = +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_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .latency = 1} + .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 risc86_instruction_t complex_out_op = +static const macro_op_t out_op = { - .nr_uops = 2, + .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 10}, - .uop[1] = {.type = UOP_STOREA, .latency = 10}, + .uop[0] = {.type = UOP_ALU, .latency = 18} }; -static const risc86_instruction_t complex_outs_op = +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_STORED, .latency = 10}, - .uop[1] = {.type = UOP_STOREA, .latency = 10}, - .uop[2] = {.type = UOP_ALU, .latency = 1} + .uop[1] = {.type = UOP_ALU, .latency = 18} }; -static const risc86_instruction_t complex_pusha_op = +static const macro_op_t pusha_op = { .nr_uops = 8, .decode_type = DECODE_COMPLEX, @@ -822,7 +786,7 @@ static const risc86_instruction_t complex_pusha_op = .uop[6] = {.type = UOP_STORED, .latency = 2}, .uop[7] = {.type = UOP_STOREA, .latency = 2} }; -static const risc86_instruction_t complex_popa_op = +static const macro_op_t popa_op = { .nr_uops = 8, .decode_type = DECODE_COMPLEX, @@ -835,36 +799,30 @@ static const risc86_instruction_t complex_popa_op = .uop[6] = {.type = UOP_LOAD, .latency = 1}, .uop[7] = {.type = UOP_LOAD, .latency = 1} }; -static const risc86_instruction_t complex_popf_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_ALUX, .latency = 17} -}; -static const risc86_instruction_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 risc86_instruction_t complex_pushf_op = +static const macro_op_t popf_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .latency = 6}, + .uop[2] = {.type = UOP_ALUP0, .latency = 10} }; -static const risc86_instruction_t complex_ret_op = +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 risc86_instruction_t complex_retf_op = +static const macro_op_t retf_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -872,52 +830,52 @@ static const risc86_instruction_t complex_retf_op = .uop[1] = {.type = UOP_ALU, .latency = 3}, .uop[2] = {.type = UOP_BRANCH, .latency = 1} }; -static const risc86_instruction_t complex_scas_op = +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 risc86_instruction_t complex_scasb_op = +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 risc86_instruction_t complex_setcc_mem_op = +static const macro_op_t setcc_mem_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_FSTORED, .latency = 1}, - .uop[3] = {.type = UOP_FSTOREA, .latency = 1} + .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 risc86_instruction_t complex_setcc_reg_op = +static const macro_op_t setcc_reg_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_test_mem_op = +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 risc86_instruction_t complex_test_mem_b_op = +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_ALUX, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_xchg_mem_op = +static const macro_op_t xchg_mem_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -926,60 +884,58 @@ static const risc86_instruction_t complex_xchg_mem_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_xlat_op = +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 risc86_instruction_t complex_wbinvd_op = +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 risc86_instruction_t *opcode_timings[256] = +static const macro_op_t *opcode_timings[256] = { /* ADD ADD ADD ADD*/ -/*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/*00*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* ADD ADD PUSH ES POP ES*/ - &alux_op, &alu_op, &push_seg_op, &complex_mov_seg_mem_op, + &alup0_op, &alu_op, &push_seg_op, &mov_seg_mem_op, /* OR OR OR OR*/ - &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, + &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* OR OR PUSH CS */ - &alux_op, &alu_op, &push_seg_op, INVALID, + &alup0_op, &alu_op, &push_seg_op, INVALID, /* ADC ADC ADC ADC*/ -/*10*/ &complex_alux_store_op,&complex_alu_store_op, &complex_load_alux_op,&complex_load_alu_op, +/*10*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* ADC ADC PUSH SS POP SS*/ - &complex_alux1_op, &complex_alu1_op, &push_seg_op, &complex_mov_seg_mem_op, + &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, /* SBB SBB SBB SBB*/ -/*10*/ &complex_alux_store_op,&complex_alu_store_op, &complex_load_alux_op,&complex_load_alu_op, +/*10*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* SBB SBB PUSH DS POP DS*/ - &complex_alux1_op, &complex_alu1_op, &push_seg_op, &complex_mov_seg_mem_op, + &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, /* AND AND AND AND*/ -/*20*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/*20*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* AND AND DAA*/ - &alux_op, &alu_op, INVALID, &complex_alux1_op, + &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, /* SUB SUB SUB SUB*/ - &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, + &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* SUB SUB DAS*/ - &alux_op, &alu_op, INVALID, &complex_alux1_op, + &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, /* XOR XOR XOR XOR*/ -/*30*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/*30*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* XOR XOR AAA*/ - &alux_op, &alu_op, INVALID, &complex_alux6_op, + &alup0_op, &alu_op, INVALID, &alup0_6_op, /* CMP CMP CMP CMP*/ - &load_alux_op, &load_alu_op, &load_alux_op, &load_alu_op, + &load_alup0_op, &load_alu_op, &load_alup0_op, &load_alu_op, /* CMP CMP AAS*/ - &alux_op, &alu_op, INVALID, &complex_alux6_op, + &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, @@ -1000,12 +956,12 @@ static const risc86_instruction_t *opcode_timings[256] = &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, /* PUSHA POPA BOUND ARPL*/ -/*60*/ &complex_pusha_op, &complex_popa_op, &complex_bound_op, &complex_arpl_op, +/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, INVALID, INVALID, INVALID, INVALID, /* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &complex_mul_op, &push_imm_op, &complex_mul_op, + &push_imm_op, &mul_op, &push_imm_op, &mul_op, /* INSB INSW OUTSB OUTSW*/ - &complex_ins_op, &complex_ins_op, &complex_outs_op, &complex_outs_op, + &ins_op, &ins_op, &outs_op, &outs_op, /* Jxx*/ /*70*/ &branch_op, &branch_op, &branch_op, &branch_op, @@ -1015,107 +971,107 @@ static const risc86_instruction_t *opcode_timings[256] = /*80*/ INVALID, INVALID, INVALID, INVALID, /* TEST TEST XCHG XCHG*/ - &complex_test_mem_b_op, &complex_test_mem_op, &complex_xchg_mem_op, &complex_xchg_mem_op, + &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*/ - &complex_mov_mem_seg_op, &store_op, &complex_mov_seg_mem_op, &pop_mem_op, + &mov_mem_seg_op, &store_op, &mov_seg_mem_op, &pop_mem_op, /* NOP XCHG XCHG XCHG*/ -/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, +/*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, &complex_call_far_op, &limm_op, + &complex_alu1_op, &complex_alu1_op, &call_far_op, &fxch_op, /* PUSHF POPF SAHF LAHF*/ - &complex_pushf_op, &complex_popf_op, &complex_alux1_op, &complex_alux1_op, + &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, &complex_cmpsb_op, &complex_cmps_op, + &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, &complex_scasb_op, &complex_scas_op, + &lods_op, &lods_op, &scasb_op, &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, +/*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, &complex_ret_op, &complex_ret_op, +/*c0*/ INVALID, INVALID, &ret_op, &ret_op, /* LES LDS MOV MOV*/ - &complex_lss_op, &complex_lss_op, &store_op, &store_op, + &lss_op, &lss_op, &store_op, &store_op, /* ENTER LEAVE RETF RETF*/ - &complex_enter_op, &leave_op, &complex_retf_op, &complex_retf_op, + &enter_op, &leave_op, &retf_op, &retf_op, /* INT3 INT INTO IRET*/ - &complex_int_op, &complex_int_op, &complex_int_op, &complex_iret_op, + &int_op, &int_op, &int_op, &iret_op, /*d0*/ INVALID, INVALID, INVALID, INVALID, /* AAM AAD SETALC XLAT*/ - &complex_alux6_op, &complex_alux3_op, &complex_alux1_op, &complex_xlat_op, + &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*/ &complex_loop_op, &complex_loop_op, &loop_op, &complex_loop_op, +/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, /* IN AL IN AX OUT_AL OUT_AX*/ - &complex_in_op, &complex_in_op, &complex_out_op, &complex_out_op, + &in_op, &in_op, &out_op, &out_op, /* CALL JMP JMP JMP*/ - &store_op, &branch_op, &complex_jmp_far_op, &branch_op, + &store_op, &branch_op, &jmp_far_op, &branch_op, /* IN AL IN AX OUT_AL OUT_AX*/ - &complex_in_op, &complex_in_op, &complex_out_op, &complex_out_op, + &in_op, &in_op, &out_op, &out_op, /* REPNE REPE*/ /*f0*/ INVALID, INVALID, INVALID, INVALID, /* HLT CMC*/ - &complex_alux1_op, &complex_alu2_op, INVALID, INVALID, + &complex_alup0_1_op, &alu2_op, INVALID, INVALID, /* CLC STC CLI STI*/ - &complex_alu1_op, &complex_alu1_op, &complex_cli_sti_op, &complex_cli_sti_op, + &complex_alu1_op, &complex_alu1_op, &cli_sti_op, &cli_sti_op, /* CLD STD INCDEC*/ - &complex_alu1_op, &complex_alu1_op, &alux_store_op, INVALID + &complex_alu1_op, &complex_alu1_op, &alup0_store_op, INVALID }; -static const risc86_instruction_t *opcode_timings_mod3[256] = +static const macro_op_t *opcode_timings_mod3[256] = { /* ADD ADD ADD ADD*/ -/*00*/ &alux_op, &alu_op, &alux_op, &alu_op, +/*00*/ &alup0_op, &alu_op, &alup0_op, &alu_op, /* ADD ADD PUSH ES POP ES*/ - &alux_op, &alu_op, &push_seg_op, &complex_mov_seg_mem_op, + &alup0_op, &alu_op, &push_seg_op, &mov_seg_mem_op, /* OR OR OR OR*/ - &alux_op, &alu_op, &alux_op, &alu_op, + &alup0_op, &alu_op, &alup0_op, &alu_op, /* OR OR PUSH CS */ - &alux_op, &alu_op, &push_seg_op, INVALID, + &alup0_op, &alu_op, &push_seg_op, INVALID, /* ADC ADC ADC ADC*/ -/*10*/ &complex_alux1_op, &complex_alu1_op, &complex_alux1_op, &complex_alu1_op, +/*10*/ &complex_alup0_1_op, &complex_alu1_op, &complex_alup0_1_op, &complex_alu1_op, /* ADC ADC PUSH SS POP SS*/ - &complex_alux1_op, &complex_alu1_op, &push_seg_op, &complex_mov_seg_mem_op, + &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, /* SBB SBB SBB SBB*/ - &complex_alux1_op, &complex_alu1_op, &complex_alux1_op, &complex_alu1_op, + &complex_alup0_1_op, &complex_alu1_op, &complex_alup0_1_op, &complex_alu1_op, /* SBB SBB PUSH DS POP DS*/ - &complex_alux1_op, &complex_alu1_op, &push_seg_op, &complex_mov_seg_mem_op, + &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, /* AND AND AND AND*/ -/*20*/ &alux_op, &alu_op, &alux_op, &alu_op, +/*20*/ &alup0_op, &alu_op, &alup0_op, &alu_op, /* AND AND DAA*/ - &alux_op, &alu_op, INVALID, &complex_alux1_op, + &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, /* SUB SUB SUB SUB*/ - &alux_op, &alu_op, &alux_op, &alu_op, + &alup0_op, &alu_op, &alup0_op, &alu_op, /* SUB SUB DAS*/ - &alux_op, &alu_op, INVALID, &complex_alux1_op, + &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, /* XOR XOR XOR XOR*/ -/*30*/ &alux_op, &alu_op, &alux_op, &alu_op, +/*30*/ &alup0_op, &alu_op, &alup0_op, &alu_op, /* XOR XOR AAA*/ - &alux_op, &alu_op, INVALID, &complex_alux6_op, + &alup0_op, &alu_op, INVALID, &alup0_6_op, /* CMP CMP CMP CMP*/ - &alux_op, &alu_op, &alux_op, &alu_op, + &alup0_op, &alu_op, &alup0_op, &alu_op, /* CMP CMP AAS*/ - &alux_op, &alu_op, INVALID, &complex_alux6_op, + &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, @@ -1136,12 +1092,12 @@ static const risc86_instruction_t *opcode_timings_mod3[256] = &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, /* PUSHA POPA BOUND ARPL*/ -/*60*/ &complex_pusha_op, &complex_popa_op, &complex_bound_op, &complex_arpl_op, +/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, INVALID, INVALID, INVALID, INVALID, /* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &complex_mul_op, &push_imm_op, &complex_mul_op, + &push_imm_op, &mul_op, &push_imm_op, &mul_op, /* INSB INSW OUTSB OUTSW*/ - &complex_ins_op, &complex_ins_op, &complex_outs_op, &complex_outs_op, + &ins_op, &ins_op, &outs_op, &outs_op, /* Jxx*/ /*70*/ &branch_op, &branch_op, &branch_op, &branch_op, @@ -1151,88 +1107,89 @@ static const risc86_instruction_t *opcode_timings_mod3[256] = /*80*/ INVALID, INVALID, INVALID, INVALID, /* TEST TEST XCHG XCHG*/ - &complex_alu1_op, &complex_alu1_op, &complex_alu3_op, &complex_alu3_op, + &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, &complex_mov_seg_reg_op, &pop_reg_op, + &mov_reg_seg_op, &store_op, &mov_seg_reg_op, &pop_reg_op, /* NOP XCHG XCHG XCHG*/ -/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, +/*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, &complex_call_far_op, &limm_op, + &complex_alu1_op, &complex_alu1_op, &call_far_op, &fxch_op, /* PUSHF POPF SAHF LAHF*/ - &complex_pushf_op, &complex_popf_op, &complex_alux1_op, &complex_alux1_op, + &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, &complex_cmpsb_op, &complex_cmps_op, + &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, &complex_scasb_op, &complex_scas_op, + &lods_op, &lods_op, &scasb_op, &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, +/*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, &complex_ret_op, &complex_ret_op, +/*c0*/ INVALID, INVALID, &ret_op, &ret_op, /* LES LDS MOV MOV*/ - &complex_lss_op, &complex_lss_op, &store_op, &store_op, + &lss_op, &lss_op, &store_op, &store_op, /* ENTER LEAVE RETF RETF*/ - &complex_enter_op, &leave_op, &complex_retf_op, &complex_retf_op, + &enter_op, &leave_op, &retf_op, &retf_op, /* INT3 INT INTO IRET*/ - &complex_int_op, &complex_int_op, &complex_int_op, &complex_iret_op, + &int_op, &int_op, &int_op, &iret_op, /*d0*/ INVALID, INVALID, INVALID, INVALID, /* AAM AAD SETALC XLAT*/ - &complex_alux6_op, &complex_alux3_op, &complex_alux1_op, &complex_xlat_op, + &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*/ &complex_loop_op, &complex_loop_op, &loop_op, &complex_loop_op, +/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, /* IN AL IN AX OUT_AL OUT_AX*/ - &complex_in_op, &complex_in_op, &complex_out_op, &complex_out_op, + &in_op, &in_op, &out_op, &out_op, /* CALL JMP JMP JMP*/ - &store_op, &branch_op, &complex_jmp_far_op, &branch_op, + &store_op, &branch_op, &jmp_far_op, &branch_op, /* IN AL IN AX OUT_AL OUT_AX*/ - &complex_in_op, &complex_in_op, &complex_out_op, &complex_out_op, + &in_op, &in_op, &out_op, &out_op, /* REPNE REPE*/ /*f0*/ INVALID, INVALID, INVALID, INVALID, /* HLT CMC*/ - &complex_alux1_op, &complex_alu2_op, INVALID, INVALID, + &complex_alup0_1_op, &alu2_op, INVALID, INVALID, /* CLC STC CLI STI*/ - &complex_alu1_op, &complex_alu1_op, &complex_cli_sti_op, &complex_cli_sti_op, + &complex_alu1_op, &complex_alu1_op, &cli_sti_op, &cli_sti_op, /* CLD STD INCDEC*/ - &complex_alu1_op, &complex_alu1_op, &complex_alux1_op, INVALID + &complex_alu1_op, &complex_alu1_op, &complex_alup0_1_op, INVALID }; -static const risc86_instruction_t *opcode_timings_0f[256] = +static const macro_op_t *opcode_timings_0f[256] = { -/*00*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, - INVALID, &complex_alu6_op, &complex_alu6_op, INVALID, - &complex_invd_op, &complex_wbinvd_op, INVALID, INVALID, - INVALID, &load_op, &complex_femms_op, INVALID, +/*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*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, - &complex_alu6_op, &complex_alu6_op, 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*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, INVALID, +/*30*/ &alu6_op, &alu6_op, &alu6_op, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1253,7 +1210,7 @@ static const risc86_instruction_t *opcode_timings_0f[256] = 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, &complex_emms_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &emms_op, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, &mstore_op, &mstore_op, @@ -1262,23 +1219,23 @@ static const risc86_instruction_t *opcode_timings_0f[256] = &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, -/*90*/ &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, - &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, - &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, - &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_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, &complex_mov_seg_mem_op,&complex_cpuid_op, &complex_load_alu_op, - &complex_alu_store_op, &complex_alu_store_op, INVALID, INVALID, - &push_seg_op, &complex_mov_seg_mem_op,INVALID, &complex_load_alu_op, - &complex_alu_store_op, &complex_alu_store_op, INVALID, &complex_mul_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*/ &complex_cmpxchg_b_op, &complex_cmpxchg_op, &complex_lss_op, &complex_load_alu_op, - &complex_lss_op, &complex_lss_op, &load_alux_op, &load_alu_op, - INVALID, INVALID, &complex_load_alu_op, &complex_load_alu_op, - &complex_bsx_op, &complex_bsx_op, &load_alux_op, &load_alu_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*/ &complex_alux_store_op, &complex_alu_store_op, INVALID, INVALID, - INVALID, INVALID, INVALID, &complex_cmpxchg_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, @@ -1297,182 +1254,182 @@ static const risc86_instruction_t *opcode_timings_0f[256] = &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] = +static const macro_op_t *opcode_timings_0f_mod3[256] = { -/*00*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, - INVALID, &complex_alu6_op, &complex_alu6_op, INVALID, - &complex_invd_op, &complex_wbinvd_op, INVALID, INVALID, - INVALID, INVALID, &complex_femms_op, INVALID, +/*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*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, - &complex_alu6_op, &complex_alu6_op, 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*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, INVALID, - INVALID, INVALID, 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, +/*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, +/*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, +/*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, &complex_emms_op, - INVALID, INVALID, INVALID, INVALID, - 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*/ &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, - &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, - &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, - &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_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, &complex_mov_seg_mem_op, &complex_cpuid_op, &complex_alu1_op, - &complex_alu1_op, &complex_alu1_op, INVALID, INVALID, - &push_seg_op, &complex_mov_seg_mem_op, INVALID, &complex_alu1_op, - &complex_alu1_op, &complex_alu1_op, INVALID, &complex_mul_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*/ &complex_cmpxchg_b_op, &complex_cmpxchg_op, &complex_lss_op, &complex_alu1_op, - &complex_lss_op, &complex_lss_op, &alux_op, &alu_op, - INVALID, INVALID, &complex_alu1_op, &complex_alu1_op, - &complex_bsx_op, &complex_bsx_op, &alux_op, &alu_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_alux1_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, +/*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, +/*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, +/*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, +/*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_shift[8] = +static const macro_op_t *opcode_timings_shift[8] = { - &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, - &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op + &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 risc86_instruction_t *opcode_timings_shift_b[8] = +static const macro_op_t *opcode_timings_shift_b[8] = { - &complex_alux_store_op, &complex_alux_store_op, &complex_alux_store_op, &complex_alux_store_op, - &complex_alux_store_op, &complex_alux_store_op, &complex_alux_store_op, &complex_alux_store_op + &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 risc86_instruction_t *opcode_timings_shift_mod3[8] = +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 risc86_instruction_t *opcode_timings_shift_b_mod3[8] = +static const macro_op_t *opcode_timings_shift_b_mod3[8] = { - &complex_alux1_op, &complex_alux1_op, &complex_alux1_op, &complex_alux1_op, - &alux_op, &alux_op, &alux_op, &alux_op + &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 risc86_instruction_t *opcode_timings_80[8] = +static const macro_op_t *opcode_timings_80[8] = { - &alux_store_op, &alux_store_op, &complex_alux_store_op, &complex_alux_store_op, - &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, + &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 risc86_instruction_t *opcode_timings_80_mod3[8] = +static const macro_op_t *opcode_timings_80_mod3[8] = { - &alux_op, &alux_op, &alux_store_op, &alux_store_op, - &alux_op, &alux_op, &alux_op, &alux_op, + &alup0_op, &alup0_op, &alup0_store_op, &alup0_store_op, + &alup0_op, &alup0_op, &alup0_op, &alup0_op, }; -static const risc86_instruction_t *opcode_timings_8x[8] = +static const macro_op_t *opcode_timings_8x[8] = { - &alu_store_op, &alu_store_op, &complex_alu_store_op, &complex_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_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, + &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] = +static const macro_op_t *opcode_timings_f6[8] = { /* TST NOT NEG*/ - &test_mem_imm_b_op, INVALID, &complex_alux_store_op, &complex_alux_store_op, + &test_mem_imm_b_op, INVALID, &alup0_store_op, &alup0_store_op, /* MUL IMUL DIV IDIV*/ - &complex_mul_mem_op, &complex_mul_mem_op, &complex_div16_mem_op, &complex_div16_mem_op, + &mul_mem_op, &mul_mem_op, &div16_mem_op, &div16_mem_op, }; -static const risc86_instruction_t *opcode_timings_f6_mod3[8] = +static const macro_op_t *opcode_timings_f6_mod3[8] = { /* TST NOT NEG*/ - &test_reg_b_op, INVALID, &alux_op, &alux_op, + &test_reg_b_op, INVALID, &alup0_op, &alup0_op, /* MUL IMUL DIV IDIV*/ - &complex_mul_op, &complex_mul_op, &complex_div16_op, &complex_div16_op, + &mul_op, &mul_op, &div16_op, &div16_op, }; -static const risc86_instruction_t *opcode_timings_f7[8] = +static const macro_op_t *opcode_timings_f7[8] = { /* TST NOT NEG*/ - &test_mem_imm_op, INVALID, &complex_alu_store_op, &complex_alu_store_op, + &test_mem_imm_op, INVALID, &alu_store_op, &alu_store_op, /* MUL IMUL DIV IDIV*/ - &complex_mul64_mem_op, &complex_mul64_mem_op, &complex_div32_mem_op, &complex_div32_mem_op, + &mul64_mem_op, &mul64_mem_op, &div32_mem_op, &div32_mem_op, }; -static const risc86_instruction_t *opcode_timings_f7_mod3[8] = +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*/ - &complex_mul64_op, &complex_mul64_op, &complex_div32_op, &complex_div32_op, + &mul64_op, &mul64_op, &div32_op, &div32_op, }; -static const risc86_instruction_t *opcode_timings_ff[8] = +static const macro_op_t *opcode_timings_ff[8] = { /* INC DEC CALL CALL far*/ - &alu_store_op, &alu_store_op, &store_op, &complex_call_far_op, + &alu_store_op, &alu_store_op, &store_op, &call_far_op, /* JMP JMP far PUSH*/ - &branch_op, &complex_jmp_far_op, &push_mem_op, INVALID + &branch_op, &jmp_far_op, &push_mem_op, INVALID }; -static const risc86_instruction_t *opcode_timings_ff_mod3[8] = +static const macro_op_t *opcode_timings_ff_mod3[8] = { /* INC DEC CALL CALL far*/ - &complex_alu1_op, &complex_alu1_op, &store_op, &complex_call_far_op, + &complex_alu1_op, &complex_alu1_op, &store_op, &call_far_op, /* JMP JMP far PUSH*/ - &branch_op, &complex_jmp_far_op, &complex_push_mem_op, INVALID + &branch_op, &jmp_far_op, &complex_push_mem_op, INVALID }; -static const risc86_instruction_t *opcode_timings_d8[8] = +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 risc86_instruction_t *opcode_timings_d8_mod3[8] = +static const macro_op_t *opcode_timings_d8_mod3[8] = { /* FADD FMUL FCOM FCOMP*/ &fadd_op, &fmul_op, &float_op, &float_op, @@ -1480,27 +1437,27 @@ static const risc86_instruction_t *opcode_timings_d8_mod3[8] = &float_op, &float_op, &fdiv_op, &fdiv_op, }; -static const risc86_instruction_t *opcode_timings_d9[8] = +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, &complex_fldcw_op, &complex_float_l_op, &complex_float_op + &complex_float_l_op, &fldcw_op, &complex_float_l_op, &complex_float_op }; -static const risc86_instruction_t *opcode_timings_d9_mod3[64] = +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*/ - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, + &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, + &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*/ @@ -1519,28 +1476,28 @@ static const risc86_instruction_t *opcode_timings_d9_mod3[64] = &float_op, &fdiv_op, &fsin_op, &fsin_op }; -static const risc86_instruction_t *opcode_timings_da[8] = +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 risc86_instruction_t *opcode_timings_da_mod3[8] = +static const macro_op_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] = +static const macro_op_t *opcode_timings_db[8] = { /* FLDil FSTil FSTPil*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDe FSTPe*/ - INVALID, &complex_flde_op, INVALID, &complex_fste_op + INVALID, &flde_op, INVALID, &fste_op }; -static const risc86_instruction_t *opcode_timings_db_mod3[64] = +static const macro_op_t *opcode_timings_db_mod3[64] = { INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1569,14 +1526,14 @@ static const risc86_instruction_t *opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, }; -static const risc86_instruction_t *opcode_timings_dc[8] = +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 risc86_instruction_t *opcode_timings_dc_mod3[8] = +static const macro_op_t *opcode_timings_dc_mod3[8] = { /* opFADDr opFMULr*/ &fadd_op, &fmul_op, INVALID, INVALID, @@ -1584,14 +1541,14 @@ static const risc86_instruction_t *opcode_timings_dc_mod3[8] = &float_op, &float_op, &fdiv_op, &fdiv_op }; -static const risc86_instruction_t *opcode_timings_dd[8] = +static const macro_op_t *opcode_timings_dd[8] = { /* FLDd FSTd FSTPd*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, + &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 risc86_instruction_t *opcode_timings_dd_mod3[8] = +static const macro_op_t *opcode_timings_dd_mod3[8] = { /* FFFREE FST FSTP*/ &float_op, INVALID, &float_op, &float_op, @@ -1599,14 +1556,14 @@ static const risc86_instruction_t *opcode_timings_dd_mod3[8] = &float_op, &float_op, INVALID, INVALID }; -static const risc86_instruction_t *opcode_timings_de[8] = +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 risc86_instruction_t *opcode_timings_de_mod3[8] = +static const macro_op_t *opcode_timings_de_mod3[8] = { /* FADDP FMULP FCOMPP*/ &fadd_op, &fmul_op, INVALID, &float_op, @@ -1614,14 +1571,14 @@ static const risc86_instruction_t *opcode_timings_de_mod3[8] = &float_op, &float_op, &fdiv_op, &fdiv_op, }; -static const risc86_instruction_t *opcode_timings_df[8] = +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 risc86_instruction_t *opcode_timings_df_mod3[8] = +static const macro_op_t *opcode_timings_df_mod3[8] = { INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ @@ -1647,35 +1604,35 @@ static p6_unit_t *units; /*Pentium Pro has no MMX*/ static p6_unit_t ppro_units[] = { - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_FLOAT)}, /*Integer X & Floating point*/ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH)}, /*Integer Y*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD)}, /*Load*/ - {.uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED)}, /*Data Store*/ - {.uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA)}, /*Address Store*/ + {.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_ALUX) | (1 << UOP_FLOAT) | /*Integer X & Floating point*/ + {.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) | /*Integer Y*/ + {.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)}, /*Load*/ - {.uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED) | (1 << UOP_MSTORED)}, /*Data Store*/ - {.uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA) | (1 << UOP_MSTOREA)}, /*Address Store*/ + {.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 risc86_uop_t *uop, int decode_time) +static int uop_run(const p6_uop_t *uop, int decode_time) { int c; p6_unit_t *best_unit = NULL; - double best_start_cycle = 99999; + int best_start_cycle = 99999; - /*UOP_LIMM does not require execution*/ - if (uop->type == UOP_LIMM) + /*UOP_FXCH does not require execution*/ + if (uop->type == UOP_FXCH) return decode_time; /*Find execution unit for this uOP*/ @@ -1709,7 +1666,7 @@ static int uop_run(const risc86_uop_t *uop, int decode_time) static struct { int nr_uops; - const risc86_uop_t *uops[6]; + 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*/ @@ -1748,7 +1705,10 @@ void decode_flush_p6() /*Submit uops to execution units, and determine the latest completion time*/ for (c = 0; c < (decode_buffer.nr_uops); c++) { - start_timestamp = decode_buffer.earliest_start[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) @@ -1822,7 +1782,7 @@ static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_ return len; } -static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) +static void decode_instruction(const macro_op_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) { uint32_t regmask_required; uint32_t regmask_modified; @@ -1858,10 +1818,8 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u } /*Simple decoders are limited to 7 bytes & 1 uOP*/ - if (decode_type == DECODE_SIMPLE && instr_length > 7) + if ((decode_type == DECODE_SIMPLE && instr_length > 7) || (decode_type == DECODE_SIMPLE && ins->nr_uops > 1)) decode_type = DECODE_COMPLEX; - else if (decode_type == DECODE_SIMPLE && ins->nr_uops > 1) - decode_type = DECODE_COMPLEX; switch (decode_type) { @@ -1904,7 +1862,10 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u for (c = 0; c < ins->nr_uops; c++) { decode_buffer.uops[d] = &ins->uop[c]; - decode_buffer.earliest_start[d] = earliest_start; + 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*/ @@ -2009,7 +1970,7 @@ void codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { - const risc86_instruction_t **ins_table; + const macro_op_t **ins_table; uint64_t *deps; int mod3 = ((fetchdat & 0xc0) == 0xc0); int old_last_complete_timestamp = last_complete_timestamp; diff --git a/src/cpu_common/386_common.c b/src/cpu_common/386_common.c index c552faef3..47db7c5db 100644 --- a/src/cpu_common/386_common.c +++ b/src/cpu_common/386_common.c @@ -37,11 +37,6 @@ uint32_t dr[8]; uint32_t use32; int stack32; -int optype; - -int trap; - -uint32_t rmdat; uint32_t *eal_r, *eal_w; @@ -57,8 +52,10 @@ uint16_t cpu_cur_status = 0; uint32_t cpu_cur_status = 0; #endif -uint32_t pccache; -uint8_t *pccache2; +extern uint8_t *pccache2; + +extern int optype; +extern uint32_t pccache; int in_sys = 0; diff --git a/src/cpu_common/386_dynarec.c b/src/cpu_common/386_dynarec.c index 70df8e8a3..af004521a 100644 --- a/src/cpu_common/386_dynarec.c +++ b/src/cpu_common/386_dynarec.c @@ -273,8 +273,32 @@ static void prefetch_flush() #define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #ifdef USE_DYNAREC -static int cycles_main = 0; +static int cycles_main = 0, cycles_old = 0; +static uint64_t tsc_old = 0; +void update_tsc(void) +{ + int cycdiff; + uint64_t delta; + + cycdiff = cycles_old - cycles; + delta = tsc - tsc_old; + if (delta > 0) { + /* TSC has changed, this means interim timer processing has happened, + see how much we still need to add. */ + cycdiff -= delta; + if (cycdiff > 0) + tsc += cycdiff; + } else { + /* TSC has not changed. */ + tsc += cycdiff; + } + + if (cycdiff > 0) { + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + } +} void exec386_dynarec(int cycs) { @@ -283,6 +307,8 @@ void exec386_dynarec(int cycs) int tempi; int cycdiff; int oldcyc; + int oldcyc2; + uint64_t oldtsc, delta; uint32_t start_pc = 0; int cyc_period = cycs / 2000; /*5us*/ @@ -305,7 +331,10 @@ void exec386_dynarec(int cycs) cycdiff=0; #endif - oldcyc=cycles; + oldcyc = oldcyc2 = cycles; + cycles_old = cycles; + oldtsc = tsc; + tsc_old = tsc; if (!CACHE_ON()) /*Interpret block*/ { cpu_block_end = 0; @@ -699,9 +728,19 @@ void exec386_dynarec(int cycs) #endif } - cycdiff=oldcyc-cycles; - tsc += cycdiff; - + cycdiff = oldcyc - cycles; + delta = tsc - oldtsc; + if (delta > 0) { + /* TSC has changed, this means interim timer processing has happened, + see how much we still need to add. */ + cycdiff -= delta; + if (cycdiff > 0) + tsc += cycdiff; + } else { + /* TSC has not changed. */ + tsc += cycdiff; + } + if (cpu_state.abrt) { flags_rebuild(); @@ -799,8 +838,10 @@ void exec386_dynarec(int cycs) } } - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); + if (cycdiff > 0) { + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + } } cycles_main -= (cycles_start - cycles); diff --git a/src/cpu_common/808x.c b/src/cpu_common/808x.c index ca2b80979..6bc896753 100644 --- a/src/cpu_common/808x.c +++ b/src/cpu_common/808x.c @@ -34,6 +34,7 @@ #include <86box/rom.h> #include <86box/nmi.h> #include <86box/pic.h> +#include <86box/ppi.h> #include <86box/timer.h> /* The opcode of the instruction currently being executed. */ @@ -978,8 +979,10 @@ reset_common(int hard) in_smm = smi_latched = 0; smi_line = smm_in_hlt = 0; - if (hard) + if (hard) { smbase = 0x00030000; + ppi_reset(); + } in_sys = 0; } diff --git a/src/cpu_common/cpu.c b/src/cpu_common/cpu.c index b3bec0256..3bf19b26b 100644 --- a/src/cpu_common/cpu.c +++ b/src/cpu_common/cpu.c @@ -3162,6 +3162,10 @@ void cpu_WRMSR() case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; + case 0x8B: + cpu_log("WRMSR: Invalid MSR: 0x8B/n"); /*Needed for Vista to correctly break on Pentium*/ + x86gpf(NULL, 0); + break; } break; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) diff --git a/src/cpu_common/cpu.h b/src/cpu_common/cpu.h index 403457f60..a7a8f8621 100644 --- a/src/cpu_common/cpu.h +++ b/src/cpu_common/cpu.h @@ -147,6 +147,7 @@ extern CPU cpus_Cyrix3[]; extern CPU cpus_PentiumPro[]; extern CPU cpus_PentiumII_28v[]; extern CPU cpus_PentiumII[]; +extern CPU cpus_Xeon[]; extern CPU cpus_Celeron[]; @@ -565,6 +566,7 @@ extern int cpu_effective, cpu_alt_reset; extern void cpu_dynamic_switch(int new_cpu); extern void cpu_ven_reset(void); +extern void update_tsc(void); extern int sysenter(uint32_t fetchdat); extern int sysexit(uint32_t fetchdat); diff --git a/src/cpu_common/cpu_table.c b/src/cpu_common/cpu_table.c index 620d94eaa..e08f57949 100644 --- a/src/cpu_common/cpu_table.c +++ b/src/cpu_common/cpu_table.c @@ -724,25 +724,29 @@ CPU cpus_PentiumII[] = { }; +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. Intended for - the PGA370 boards but they were capable to fit on a PGA 370 to Slot 1 + /* 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 Mendocino is only meant to not cause any struggle + The 100Mhz & 166Mhz Mendocino is only meant to not cause any struggle to the recompiler. */ - {"Celeron Mendocino 25", CPU_PENTIUM2D, 25000000, 1.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 3}, - {"Celeron Mendocino 50", CPU_PENTIUM2D, 50000000, 1.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"Celeron Mendocino 66", CPU_PENTIUM2D, 66666666, 1.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, {"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, 4.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, - {"Celeron Mendocino 433", CPU_PENTIUM2D, 433333333, 4.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 39,39,13,13, 51}, - {"Celeron Mendocino 466", CPU_PENTIUM2D, 466666666, 5.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43,43,15,15, 57}, - {"Celeron Mendocino 500", CPU_PENTIUM2D, 500000000, 5.0, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45,45,15,15, 60}, - {"Celeron Mendocino 533", CPU_PENTIUM2D, 533333333, 5.5, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48,48,17,17, 64}, + {"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} }; diff --git a/src/cpu_common/x86_ops_msr.h b/src/cpu_common/x86_ops_msr.h index 2a8bdcf4c..4c9fd9fe5 100644 --- a/src/cpu_common/x86_ops_msr.h +++ b/src/cpu_common/x86_ops_msr.h @@ -14,6 +14,8 @@ static int opRDTSC(uint32_t fetchdat) EAX = tsc & 0xffffffff; EDX = tsc >> 32; CLOCK_CYCLES(1); + if (cpu_use_dynarec) + update_tsc(); return 0; } diff --git a/src/cpu_common/x87.c b/src/cpu_common/x87.c index 8183f2e3e..47ab0c844 100644 --- a/src/cpu_common/x87.c +++ b/src/cpu_common/x87.c @@ -17,6 +17,10 @@ #include "386_common.h" +uint32_t x87_pc_off,x87_op_off; +uint16_t x87_pc_seg,x87_op_seg; + + #ifdef ENABLE_FPU_LOG int fpu_do_log = ENABLE_FPU_LOG; diff --git a/src/cpu_common/x87.h b/src/cpu_common/x87.h index 106e8c23c..9436d0447 100644 --- a/src/cpu_common/x87.h +++ b/src/cpu_common/x87.h @@ -3,8 +3,8 @@ #define C2 (1<<10) #define C3 (1<<14) -uint32_t x87_pc_off,x87_op_off; -uint16_t x87_pc_seg,x87_op_seg; +extern uint32_t x87_pc_off,x87_op_off; +extern uint16_t x87_pc_seg,x87_op_seg; static __inline void x87_set_mmx() { diff --git a/src/cpu_new/codegen_timing_p6.c b/src/cpu_new/codegen_timing_p6.c index a51b4df32..3cb15bf68 100644 --- a/src/cpu_new/codegen_timing_p6.c +++ b/src/cpu_new/codegen_timing_p6.c @@ -16,8 +16,8 @@ typedef enum uop_type_t { - UOP_ALU = 0, /*Executes in Integer X or Y units*/ - UOP_ALUX, /*Executes in Integer X unit*/ + 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*/ @@ -28,11 +28,11 @@ typedef enum uop_type_t 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 Integer X or Y units as MMX*/ - UOP_MMX_SHIFT, /*Executes in Integer Y unit. Uses MMX shifter*/ - UOP_MMX_MUL, /*Executes in Integer X unit. Uses MMX multiplier*/ + 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_LIMM /*Does not require an execution unit*/ + UOP_FXCH /*Does not require an execution unit*/ } uop_type_t; typedef enum decode_type_t @@ -43,46 +43,46 @@ typedef enum decode_type_t #define MAX_UOPS 10 -typedef struct risc86_uop_t +typedef struct p6_uop_t { uop_type_t type; - double latency; -} risc86_uop_t; + int latency; +} p6_uop_t; -typedef struct risc86_instruction_t +typedef struct macro_op_t { int nr_uops; decode_type_t decode_type; - risc86_uop_t uop[MAX_UOPS]; -} risc86_instruction_t; + p6_uop_t uop[MAX_UOPS]; +} macro_op_t; -static const risc86_instruction_t alu_op = +static const macro_op_t alu_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t alux_op = +static const macro_op_t alup0_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1} + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t load_alu_op = +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 risc86_instruction_t load_alux_op = +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_ALUX, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t alu_store_op = +static const macro_op_t alu_store_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -91,38 +91,38 @@ static const risc86_instruction_t alu_store_op = .uop[2] = {.type = UOP_STORED, .latency = 1}, .uop[3] = {.type = UOP_STOREA, .latency = 1} }; -static const risc86_instruction_t alux_store_op = +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_ALUX, .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 risc86_instruction_t branch_op = +static const macro_op_t branch_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_BRANCH, .latency = 1} + .uop[0] = {.type = UOP_BRANCH, .latency = 2} }; -static const risc86_instruction_t limm_op = +static const macro_op_t fxch_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_LIMM, .latency = 1} + .uop[0] = {.type = UOP_FXCH, .latency = 1} }; -static const risc86_instruction_t load_op = +static const macro_op_t load_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, + .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_LOAD, .latency = 1} }; -static const risc86_instruction_t store_op = +static const macro_op_t store_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, @@ -131,14 +131,14 @@ static const risc86_instruction_t store_op = }; -static const risc86_instruction_t bswap_op = +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 risc86_instruction_t leave_op = +static const macro_op_t leave_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -146,27 +146,27 @@ static const risc86_instruction_t leave_op = .uop[1] = {.type = UOP_ALU, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t lods_op = +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 risc86_instruction_t loop_op = +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 = 1} + .uop[1] = {.type = UOP_BRANCH, .latency = 2} }; -static const risc86_instruction_t mov_reg_seg_op = +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 risc86_instruction_t movs_op = +static const macro_op_t movs_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -175,14 +175,14 @@ static const risc86_instruction_t movs_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t pop_reg_op = +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 risc86_instruction_t pop_mem_op = +static const macro_op_t pop_mem_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -191,14 +191,14 @@ static const risc86_instruction_t pop_mem_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t push_imm_op = +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 risc86_instruction_t push_mem_op = +static const macro_op_t push_mem_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -206,7 +206,7 @@ static const risc86_instruction_t push_mem_op = .uop[1] = {.type = UOP_STORED, .latency = 1}, .uop[2] = {.type = UOP_STOREA, .latency = 1} }; -static const risc86_instruction_t push_seg_op = +static const macro_op_t push_seg_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -215,7 +215,7 @@ static const risc86_instruction_t push_seg_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t stos_op = +static const macro_op_t stos_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -223,33 +223,33 @@ static const risc86_instruction_t stos_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t test_reg_op = -{ - .nr_uops = 1, - .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALU, .latency = 1} -}; -static const risc86_instruction_t test_reg_b_op = +static const macro_op_t test_reg_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t test_mem_imm_op = +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 risc86_instruction_t test_mem_imm_b_op = +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_ALUX, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t xchg_op = +static const macro_op_t xchg_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -259,98 +259,98 @@ static const risc86_instruction_t xchg_op = }; -static const risc86_instruction_t mmx_op = +static const macro_op_t mmx_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX, .latency = 1.5} + .uop[0] = {.type = UOP_MMX, .latency = 1} }; -static const risc86_instruction_t mmx_mul_op = +static const macro_op_t mmx_mul_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_MUL, .latency = 1.5} + .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} }; -static const risc86_instruction_t mmx_shift_op = +static const macro_op_t mmx_shift_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_SHIFT, .latency = 1.5} + .uop[0] = {.type = UOP_MMX_SHIFT, .latency = 1} }; -static const risc86_instruction_t load_mmx_op = +static const macro_op_t load_mmx_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_MMX, .latency = 1.5} + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = {.type = UOP_MMX, .latency = 2} }; -static const risc86_instruction_t load_mmx_mul_op = +static const macro_op_t load_mmx_mul_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_MMX_MUL, .latency = 1.5} + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = {.type = UOP_MMX_MUL, .latency = 2} }; -static const risc86_instruction_t load_mmx_shift_op = +static const macro_op_t load_mmx_shift_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_MMX_SHIFT, .latency = 1.5} + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = {.type = UOP_MMX_SHIFT, .latency = 2} }; -static const risc86_instruction_t mload_op = +static const macro_op_t mload_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_MLOAD, .latency = 3}, + .uop[0] = {.type = UOP_MLOAD, .latency = 1}, }; -static const risc86_instruction_t mstore_op = +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 risc86_instruction_t pmul_op = +static const macro_op_t pmul_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_MMX_MUL, .latency = 1.5} + .uop[0] = {.type = UOP_MMX_MUL, .latency = 1} }; -static const risc86_instruction_t pmul_mem_op = +static const macro_op_t pmul_mem_op = { .nr_uops = 2, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_MMX_MUL, .latency = 1.5} + .uop[0] = {.type = UOP_LOAD, .latency = 2}, + .uop[1] = {.type = UOP_MMX_MUL, .latency = 2} }; -static const risc86_instruction_t float_op = +static const macro_op_t float_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_FLOAT, .latency = 1} }; -static const risc86_instruction_t fadd_op = +static const macro_op_t fadd_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_FLOAT, .latency = 3} + .uop[0] = {.type = UOP_FLOAT, .latency = 2} }; -static const risc86_instruction_t fmul_op = +static const macro_op_t fmul_op = { .nr_uops = 1, .decode_type = DECODE_SIMPLE, - .uop[0] = {.type = UOP_ALU, .latency = 5} + .uop[0] = {.type = UOP_ALUP0, .latency = 3} }; -static const risc86_instruction_t float2_op = +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 risc86_instruction_t fchs_op = +static const macro_op_t fchs_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -358,35 +358,35 @@ static const risc86_instruction_t fchs_op = .uop[1] = {.type = UOP_FLOAT, .latency = 2}, .uop[2] = {.type = UOP_FLOAT, .latency = 2} }; -static const risc86_instruction_t load_float_op = +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 risc86_instruction_t load_fadd_op = +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 = 3} + .uop[1] = {.type = UOP_FLOAT, .latency = 2} }; -static const risc86_instruction_t load_fmul_op = +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 = 5} + .uop[1] = {.type = UOP_ALU, .latency = 4} }; -static const risc86_instruction_t fstore_op = +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 risc86_instruction_t load_fiadd_op = +static const macro_op_t load_fiadd_op = { .nr_uops = 7, .decode_type = DECODE_COMPLEX, @@ -398,51 +398,51 @@ static const risc86_instruction_t load_fiadd_op = .uop[5] = {.type = UOP_FLOAT, .latency = 1}, .uop[6] = {.type = UOP_FLOAT, .latency = 1} }; -static const risc86_instruction_t fdiv_op = +static const macro_op_t fdiv_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 32} + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 37} }; -static const risc86_instruction_t fdiv_mem_op = +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 = 38} + .uop[1] = {.type = UOP_FLOAT, .latency = 37} }; -static const risc86_instruction_t fsin_op = +static const macro_op_t fsin_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_FLOAT, .latency = 60} + .decode_type = DECODE_SIMPLE, + .uop[0] = {.type = UOP_FLOAT, .latency = 62} }; -static const risc86_instruction_t fsqrt_op = +static const macro_op_t fsqrt_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, + .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_FLOAT, .latency = 69} }; -static const risc86_instruction_t complex_fldcw_op = +static const macro_op_t fldcw_op = { .nr_uops = 1, - .decode_type = DECODE_COMPLEX, + .decode_type = DECODE_SIMPLE, .uop[0] = {.type = UOP_FLOAT, .latency = 10} }; -static const risc86_instruction_t complex_float_op = +static const macro_op_t complex_float_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_FLOAT, .latency = 1} }; -static const risc86_instruction_t complex_float_l_op = +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 risc86_instruction_t complex_flde_op = +static const macro_op_t flde_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -450,7 +450,7 @@ static const risc86_instruction_t complex_flde_op = .uop[1] = {.type = UOP_FLOAD, .latency = 1}, .uop[2] = {.type = UOP_FLOAT, .latency = 2} }; -static const risc86_instruction_t complex_fste_op = +static const macro_op_t fste_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -459,20 +459,20 @@ static const risc86_instruction_t complex_fste_op = .uop[2] = {.type = UOP_FSTOREA, .latency = 1} }; -static const risc86_instruction_t complex_alu1_op = +static const macro_op_t complex_alu1_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_alu2_op = +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 risc86_instruction_t complex_alu3_op = +static const macro_op_t alu3_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -480,7 +480,7 @@ static const risc86_instruction_t complex_alu3_op = .uop[1] = {.type = UOP_ALU, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_alu6_op = +static const macro_op_t alu6_op = { .nr_uops = 6, .decode_type = DECODE_COMPLEX, @@ -491,57 +491,39 @@ static const risc86_instruction_t complex_alu6_op = .uop[4] = {.type = UOP_ALU, .latency = 1}, .uop[5] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_alux1_op = +static const macro_op_t complex_alup0_1_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_alux3_op = +static const macro_op_t alup0_3_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1}, + .uop[2] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_alux6_op = +static const macro_op_t alup0_6_op = { .nr_uops = 6, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .latency = 1}, - .uop[4] = {.type = UOP_ALUX, .latency = 1}, - .uop[5] = {.type = UOP_ALUX, .latency = 1} + .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 risc86_instruction_t complex_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 risc86_instruction_t complex_alux_store_op = -{ - .nr_uops = 4, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} -}; -static const risc86_instruction_t complex_arpl_op = +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 risc86_instruction_t complex_bound_op = +static const macro_op_t bound_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -550,13 +532,13 @@ static const risc86_instruction_t complex_bound_op = .uop[2] = {.type = UOP_ALU, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_bsx_op = +static const macro_op_t bsx_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 10} }; -static const risc86_instruction_t complex_call_far_op = +static const macro_op_t call_far_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -565,13 +547,13 @@ static const risc86_instruction_t complex_call_far_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_BRANCH, .latency = 1} }; -static const risc86_instruction_t complex_cli_sti_op = +static const macro_op_t cli_sti_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 7} }; -static const risc86_instruction_t complex_cmps_op = +static const macro_op_t cmps_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -579,15 +561,15 @@ static const risc86_instruction_t complex_cmps_op = .uop[1] = {.type = UOP_ALU, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_cmpsb_op = +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_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_cmpxchg_op = +static const macro_op_t cmpxchg_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -596,54 +578,62 @@ static const risc86_instruction_t complex_cmpxchg_op = .uop[2] = {.type = UOP_STORED, .latency = 1}, .uop[3] = {.type = UOP_STOREA, .latency = 1} }; -static const risc86_instruction_t complex_cmpxchg_b_op = +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_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_STORED, .latency = 1}, - .uop[3] = {.type = UOP_STOREA, .latency = 1} + .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 risc86_instruction_t complex_cpuid_op = +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 risc86_instruction_t complex_div16_op = +static const macro_op_t div16_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 10} + .uop[0] = {.type = UOP_ALUP0, .latency = 21} }; -static const risc86_instruction_t complex_div16_mem_op = +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_ALUX, .latency = 10} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 21} }; -static const risc86_instruction_t complex_div32_op = +static const macro_op_t div32_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 18} + .uop[0] = {.type = UOP_ALUP0, .latency = 37} }; -static const risc86_instruction_t complex_div32_mem_op = +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_ALUX, .latency = 18} + .uop[1] = {.type = UOP_ALUP0, .latency = 37} }; -static const risc86_instruction_t complex_emms_op = +static const macro_op_t emms_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 25} + .uop[0] = {.type = UOP_ALU, .latency = 50} }; -static const risc86_instruction_t complex_enter_op = +static const macro_op_t enter_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -651,28 +641,28 @@ static const risc86_instruction_t complex_enter_op = .uop[1] = {.type = UOP_STOREA, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 10} }; -static const risc86_instruction_t complex_femms_op = +static const macro_op_t femms_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 6} }; -static const risc86_instruction_t complex_in_op = +static const macro_op_t in_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 10} + .uop[0] = {.type = UOP_LOAD, .latency = 18} }; -static const risc86_instruction_t complex_ins_op = +static const macro_op_t ins_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 10}, + .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 risc86_instruction_t complex_int_op = +static const macro_op_t int_op = { .nr_uops = 8, .decode_type = DECODE_COMPLEX, @@ -685,7 +675,7 @@ static const risc86_instruction_t complex_int_op = .uop[6] = {.type = UOP_STOREA, .latency = 1}, .uop[7] = {.type = UOP_BRANCH, .latency = 1} }; -static const risc86_instruction_t complex_iret_op = +static const macro_op_t iret_op = { .nr_uops = 5, .decode_type = DECODE_COMPLEX, @@ -695,41 +685,20 @@ static const risc86_instruction_t complex_iret_op = .uop[3] = {.type = UOP_ALU, .latency = 20}, .uop[4] = {.type = UOP_BRANCH, .latency = 1} }; -static const risc86_instruction_t complex_invd_op = +static const macro_op_t invd_op = { .nr_uops = 1, .decode_type = DECODE_COMPLEX, .uop[0] = {.type = UOP_ALU, .latency = 500} }; -static const risc86_instruction_t complex_jmp_far_op = +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 risc86_instruction_t complex_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 risc86_instruction_t complex_load_alux_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1} -}; -static const risc86_instruction_t complex_loop_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALU, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .latency = 1} -}; -static const risc86_instruction_t complex_lss_op = +static const macro_op_t lss_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -737,7 +706,7 @@ static const risc86_instruction_t complex_lss_op = .uop[1] = {.type = UOP_LOAD, .latency = 1}, .uop[2] = {.type = UOP_ALU, .latency = 3} }; -static const risc86_instruction_t complex_mov_mem_seg_op = +static const macro_op_t mov_mem_seg_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -745,68 +714,63 @@ static const risc86_instruction_t complex_mov_mem_seg_op = .uop[1] = {.type = UOP_STORED, .latency = 1}, .uop[2] = {.type = UOP_STOREA, .latency = 1}, }; -static const risc86_instruction_t complex_mov_seg_mem_op = +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 risc86_instruction_t complex_mov_seg_reg_op = +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 risc86_instruction_t complex_mul_op = +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_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_mul_mem_op = +static const macro_op_t mul64_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1} + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1}, + .uop[2] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_mul64_op = -{ - .nr_uops = 3, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1} -}; -static const risc86_instruction_t complex_mul64_mem_op = +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_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .latency = 1} + .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 risc86_instruction_t complex_out_op = +static const macro_op_t out_op = { - .nr_uops = 2, + .nr_uops = 1, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_STORED, .latency = 10}, - .uop[1] = {.type = UOP_STOREA, .latency = 10}, + .uop[0] = {.type = UOP_ALU, .latency = 18} }; -static const risc86_instruction_t complex_outs_op = +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_STORED, .latency = 10}, - .uop[1] = {.type = UOP_STOREA, .latency = 10}, - .uop[2] = {.type = UOP_ALU, .latency = 1} + .uop[1] = {.type = UOP_ALU, .latency = 18} }; -static const risc86_instruction_t complex_pusha_op = +static const macro_op_t pusha_op = { .nr_uops = 8, .decode_type = DECODE_COMPLEX, @@ -819,7 +783,7 @@ static const risc86_instruction_t complex_pusha_op = .uop[6] = {.type = UOP_STORED, .latency = 2}, .uop[7] = {.type = UOP_STOREA, .latency = 2} }; -static const risc86_instruction_t complex_popa_op = +static const macro_op_t popa_op = { .nr_uops = 8, .decode_type = DECODE_COMPLEX, @@ -832,36 +796,30 @@ static const risc86_instruction_t complex_popa_op = .uop[6] = {.type = UOP_LOAD, .latency = 1}, .uop[7] = {.type = UOP_LOAD, .latency = 1} }; -static const risc86_instruction_t complex_popf_op = -{ - .nr_uops = 2, - .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_LOAD, .latency = 3}, - .uop[1] = {.type = UOP_ALUX, .latency = 17} -}; -static const risc86_instruction_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 risc86_instruction_t complex_pushf_op = +static const macro_op_t popf_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_STORED, .latency = 1}, - .uop[2] = {.type = UOP_STOREA, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .latency = 6}, + .uop[2] = {.type = UOP_ALUP0, .latency = 10} }; -static const risc86_instruction_t complex_ret_op = +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 risc86_instruction_t complex_retf_op = +static const macro_op_t retf_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, @@ -869,52 +827,52 @@ static const risc86_instruction_t complex_retf_op = .uop[1] = {.type = UOP_ALU, .latency = 3}, .uop[2] = {.type = UOP_BRANCH, .latency = 1} }; -static const risc86_instruction_t complex_scas_op = +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 risc86_instruction_t complex_scasb_op = +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 risc86_instruction_t complex_setcc_mem_op = +static const macro_op_t setcc_mem_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_FSTORED, .latency = 1}, - .uop[3] = {.type = UOP_FSTOREA, .latency = 1} + .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 risc86_instruction_t complex_setcc_reg_op = +static const macro_op_t setcc_reg_op = { .nr_uops = 3, .decode_type = DECODE_COMPLEX, - .uop[0] = {.type = UOP_ALUX, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .latency = 1} + .uop[0] = {.type = UOP_ALUP0, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_test_mem_op = +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 risc86_instruction_t complex_test_mem_b_op = +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_ALUX, .latency = 1} + .uop[0] = {.type = UOP_LOAD, .latency = 1}, + .uop[1] = {.type = UOP_ALUP0, .latency = 1} }; -static const risc86_instruction_t complex_xchg_mem_op = +static const macro_op_t xchg_mem_op = { .nr_uops = 4, .decode_type = DECODE_COMPLEX, @@ -923,60 +881,58 @@ static const risc86_instruction_t complex_xchg_mem_op = .uop[2] = {.type = UOP_STOREA, .latency = 1}, .uop[3] = {.type = UOP_ALU, .latency = 1} }; -static const risc86_instruction_t complex_xlat_op = +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 risc86_instruction_t complex_wbinvd_op = +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 risc86_instruction_t *opcode_timings[256] = +static const macro_op_t *opcode_timings[256] = { /* ADD ADD ADD ADD*/ -/*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/*00*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* ADD ADD PUSH ES POP ES*/ - &alux_op, &alu_op, &push_seg_op, &complex_mov_seg_mem_op, + &alup0_op, &alu_op, &push_seg_op, &mov_seg_mem_op, /* OR OR OR OR*/ - &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, + &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* OR OR PUSH CS */ - &alux_op, &alu_op, &push_seg_op, INVALID, + &alup0_op, &alu_op, &push_seg_op, INVALID, /* ADC ADC ADC ADC*/ -/*10*/ &complex_alux_store_op,&complex_alu_store_op, &complex_load_alux_op,&complex_load_alu_op, +/*10*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* ADC ADC PUSH SS POP SS*/ - &complex_alux1_op, &complex_alu1_op, &push_seg_op, &complex_mov_seg_mem_op, + &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, /* SBB SBB SBB SBB*/ -/*10*/ &complex_alux_store_op,&complex_alu_store_op, &complex_load_alux_op,&complex_load_alu_op, +/*10*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* SBB SBB PUSH DS POP DS*/ - &complex_alux1_op, &complex_alu1_op, &push_seg_op, &complex_mov_seg_mem_op, + &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, /* AND AND AND AND*/ -/*20*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/*20*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* AND AND DAA*/ - &alux_op, &alu_op, INVALID, &complex_alux1_op, + &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, /* SUB SUB SUB SUB*/ - &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, + &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* SUB SUB DAS*/ - &alux_op, &alu_op, INVALID, &complex_alux1_op, + &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, /* XOR XOR XOR XOR*/ -/*30*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/*30*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, /* XOR XOR AAA*/ - &alux_op, &alu_op, INVALID, &complex_alux6_op, + &alup0_op, &alu_op, INVALID, &alup0_6_op, /* CMP CMP CMP CMP*/ - &load_alux_op, &load_alu_op, &load_alux_op, &load_alu_op, + &load_alup0_op, &load_alu_op, &load_alup0_op, &load_alu_op, /* CMP CMP AAS*/ - &alux_op, &alu_op, INVALID, &complex_alux6_op, + &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, @@ -997,12 +953,12 @@ static const risc86_instruction_t *opcode_timings[256] = &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, /* PUSHA POPA BOUND ARPL*/ -/*60*/ &complex_pusha_op, &complex_popa_op, &complex_bound_op, &complex_arpl_op, +/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, INVALID, INVALID, INVALID, INVALID, /* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &complex_mul_op, &push_imm_op, &complex_mul_op, + &push_imm_op, &mul_op, &push_imm_op, &mul_op, /* INSB INSW OUTSB OUTSW*/ - &complex_ins_op, &complex_ins_op, &complex_outs_op, &complex_outs_op, + &ins_op, &ins_op, &outs_op, &outs_op, /* Jxx*/ /*70*/ &branch_op, &branch_op, &branch_op, &branch_op, @@ -1012,107 +968,107 @@ static const risc86_instruction_t *opcode_timings[256] = /*80*/ INVALID, INVALID, INVALID, INVALID, /* TEST TEST XCHG XCHG*/ - &complex_test_mem_b_op, &complex_test_mem_op, &complex_xchg_mem_op, &complex_xchg_mem_op, + &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*/ - &complex_mov_mem_seg_op, &store_op, &complex_mov_seg_mem_op, &pop_mem_op, + &mov_mem_seg_op, &store_op, &mov_seg_mem_op, &pop_mem_op, /* NOP XCHG XCHG XCHG*/ -/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, +/*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, &complex_call_far_op, &limm_op, + &complex_alu1_op, &complex_alu1_op, &call_far_op, &fxch_op, /* PUSHF POPF SAHF LAHF*/ - &complex_pushf_op, &complex_popf_op, &complex_alux1_op, &complex_alux1_op, + &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, &complex_cmpsb_op, &complex_cmps_op, + &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, &complex_scasb_op, &complex_scas_op, + &lods_op, &lods_op, &scasb_op, &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, +/*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, &complex_ret_op, &complex_ret_op, +/*c0*/ INVALID, INVALID, &ret_op, &ret_op, /* LES LDS MOV MOV*/ - &complex_lss_op, &complex_lss_op, &store_op, &store_op, + &lss_op, &lss_op, &store_op, &store_op, /* ENTER LEAVE RETF RETF*/ - &complex_enter_op, &leave_op, &complex_retf_op, &complex_retf_op, + &enter_op, &leave_op, &retf_op, &retf_op, /* INT3 INT INTO IRET*/ - &complex_int_op, &complex_int_op, &complex_int_op, &complex_iret_op, + &int_op, &int_op, &int_op, &iret_op, /*d0*/ INVALID, INVALID, INVALID, INVALID, /* AAM AAD SETALC XLAT*/ - &complex_alux6_op, &complex_alux3_op, &complex_alux1_op, &complex_xlat_op, + &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*/ &complex_loop_op, &complex_loop_op, &loop_op, &complex_loop_op, +/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, /* IN AL IN AX OUT_AL OUT_AX*/ - &complex_in_op, &complex_in_op, &complex_out_op, &complex_out_op, + &in_op, &in_op, &out_op, &out_op, /* CALL JMP JMP JMP*/ - &store_op, &branch_op, &complex_jmp_far_op, &branch_op, + &store_op, &branch_op, &jmp_far_op, &branch_op, /* IN AL IN AX OUT_AL OUT_AX*/ - &complex_in_op, &complex_in_op, &complex_out_op, &complex_out_op, + &in_op, &in_op, &out_op, &out_op, /* REPNE REPE*/ /*f0*/ INVALID, INVALID, INVALID, INVALID, /* HLT CMC*/ - &complex_alux1_op, &complex_alu2_op, INVALID, INVALID, + &complex_alup0_1_op, &alu2_op, INVALID, INVALID, /* CLC STC CLI STI*/ - &complex_alu1_op, &complex_alu1_op, &complex_cli_sti_op, &complex_cli_sti_op, + &complex_alu1_op, &complex_alu1_op, &cli_sti_op, &cli_sti_op, /* CLD STD INCDEC*/ - &complex_alu1_op, &complex_alu1_op, &alux_store_op, INVALID + &complex_alu1_op, &complex_alu1_op, &alup0_store_op, INVALID }; -static const risc86_instruction_t *opcode_timings_mod3[256] = +static const macro_op_t *opcode_timings_mod3[256] = { /* ADD ADD ADD ADD*/ -/*00*/ &alux_op, &alu_op, &alux_op, &alu_op, +/*00*/ &alup0_op, &alu_op, &alup0_op, &alu_op, /* ADD ADD PUSH ES POP ES*/ - &alux_op, &alu_op, &push_seg_op, &complex_mov_seg_mem_op, + &alup0_op, &alu_op, &push_seg_op, &mov_seg_mem_op, /* OR OR OR OR*/ - &alux_op, &alu_op, &alux_op, &alu_op, + &alup0_op, &alu_op, &alup0_op, &alu_op, /* OR OR PUSH CS */ - &alux_op, &alu_op, &push_seg_op, INVALID, + &alup0_op, &alu_op, &push_seg_op, INVALID, /* ADC ADC ADC ADC*/ -/*10*/ &complex_alux1_op, &complex_alu1_op, &complex_alux1_op, &complex_alu1_op, +/*10*/ &complex_alup0_1_op, &complex_alu1_op, &complex_alup0_1_op, &complex_alu1_op, /* ADC ADC PUSH SS POP SS*/ - &complex_alux1_op, &complex_alu1_op, &push_seg_op, &complex_mov_seg_mem_op, + &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, /* SBB SBB SBB SBB*/ - &complex_alux1_op, &complex_alu1_op, &complex_alux1_op, &complex_alu1_op, + &complex_alup0_1_op, &complex_alu1_op, &complex_alup0_1_op, &complex_alu1_op, /* SBB SBB PUSH DS POP DS*/ - &complex_alux1_op, &complex_alu1_op, &push_seg_op, &complex_mov_seg_mem_op, + &complex_alup0_1_op, &complex_alu1_op, &push_seg_op, &mov_seg_mem_op, /* AND AND AND AND*/ -/*20*/ &alux_op, &alu_op, &alux_op, &alu_op, +/*20*/ &alup0_op, &alu_op, &alup0_op, &alu_op, /* AND AND DAA*/ - &alux_op, &alu_op, INVALID, &complex_alux1_op, + &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, /* SUB SUB SUB SUB*/ - &alux_op, &alu_op, &alux_op, &alu_op, + &alup0_op, &alu_op, &alup0_op, &alu_op, /* SUB SUB DAS*/ - &alux_op, &alu_op, INVALID, &complex_alux1_op, + &alup0_op, &alu_op, INVALID, &complex_alup0_1_op, /* XOR XOR XOR XOR*/ -/*30*/ &alux_op, &alu_op, &alux_op, &alu_op, +/*30*/ &alup0_op, &alu_op, &alup0_op, &alu_op, /* XOR XOR AAA*/ - &alux_op, &alu_op, INVALID, &complex_alux6_op, + &alup0_op, &alu_op, INVALID, &alup0_6_op, /* CMP CMP CMP CMP*/ - &alux_op, &alu_op, &alux_op, &alu_op, + &alup0_op, &alu_op, &alup0_op, &alu_op, /* CMP CMP AAS*/ - &alux_op, &alu_op, INVALID, &complex_alux6_op, + &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, @@ -1133,12 +1089,12 @@ static const risc86_instruction_t *opcode_timings_mod3[256] = &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, /* PUSHA POPA BOUND ARPL*/ -/*60*/ &complex_pusha_op, &complex_popa_op, &complex_bound_op, &complex_arpl_op, +/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, INVALID, INVALID, INVALID, INVALID, /* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &complex_mul_op, &push_imm_op, &complex_mul_op, + &push_imm_op, &mul_op, &push_imm_op, &mul_op, /* INSB INSW OUTSB OUTSW*/ - &complex_ins_op, &complex_ins_op, &complex_outs_op, &complex_outs_op, + &ins_op, &ins_op, &outs_op, &outs_op, /* Jxx*/ /*70*/ &branch_op, &branch_op, &branch_op, &branch_op, @@ -1148,88 +1104,89 @@ static const risc86_instruction_t *opcode_timings_mod3[256] = /*80*/ INVALID, INVALID, INVALID, INVALID, /* TEST TEST XCHG XCHG*/ - &complex_alu1_op, &complex_alu1_op, &complex_alu3_op, &complex_alu3_op, + &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, &complex_mov_seg_reg_op, &pop_reg_op, + &mov_reg_seg_op, &store_op, &mov_seg_reg_op, &pop_reg_op, /* NOP XCHG XCHG XCHG*/ -/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, +/*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, &complex_call_far_op, &limm_op, + &complex_alu1_op, &complex_alu1_op, &call_far_op, &fxch_op, /* PUSHF POPF SAHF LAHF*/ - &complex_pushf_op, &complex_popf_op, &complex_alux1_op, &complex_alux1_op, + &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, &complex_cmpsb_op, &complex_cmps_op, + &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, &complex_scasb_op, &complex_scas_op, + &lods_op, &lods_op, &scasb_op, &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, +/*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, &complex_ret_op, &complex_ret_op, +/*c0*/ INVALID, INVALID, &ret_op, &ret_op, /* LES LDS MOV MOV*/ - &complex_lss_op, &complex_lss_op, &store_op, &store_op, + &lss_op, &lss_op, &store_op, &store_op, /* ENTER LEAVE RETF RETF*/ - &complex_enter_op, &leave_op, &complex_retf_op, &complex_retf_op, + &enter_op, &leave_op, &retf_op, &retf_op, /* INT3 INT INTO IRET*/ - &complex_int_op, &complex_int_op, &complex_int_op, &complex_iret_op, + &int_op, &int_op, &int_op, &iret_op, /*d0*/ INVALID, INVALID, INVALID, INVALID, /* AAM AAD SETALC XLAT*/ - &complex_alux6_op, &complex_alux3_op, &complex_alux1_op, &complex_xlat_op, + &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*/ &complex_loop_op, &complex_loop_op, &loop_op, &complex_loop_op, +/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, /* IN AL IN AX OUT_AL OUT_AX*/ - &complex_in_op, &complex_in_op, &complex_out_op, &complex_out_op, + &in_op, &in_op, &out_op, &out_op, /* CALL JMP JMP JMP*/ - &store_op, &branch_op, &complex_jmp_far_op, &branch_op, + &store_op, &branch_op, &jmp_far_op, &branch_op, /* IN AL IN AX OUT_AL OUT_AX*/ - &complex_in_op, &complex_in_op, &complex_out_op, &complex_out_op, + &in_op, &in_op, &out_op, &out_op, /* REPNE REPE*/ /*f0*/ INVALID, INVALID, INVALID, INVALID, /* HLT CMC*/ - &complex_alux1_op, &complex_alu2_op, INVALID, INVALID, + &complex_alup0_1_op, &alu2_op, INVALID, INVALID, /* CLC STC CLI STI*/ - &complex_alu1_op, &complex_alu1_op, &complex_cli_sti_op, &complex_cli_sti_op, + &complex_alu1_op, &complex_alu1_op, &cli_sti_op, &cli_sti_op, /* CLD STD INCDEC*/ - &complex_alu1_op, &complex_alu1_op, &complex_alux1_op, INVALID + &complex_alu1_op, &complex_alu1_op, &complex_alup0_1_op, INVALID }; -static const risc86_instruction_t *opcode_timings_0f[256] = +static const macro_op_t *opcode_timings_0f[256] = { -/*00*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, - INVALID, &complex_alu6_op, &complex_alu6_op, INVALID, - &complex_invd_op, &complex_wbinvd_op, INVALID, INVALID, - INVALID, &load_op, &complex_femms_op, INVALID, +/*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*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, - &complex_alu6_op, &complex_alu6_op, 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*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, INVALID, +/*30*/ &alu6_op, &alu6_op, &alu6_op, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1250,7 +1207,7 @@ static const risc86_instruction_t *opcode_timings_0f[256] = 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, &complex_emms_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &emms_op, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, &mstore_op, &mstore_op, @@ -1259,23 +1216,23 @@ static const risc86_instruction_t *opcode_timings_0f[256] = &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, -/*90*/ &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, - &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, - &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, - &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_op, &complex_setcc_reg_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, &complex_mov_seg_mem_op,&complex_cpuid_op, &complex_load_alu_op, - &complex_alu_store_op, &complex_alu_store_op, INVALID, INVALID, - &push_seg_op, &complex_mov_seg_mem_op,INVALID, &complex_load_alu_op, - &complex_alu_store_op, &complex_alu_store_op, INVALID, &complex_mul_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*/ &complex_cmpxchg_b_op, &complex_cmpxchg_op, &complex_lss_op, &complex_load_alu_op, - &complex_lss_op, &complex_lss_op, &load_alux_op, &load_alu_op, - INVALID, INVALID, &complex_load_alu_op, &complex_load_alu_op, - &complex_bsx_op, &complex_bsx_op, &load_alux_op, &load_alu_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*/ &complex_alux_store_op, &complex_alu_store_op, INVALID, INVALID, - INVALID, INVALID, INVALID, &complex_cmpxchg_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, @@ -1294,182 +1251,182 @@ static const risc86_instruction_t *opcode_timings_0f[256] = &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] = +static const macro_op_t *opcode_timings_0f_mod3[256] = { -/*00*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, - INVALID, &complex_alu6_op, &complex_alu6_op, INVALID, - &complex_invd_op, &complex_wbinvd_op, INVALID, INVALID, - INVALID, INVALID, &complex_femms_op, INVALID, +/*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*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, - &complex_alu6_op, &complex_alu6_op, 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*/ &complex_alu6_op, &complex_alu6_op, &complex_alu6_op, INVALID, - INVALID, INVALID, 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, +/*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, +/*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, +/*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, &complex_emms_op, - INVALID, INVALID, INVALID, INVALID, - 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*/ &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, - &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, - &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, - &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_op, &complex_setcc_mem_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, &complex_mov_seg_mem_op, &complex_cpuid_op, &complex_alu1_op, - &complex_alu1_op, &complex_alu1_op, INVALID, INVALID, - &push_seg_op, &complex_mov_seg_mem_op, INVALID, &complex_alu1_op, - &complex_alu1_op, &complex_alu1_op, INVALID, &complex_mul_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*/ &complex_cmpxchg_b_op, &complex_cmpxchg_op, &complex_lss_op, &complex_alu1_op, - &complex_lss_op, &complex_lss_op, &alux_op, &alu_op, - INVALID, INVALID, &complex_alu1_op, &complex_alu1_op, - &complex_bsx_op, &complex_bsx_op, &alux_op, &alu_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_alux1_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, +/*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, +/*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, +/*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, +/*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_shift[8] = +static const macro_op_t *opcode_timings_shift[8] = { - &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, - &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op + &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 risc86_instruction_t *opcode_timings_shift_b[8] = +static const macro_op_t *opcode_timings_shift_b[8] = { - &complex_alux_store_op, &complex_alux_store_op, &complex_alux_store_op, &complex_alux_store_op, - &complex_alux_store_op, &complex_alux_store_op, &complex_alux_store_op, &complex_alux_store_op + &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 risc86_instruction_t *opcode_timings_shift_mod3[8] = +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 risc86_instruction_t *opcode_timings_shift_b_mod3[8] = +static const macro_op_t *opcode_timings_shift_b_mod3[8] = { - &complex_alux1_op, &complex_alux1_op, &complex_alux1_op, &complex_alux1_op, - &alux_op, &alux_op, &alux_op, &alux_op + &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 risc86_instruction_t *opcode_timings_80[8] = +static const macro_op_t *opcode_timings_80[8] = { - &alux_store_op, &alux_store_op, &complex_alux_store_op, &complex_alux_store_op, - &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, + &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 risc86_instruction_t *opcode_timings_80_mod3[8] = +static const macro_op_t *opcode_timings_80_mod3[8] = { - &alux_op, &alux_op, &alux_store_op, &alux_store_op, - &alux_op, &alux_op, &alux_op, &alux_op, + &alup0_op, &alup0_op, &alup0_store_op, &alup0_store_op, + &alup0_op, &alup0_op, &alup0_op, &alup0_op, }; -static const risc86_instruction_t *opcode_timings_8x[8] = +static const macro_op_t *opcode_timings_8x[8] = { - &alu_store_op, &alu_store_op, &complex_alu_store_op, &complex_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_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, + &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] = +static const macro_op_t *opcode_timings_f6[8] = { /* TST NOT NEG*/ - &test_mem_imm_b_op, INVALID, &complex_alux_store_op, &complex_alux_store_op, + &test_mem_imm_b_op, INVALID, &alup0_store_op, &alup0_store_op, /* MUL IMUL DIV IDIV*/ - &complex_mul_mem_op, &complex_mul_mem_op, &complex_div16_mem_op, &complex_div16_mem_op, + &mul_mem_op, &mul_mem_op, &div16_mem_op, &div16_mem_op, }; -static const risc86_instruction_t *opcode_timings_f6_mod3[8] = +static const macro_op_t *opcode_timings_f6_mod3[8] = { /* TST NOT NEG*/ - &test_reg_b_op, INVALID, &alux_op, &alux_op, + &test_reg_b_op, INVALID, &alup0_op, &alup0_op, /* MUL IMUL DIV IDIV*/ - &complex_mul_op, &complex_mul_op, &complex_div16_op, &complex_div16_op, + &mul_op, &mul_op, &div16_op, &div16_op, }; -static const risc86_instruction_t *opcode_timings_f7[8] = +static const macro_op_t *opcode_timings_f7[8] = { /* TST NOT NEG*/ - &test_mem_imm_op, INVALID, &complex_alu_store_op, &complex_alu_store_op, + &test_mem_imm_op, INVALID, &alu_store_op, &alu_store_op, /* MUL IMUL DIV IDIV*/ - &complex_mul64_mem_op, &complex_mul64_mem_op, &complex_div32_mem_op, &complex_div32_mem_op, + &mul64_mem_op, &mul64_mem_op, &div32_mem_op, &div32_mem_op, }; -static const risc86_instruction_t *opcode_timings_f7_mod3[8] = +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*/ - &complex_mul64_op, &complex_mul64_op, &complex_div32_op, &complex_div32_op, + &mul64_op, &mul64_op, &div32_op, &div32_op, }; -static const risc86_instruction_t *opcode_timings_ff[8] = +static const macro_op_t *opcode_timings_ff[8] = { /* INC DEC CALL CALL far*/ - &alu_store_op, &alu_store_op, &store_op, &complex_call_far_op, + &alu_store_op, &alu_store_op, &store_op, &call_far_op, /* JMP JMP far PUSH*/ - &branch_op, &complex_jmp_far_op, &push_mem_op, INVALID + &branch_op, &jmp_far_op, &push_mem_op, INVALID }; -static const risc86_instruction_t *opcode_timings_ff_mod3[8] = +static const macro_op_t *opcode_timings_ff_mod3[8] = { /* INC DEC CALL CALL far*/ - &complex_alu1_op, &complex_alu1_op, &store_op, &complex_call_far_op, + &complex_alu1_op, &complex_alu1_op, &store_op, &call_far_op, /* JMP JMP far PUSH*/ - &branch_op, &complex_jmp_far_op, &complex_push_mem_op, INVALID + &branch_op, &jmp_far_op, &complex_push_mem_op, INVALID }; -static const risc86_instruction_t *opcode_timings_d8[8] = +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 risc86_instruction_t *opcode_timings_d8_mod3[8] = +static const macro_op_t *opcode_timings_d8_mod3[8] = { /* FADD FMUL FCOM FCOMP*/ &fadd_op, &fmul_op, &float_op, &float_op, @@ -1477,27 +1434,27 @@ static const risc86_instruction_t *opcode_timings_d8_mod3[8] = &float_op, &float_op, &fdiv_op, &fdiv_op, }; -static const risc86_instruction_t *opcode_timings_d9[8] = +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, &complex_fldcw_op, &complex_float_l_op, &complex_float_op + &complex_float_l_op, &fldcw_op, &complex_float_l_op, &complex_float_op }; -static const risc86_instruction_t *opcode_timings_d9_mod3[64] = +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*/ - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, + &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, + &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*/ @@ -1516,28 +1473,28 @@ static const risc86_instruction_t *opcode_timings_d9_mod3[64] = &float_op, &fdiv_op, &fsin_op, &fsin_op }; -static const risc86_instruction_t *opcode_timings_da[8] = +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 risc86_instruction_t *opcode_timings_da_mod3[8] = +static const macro_op_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] = +static const macro_op_t *opcode_timings_db[8] = { /* FLDil FSTil FSTPil*/ &load_float_op, INVALID, &fstore_op, &fstore_op, /* FLDe FSTPe*/ - INVALID, &complex_flde_op, INVALID, &complex_fste_op + INVALID, &flde_op, INVALID, &fste_op }; -static const risc86_instruction_t *opcode_timings_db_mod3[64] = +static const macro_op_t *opcode_timings_db_mod3[64] = { INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1566,14 +1523,14 @@ static const risc86_instruction_t *opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, }; -static const risc86_instruction_t *opcode_timings_dc[8] = +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 risc86_instruction_t *opcode_timings_dc_mod3[8] = +static const macro_op_t *opcode_timings_dc_mod3[8] = { /* opFADDr opFMULr*/ &fadd_op, &fmul_op, INVALID, INVALID, @@ -1581,14 +1538,14 @@ static const risc86_instruction_t *opcode_timings_dc_mod3[8] = &float_op, &float_op, &fdiv_op, &fdiv_op }; -static const risc86_instruction_t *opcode_timings_dd[8] = +static const macro_op_t *opcode_timings_dd[8] = { /* FLDd FSTd FSTPd*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, + &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 risc86_instruction_t *opcode_timings_dd_mod3[8] = +static const macro_op_t *opcode_timings_dd_mod3[8] = { /* FFFREE FST FSTP*/ &float_op, INVALID, &float_op, &float_op, @@ -1596,14 +1553,14 @@ static const risc86_instruction_t *opcode_timings_dd_mod3[8] = &float_op, &float_op, INVALID, INVALID }; -static const risc86_instruction_t *opcode_timings_de[8] = +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 risc86_instruction_t *opcode_timings_de_mod3[8] = +static const macro_op_t *opcode_timings_de_mod3[8] = { /* FADDP FMULP FCOMPP*/ &fadd_op, &fmul_op, INVALID, &float_op, @@ -1611,14 +1568,14 @@ static const risc86_instruction_t *opcode_timings_de_mod3[8] = &float_op, &float_op, &fdiv_op, &fdiv_op, }; -static const risc86_instruction_t *opcode_timings_df[8] = +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 risc86_instruction_t *opcode_timings_df_mod3[8] = +static const macro_op_t *opcode_timings_df_mod3[8] = { INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ @@ -1644,35 +1601,35 @@ static p6_unit_t *units; /*Pentium Pro has no MMX*/ static p6_unit_t ppro_units[] = { - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_FLOAT)}, /*Integer X & Floating point*/ - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_BRANCH)}, /*Integer Y*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD)}, /*Load*/ - {.uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED)}, /*Data Store*/ - {.uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA)}, /*Address Store*/ + {.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_ALUX) | (1 << UOP_FLOAT) | /*Integer X & Floating point*/ + {.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) | /*Integer Y*/ + {.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)}, /*Load*/ - {.uop_mask = (1 << UOP_STORED) | (1 << UOP_FSTORED) | (1 << UOP_MSTORED)}, /*Data Store*/ - {.uop_mask = (1 << UOP_STOREA) | (1 << UOP_FSTOREA) | (1 << UOP_MSTOREA)}, /*Address Store*/ + {.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 risc86_uop_t *uop, int decode_time) +static int uop_run(const p6_uop_t *uop, int decode_time) { int c; p6_unit_t *best_unit = NULL; - double best_start_cycle = 99999; + int best_start_cycle = 99999; - /*UOP_LIMM does not require execution*/ - if (uop->type == UOP_LIMM) + /*UOP_FXCH does not require execution*/ + if (uop->type == UOP_FXCH) return decode_time; /*Find execution unit for this uOP*/ @@ -1706,7 +1663,7 @@ static int uop_run(const risc86_uop_t *uop, int decode_time) static struct { int nr_uops; - const risc86_uop_t *uops[6]; + 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*/ @@ -1745,7 +1702,10 @@ void decode_flush_p6() /*Submit uops to execution units, and determine the latest completion time*/ for (c = 0; c < (decode_buffer.nr_uops); c++) { - start_timestamp = decode_buffer.earliest_start[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) @@ -1819,7 +1779,7 @@ static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_ return len; } -static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) +static void decode_instruction(const macro_op_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) { uint32_t regmask_required; uint32_t regmask_modified; @@ -1855,10 +1815,8 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u } /*Simple decoders are limited to 7 bytes & 1 uOP*/ - if (decode_type == DECODE_SIMPLE && instr_length > 7) + if ((decode_type == DECODE_SIMPLE && instr_length > 7) || (decode_type == DECODE_SIMPLE && ins->nr_uops > 1)) decode_type = DECODE_COMPLEX; - else if (decode_type == DECODE_SIMPLE && ins->nr_uops > 1) - decode_type = DECODE_COMPLEX; switch (decode_type) { @@ -1901,7 +1859,10 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u for (c = 0; c < ins->nr_uops; c++) { decode_buffer.uops[d] = &ins->uop[c]; - decode_buffer.earliest_start[d] = earliest_start; + 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*/ @@ -2006,7 +1967,7 @@ void codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { - const risc86_instruction_t **ins_table; + const macro_op_t **ins_table; uint64_t *deps; int mod3 = ((fetchdat & 0xc0) == 0xc0); int old_last_complete_timestamp = last_complete_timestamp; diff --git a/src/hwm.c b/src/hwm.c index cac194d98..7ef55b3ef 100644 --- a/src/hwm.c +++ b/src/hwm.c @@ -11,6 +11,7 @@ * * * Author: RichardG, + * * Copyright 2020 RichardG. */ diff --git a/src/hwm_lm75.c b/src/hwm_lm75.c new file mode 100644 index 000000000..0d937c194 --- /dev/null +++ b/src/hwm_lm75.c @@ -0,0 +1,269 @@ +/* + * 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 National Semiconductor LM75 temperature sensor chip. + * + * + * + * Author: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/smbus.h> +#include <86box/hwm.h> + + +#define LM75_TEMP_TO_REG(t) ((t) << 8) + + +static uint8_t lm75_smbus_read_byte(uint8_t addr, void *priv); +static uint8_t lm75_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint16_t lm75_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv); +static void lm75_smbus_write_byte(uint8_t addr, uint8_t val, void *priv); +static void lm75_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); +static void lm75_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv); +static void lm75_reset(lm75_t *dev); + + +#ifdef ENABLE_LM75_LOG +int lm75_do_log = ENABLE_LM75_LOG; + + +static void +lm75_log(const char *fmt, ...) +{ + va_list ap; + + if (lm75_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define lm75_log(fmt, ...) +#endif + + +void +lm75_remap(lm75_t *dev) +{ + lm75_log("LM75: remapping to SMBus %02Xh\n", dev->smbus_addr); + + smbus_removehandler(dev->smbus_addr, 1, + lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL, + lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL, + dev); + + if (dev->smbus_addr) smbus_sethandler(dev->smbus_addr, 1, + lm75_smbus_read_byte, lm75_smbus_read_byte_cmd, lm75_smbus_read_word_cmd, NULL, + lm75_smbus_write_byte, lm75_smbus_write_byte_cmd, lm75_smbus_write_word_cmd, NULL, + dev); +} + + +static uint8_t +lm75_smbus_read_byte(uint8_t addr, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + return lm75_read(dev, dev->addr_register); +} + + +static uint8_t +lm75_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + return lm75_read(dev, cmd); +} + +static uint16_t +lm75_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + uint8_t rethi = 0; + uint8_t retlo = 0; + + switch (cmd & 0x3) { + case 0x0: /* temperature */ + rethi = lm75_read(dev, 0x0); + retlo = lm75_read(dev, 0x1); + break; + case 0x1: /* configuration */ + rethi = retlo = lm75_read(dev, 0x2); + break; + case 0x2: /* Thyst */ + rethi = lm75_read(dev, 0x3); + retlo = lm75_read(dev, 0x4); + break; + case 0x3: /* Tos */ + rethi = lm75_read(dev, 0x5); + retlo = lm75_read(dev, 0x6); + break; + } + + return (retlo << 8) | rethi; /* byte-swapped for some reason */ +} + + +uint8_t +lm75_read(lm75_t *dev, uint8_t reg) +{ + uint8_t ret; + + /* The AS99127F hardware monitor uses the addresses of its LM75 devices + to access some of its proprietary registers. Pass this operation on to + the main monitor address through an internal SMBus call, if necessary. */ + if ((reg >= 0x80) && (dev->as99127f_smbus_addr)) + ret = smbus_read_byte_cmd(dev->as99127f_smbus_addr, reg); + else + ret = dev->regs[reg & 0x7]; + + lm75_log("LM75: read(%02X) = %02X\n", reg, ret); + + return ret; +} + + +static void +lm75_smbus_write_byte(uint8_t addr, uint8_t val, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + dev->addr_register = val; +} + + +static void +lm75_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + lm75_write(dev, cmd, val); +} + + +static void +lm75_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + uint8_t valhi = (val >> 8); + uint8_t vallo = (val & 0xff); + + switch (cmd & 0x3) { + case 0x0: /* temperature */ + lm75_write(dev, 0x0, valhi); + lm75_write(dev, 0x1, vallo); + break; + case 0x1: /* configuration */ + lm75_write(dev, 0x2, vallo); + break; + case 0x2: /* Thyst */ + lm75_write(dev, 0x3, valhi); + lm75_write(dev, 0x4, vallo); + break; + case 0x3: /* Tos */ + lm75_write(dev, 0x5, valhi); + lm75_write(dev, 0x6, vallo); + break; + break; + } +} + + +uint8_t +lm75_write(lm75_t *dev, uint8_t reg, uint8_t val) +{ + lm75_log("LM75: write(%02X, %02X)\n", reg, val); + + /* The AS99127F hardware monitor uses the addresses of its LM75 devices + to access some of its proprietary registers. Pass this operation on to + the main monitor address through an internal SMBus call, if necessary. */ + if ((reg >= 0x80) && (dev->as99127f_smbus_addr)) { + smbus_write_byte_cmd(dev->as99127f_smbus_addr, reg, val); + return 1; + } + + uint8_t reg_idx = (reg & 0x7); + + if ((reg_idx <= 0x1) || (reg_idx == 0x7)) + return 0; /* read-only registers */ + + dev->regs[reg_idx] = val; + + return 1; +} + + +static void +lm75_reset(lm75_t *dev) +{ + uint16_t temp = LM75_TEMP_TO_REG(dev->values->temperatures[dev->local >> 8]); + dev->regs[0x0] = (temp >> 8); + dev->regs[0x1] = temp; + dev->regs[0x3] = 0x4b; + dev->regs[0x5] = 0x50; + + lm75_remap(dev); +} + + +static void +lm75_close(void *priv) +{ + lm75_t *dev = (lm75_t *) priv; + free(dev); +} + + +static void * +lm75_init(const device_t *info) +{ + lm75_t *dev = (lm75_t *) malloc(sizeof(lm75_t)); + memset(dev, 0, sizeof(lm75_t)); + + dev->local = info->local; + dev->values = hwm_get_values(); + + dev->smbus_addr = dev->local; + dev->as99127f_smbus_addr = 0x00; + + lm75_reset(dev); + + return dev; +} + + +/* LM75 on SMBus address 4Ah, reporting temperatures[1]. */ +const device_t lm75_1_4a_device = { + "National Semiconductor LM75 Temperature Sensor", + DEVICE_AT, + 0x14a, + lm75_init, lm75_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +/* LM75 secondary/tertiary temperature sensors built into + the Winbond W83781D family. Not to be used stand-alone. */ +const device_t lm75_w83781d_device = { + "Winbond W83781D Secondary Temperature Sensor", + DEVICE_AT, + 0, + lm75_init, lm75_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/hwm_lm78.c b/src/hwm_lm78.c new file mode 100644 index 000000000..2cac22881 --- /dev/null +++ b/src/hwm_lm78.c @@ -0,0 +1,521 @@ +/* + * 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 National Semiconductor LM78 hardware monitoring chip. + * + * + * + * Author: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include "cpu.h" +#include <86box/smbus.h> +#include <86box/hwm.h> + + +#define LM78_SMBUS 0x10000 +#define LM78_W83781D 0x20000 +#define LM78_AS99127F_REV1 0x40000 +#define LM78_AS99127F_REV2 0x80000 +#define LM78_AS99127F (LM78_AS99127F_REV1 | LM78_AS99127F_REV2) /* special mask covering both _REV1 and _REV2 */ +#define LM78_WINBOND (LM78_W83781D | LM78_AS99127F) /* special mask covering all Winbond variants */ +#define LM78_WINBOND_VENDOR_ID ((dev->local & LM78_AS99127F_REV1) ? 0x12c3 : 0x5ca3) + +#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) +#define LM78_RPM_TO_REG(r, d) ((r) ? CLAMP(1350000 / (r * d), 1, 255) : 0) +#define LM78_VOLTAGE_TO_REG(v) ((v) >> 4) + + +typedef struct { + uint32_t local; + hwm_values_t *values; + device_t *lm75[2]; + + uint8_t regs[256]; + uint8_t addr_register; + uint8_t data_register; + + uint8_t smbus_addr; + uint8_t hbacs; + uint8_t active_bank; +} lm78_t; + + +static uint8_t lm78_isa_read(uint16_t port, void *priv); +static uint8_t lm78_smbus_read_byte(uint8_t addr, void *priv); +static uint8_t lm78_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint16_t lm78_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv); +static uint8_t lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank); +static void lm78_isa_write(uint16_t port, uint8_t val, void *priv); +static void lm78_smbus_write_byte(uint8_t addr, uint8_t val, void *priv); +static void lm78_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); +static void lm78_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv); +static uint8_t lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank); +static void lm78_reset(lm78_t *dev, uint8_t initialization); + + +#ifdef ENABLE_LM78_LOG +int lm78_do_log = ENABLE_LM78_LOG; + + +static void +lm78_log(const char *fmt, ...) +{ + va_list ap; + + if (lm78_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define lm78_log(fmt, ...) +#endif + + +static void +lm78_remap(lm78_t *dev) +{ + lm75_t *lm75; + + if (!(dev->local & LM78_SMBUS)) return; + + lm78_log("LM78: remapping to SMBus %02Xh\n", dev->smbus_addr); + + smbus_removehandler(dev->smbus_addr, 1, + lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, + lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, + dev); + + if (dev->smbus_addr) smbus_sethandler(dev->smbus_addr, 1, + lm78_smbus_read_byte, lm78_smbus_read_byte_cmd, lm78_smbus_read_word_cmd, NULL, + lm78_smbus_write_byte, lm78_smbus_write_byte_cmd, lm78_smbus_write_word_cmd, NULL, + dev); + + if (dev->local & LM78_AS99127F) { + /* Store the main SMBus address on the LM75 devices to ensure reads/writes + to the AS99127F's proprietary registers are passed through to this side. */ + for (uint8_t i = 0; i <= 1; i++) { + lm75 = device_get_priv(dev->lm75[i]); + if (lm75) + lm75->as99127f_smbus_addr = dev->smbus_addr; + } + } +} + + +static uint8_t +lm78_isa_read(uint16_t port, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + uint8_t ret = 0xff; + + switch (port & 0x7) { + case 0x5: + ret = (dev->addr_register & 0x7f); + break; + case 0x6: + ret = lm78_read(dev, dev->addr_register, dev->active_bank); + + if ((dev->active_bank == 0) && + ((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) || + ((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) { + /* auto-increment registers */ + dev->addr_register++; + } + break; + default: + lm78_log("LM78: Read from unknown ISA port %d\n", port & 0x7); + break; + } + + return ret; +} + + +static uint8_t +lm78_smbus_read_byte(uint8_t addr, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + return lm78_read(dev, dev->addr_register, dev->active_bank); +} + + +static uint8_t +lm78_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + return lm78_read(dev, cmd, dev->active_bank); +} + + +static uint16_t +lm78_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + return (lm78_read(dev, cmd, dev->active_bank) << 8) | lm78_read(dev, cmd, dev->active_bank); +} + + +static uint8_t +lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank) +{ + uint8_t ret = 0; + lm75_t *lm75; + + if (((reg >> 4) == 0x5) && (bank != 0)) { + /* LM75 registers */ + lm75 = device_get_priv(dev->lm75[bank - 1]); + if (lm75) + ret = lm75_read(lm75, reg & 0x7); + } else { + /* regular registers */ + if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* special case for two-byte vendor ID register */ + ret = (dev->hbacs ? (LM78_WINBOND_VENDOR_ID >> 8) : LM78_WINBOND_VENDOR_ID); + else if ((reg >= 0x60) && (reg <= 0x7f)) /* read auto-increment value RAM registers from their non-auto-increment locations */ + ret = dev->regs[reg & 0x3f]; + else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors [0x00:0x12] to [0x80:0x92] */ + ret = dev->regs[reg - 0x7f]; + else + ret = dev->regs[reg]; + } + + lm78_log("LM78: read(%02X, %d) = %02X\n", reg, bank, ret); + + return ret; +} + + +static void +lm78_isa_write(uint16_t port, uint8_t val, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + + switch (port & 0x7) { + case 0x5: + dev->addr_register = (val & 0x7f); + break; + case 0x6: + lm78_write(dev, dev->addr_register, val, dev->active_bank); + + if ((dev->active_bank == 0) && + ((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) || + ((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) { + /* auto-increment registers */ + dev->addr_register++; + } + break; + default: + lm78_log("LM78: Write %02X to unknown ISA port %d\n", val, port & 0x7); + break; + } +} + + +static void +lm78_smbus_write_byte(uint8_t addr, uint8_t val, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + dev->addr_register = val; +} + + +static void +lm78_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + lm78_write(dev, cmd, val, dev->active_bank); +} + + +static void +lm78_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + lm78_write(dev, cmd, val, dev->active_bank); +} + + +static uint8_t +lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank) +{ + lm75_t *lm75; + + lm78_log("LM78: write(%02X, %d, %02X)\n", reg, bank, val); + + if (((reg >> 4) == 0x5) && (bank != 0)) { + /* LM75 registers */ + lm75 = device_get_priv(dev->lm75[bank - 1]); + if (lm75) + lm75_write(lm75, reg & 0x7, val); + return 1; + } + + /* regular registers */ + switch (reg) { + case 0x41: case 0x42: case 0x4f: case 0x58: + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: + case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: + /* read-only registers */ + return 0; + case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: + /* Winbond-only registers */ + if (!(dev->local & LM78_WINBOND)) + return 0; + break; + } + + if ((reg >= 0x60) && (reg <= 0x7f)) /* write auto-increment value RAM registers to their non-auto-increment locations */ + dev->regs[reg & 0x3f] = val; + else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors [0x00:0x12] to [0x80:0x92] */ + dev->regs[reg & 0x7f] = val; + else + dev->regs[reg] = val; + + switch (reg) { + case 0x40: + if (val & 0x80) { + /* INITIALIZATION bit resets all registers except main SMBus address */ + lm78_reset(dev, 1); + } + break; + case 0x47: + /* update FAN1/FAN2 values to match the new divisor */ + dev->regs[0x28] = LM78_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x47] >> 4) & 0x3)); + dev->regs[0x29] = LM78_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x47] >> 6) & 0x3)); + break; + case 0x48: + /* set main SMBus address */ + if (dev->local & LM78_SMBUS) { + dev->smbus_addr = (dev->regs[0x48] & 0x7f); + lm78_remap(dev); + } + break; + case 0x49: + if (!(dev->local & LM78_WINBOND)) { + if (val & 0x20) { + /* Chip Reset bit (LM78 only) resets all registers */ + lm78_reset(dev, 0); + } else { + dev->regs[0x49] = 0x40; + } + } else { + dev->regs[0x49] &= 0x01; + } + break; + case 0x4a: + /* set LM75 SMBus addresses (Winbond only) */ + if (dev->local & LM78_SMBUS) { + for (uint8_t i = 0; i <= 1; i++) { + lm75 = device_get_priv(dev->lm75[i]); + if (dev->regs[0x4a] & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */ + lm75->smbus_addr = 0x00; + else + lm75->smbus_addr = (0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7)); + lm75_remap(lm75); + } + } + break; + case 0x4b: + /* update FAN3 value to match the new divisor */ + dev->regs[0x2a] = LM78_RPM_TO_REG(dev->values->fans[2], 1 << ((dev->regs[0x4b] >> 6) & 0x3)); + break; + case 0x4e: + dev->hbacs = (dev->regs[0x4e] & 0x80); + /* BANKSEL[0:2] is a bitfield according to the datasheet, but not in reality */ + dev->active_bank = (dev->regs[0x4e] & 0x07); + break; + case 0x87: + /* fixes AS99127F boards hanging after BIOS save & exit, probably a reset register */ + if ((dev->local & LM78_AS99127F) && (val == 0x01)) { + lm78_log("LM78: Reset requested through AS99127F\n"); + resetx86(); + } + break; + } + + return 1; +} + + +static void +lm78_reset(lm78_t *dev, uint8_t initialization) +{ + memset(dev->regs, 0, 256); + memset(dev->regs + 0xc0, 0xff, 32); /* C0-DF are 0xFF at least on the AS99127F */ + + uint8_t i; + for (i = 0; i <= 6; i++) + dev->regs[0x20 + i] = LM78_VOLTAGE_TO_REG(dev->values->voltages[i]); + dev->regs[0x27] = dev->values->temperatures[0]; + for (i = 0; i <= 2; i++) + dev->regs[0x28 + i] = LM78_RPM_TO_REG(dev->values->fans[i], 2); + dev->regs[0x40] = 0x08; + dev->regs[0x46] = 0x40; + dev->regs[0x47] = 0x50; + if (dev->local & LM78_SMBUS) { + if (!initialization) /* don't reset main SMBus address if the reset was triggered by the INITIALIZATION bit */ + dev->smbus_addr = 0x2d; + dev->regs[0x48] = dev->smbus_addr; + if (dev->local & LM78_WINBOND) + dev->regs[0x4a] = 0x01; + } else { + dev->regs[0x48] = 0x00; + if (dev->local & LM78_WINBOND) + dev->regs[0x4a] = 0x88; + } + if (dev->local & LM78_WINBOND) { + dev->regs[0x49] = 0x02; + dev->regs[0x4b] = 0x44; + dev->regs[0x4c] = 0x01; + dev->regs[0x4d] = 0x15; + dev->regs[0x4e] = 0x80; + dev->hbacs = (dev->regs[0x4e] & 0x80); + dev->regs[0x4f] = (LM78_WINBOND_VENDOR_ID >> 8); + dev->regs[0x57] = 0x80; + + /* Initialize proprietary registers on the AS99127F. The BIOS accesses some + of these on boot through read_byte_cmd on the TEMP2 address, hanging on + POST code C1 if they're defaulted to 0. There's no documentation on what + these are for. The following values were dumped from a live, initialized + AS99127F Rev. 2 on a P4B motherboard, and they seem to work well enough. */ + if (dev->local & LM78_AS99127F) { + /* 0x00 appears to mirror IN2 Low Limit */ + dev->regs[0x01] = dev->regs[0x23]; /* appears to mirror IN3 */ + dev->regs[0x02] = LM78_VOLTAGE_TO_REG(2800); /* appears to be a "maximum VCORE" of some kind; must read 2.8V on P3 boards */ + dev->regs[0x03] = 0x60; + dev->regs[0x04] = dev->regs[0x23]; /* appears to mirror IN3 */ + dev->regs[0x05] = dev->regs[0x22]; /* appears to mirror IN2 */ + dev->regs[0x07] = 0xcd; + /* 0x08 appears to mirror IN3 Low Limit */ + dev->regs[0x09] = dev->regs[0x0f] = dev->regs[0x11] = 0xf8; /* three instances of */ + dev->regs[0x0a] = dev->regs[0x10] = dev->regs[0x12] = 0xa5; /* the same word */ + dev->regs[0x0b] = 0xac; + dev->regs[0x0c] = 0x8c; + dev->regs[0x0d] = 0x68; + dev->regs[0x0e] = 0x54; + + dev->regs[0x53] = dev->regs[0x54] = dev->regs[0x55] = 0xff; + dev->regs[0x58] = 0x31; + dev->regs[0x59] = dev->regs[0x5a] = 0x8f; + dev->regs[0x5c] = 0xe0; + dev->regs[0x5d] = 0x48; + dev->regs[0x5e] = 0xe2; + dev->regs[0x5f] = 0x3f; + } else { + dev->regs[0x58] = 0x10; + } + } else { + dev->regs[0x49] = 0x40; + } + + lm78_remap(dev); +} + + +static void +lm78_close(void *priv) +{ + lm78_t *dev = (lm78_t *) priv; + + uint16_t isa_io = (dev->local & 0xffff); + if (isa_io) + io_removehandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev); + + free(dev); +} + + +static void * +lm78_init(const device_t *info) +{ + lm78_t *dev = (lm78_t *) malloc(sizeof(lm78_t)); + memset(dev, 0, sizeof(lm78_t)); + + dev->local = info->local; + dev->values = hwm_get_values(); + + /* initialize secondary/tertiary LM75 sensors on Winbond */ + for (uint8_t i = 0; i <= 1; i++) { + if (dev->local & LM78_WINBOND) { + dev->lm75[i] = (device_t *) malloc(sizeof(device_t)); + memcpy(dev->lm75[i], &lm75_w83781d_device, sizeof(device_t)); + dev->lm75[i]->local = ((i + 1) << 8); + if (dev->local & LM78_SMBUS) + dev->lm75[i]->local |= (0x48 + i); + device_add(dev->lm75[i]); + } else { + dev->lm75[i] = NULL; + } + } + + lm78_reset(dev, 0); + + uint16_t isa_io = (dev->local & 0xffff); + if (isa_io) + io_sethandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev); + + return dev; +} + + +/* National Semiconductor LM78 on ISA and SMBus. */ +const device_t lm78_device = { + "National Semiconductor LM78 Hardware Monitor", + DEVICE_ISA, + 0x290 | LM78_SMBUS, + lm78_init, lm78_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +/* Winbond W83781D (or ASUS AS97127F) on ISA and SMBus. */ +const device_t w83781d_device = { + "Winbond W83781D Hardware Monitor", + DEVICE_ISA, + 0x290 | LM78_SMBUS | LM78_W83781D, + lm78_init, lm78_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +/* The ASUS AS99127F is a customized W83781D with no ISA interface (SMBus only), + added proprietary registers and different chip/vendor IDs. */ +const device_t as99127f_device = { + "ASUS AS99127F Rev. 1 Hardware Monitor", + DEVICE_ISA, + LM78_SMBUS | LM78_AS99127F_REV1, + lm78_init, lm78_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +/* Rev. 2 changes the vendor ID back to Winbond's and brings some other changes. */ +const device_t as99127f_rev2_device = { + "ASUS AS99127F Rev. 2 Hardware Monitor", + DEVICE_AT, + LM78_SMBUS | LM78_AS99127F_REV2, + lm78_init, lm78_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/hwm_w83781d.c b/src/hwm_w83781d.c deleted file mode 100644 index 6dee12654..000000000 --- a/src/hwm_w83781d.c +++ /dev/null @@ -1,561 +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. - * - * Emulation of the Winbond W83781D hardware monitoring chip. - * - * - * - * Author: RichardG, - * Copyright 2020 RichardG. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/io.h> -#include <86box/smbus.h> -#include <86box/hwm.h> - - -#define W83781D_SMBUS 0x10000 -#define W83781D_AS99127F_REV1 0x20000 -#define W83781D_AS99127F_REV2 0x40000 -#define W83781D_AS99127F 0x60000 /* special mask covering both _REV1 and _REV2 */ -#define W83781D_VENDOR_ID ((dev->local & W83781D_AS99127F_REV1) ? 0x12C3 : 0x5CA3) - -#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) -#define W83781D_RPM_TO_REG(r, d) CLAMP(1350000 / (r * d), 1, 255) -#define W83781D_TEMP_TO_REG(t) ((t) << 8) -#define W83781D_VOLTAGE_TO_REG(v) ((v) >> 4) - - -typedef struct { - uint32_t local; - hwm_values_t* values; - - uint8_t regs[256]; - uint8_t regs_bank1[7]; - uint8_t regs_bank2[7]; - uint8_t addr_register; - uint8_t data_register; - - uint8_t smbus_addr_main; - uint8_t smbus_addr_temp2; - uint8_t smbus_addr_temp3; - uint8_t hbacs; - uint8_t active_bank; -} w83781d_t; - - -static uint8_t w83781d_isa_read(uint16_t port, void *priv); -static uint8_t w83781d_smbus_read_byte(uint8_t addr, void *priv); -static uint8_t w83781d_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv); -static uint16_t w83781d_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv); -static uint8_t w83781d_read(w83781d_t *dev, uint8_t reg, uint8_t bank); -static void w83781d_isa_write(uint16_t port, uint8_t val, void *priv); -static void w83781d_smbus_write_byte(uint8_t addr, uint8_t val, void *priv); -static void w83781d_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); -static void w83781d_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv); -static uint8_t w83781d_write(w83781d_t *dev, uint8_t reg, uint8_t val, uint8_t bank); -static void w83781d_reset(w83781d_t *dev, uint8_t initialization); - - -#ifdef ENABLE_W83781D_LOG -int w83781d_do_log = ENABLE_W83781D_LOG; - - -static void -w83781d_log(const char *fmt, ...) -{ - va_list ap; - - if (w83781d_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define w83781d_log(fmt, ...) -#endif - - -static void -w83781d_remap(w83781d_t *dev) -{ - if (!(dev->local & W83781D_SMBUS)) return; - - smbus_removehandler(0x00, 0x80, - w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, - w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, - dev); - - if (dev->smbus_addr_main) smbus_sethandler(dev->smbus_addr_main, 1, - w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, - w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, - dev); - - if (dev->smbus_addr_temp2) smbus_sethandler(dev->smbus_addr_temp2, 1, - w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, - w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, - dev); - - if (dev->smbus_addr_temp3) smbus_sethandler(dev->smbus_addr_temp3, 1, - w83781d_smbus_read_byte, w83781d_smbus_read_byte_cmd, w83781d_smbus_read_word_cmd, NULL, - w83781d_smbus_write_byte, w83781d_smbus_write_byte_cmd, w83781d_smbus_write_word_cmd, NULL, - dev); -} - - -static uint8_t -w83781d_isa_read(uint16_t port, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - uint8_t ret = 0xFF; - - switch (port - (dev->local & 0xFFFF)) { - case 0x0: - ret = dev->addr_register & 0x7F; - break; - case 0x1: - ret = w83781d_read(dev, dev->addr_register, dev->active_bank); - - if (dev->active_bank == 0 && - (dev->addr_register == 0x41 || dev->addr_register == 0x43 || dev->addr_register == 0x45 || dev->addr_register == 0x56 || - (dev->addr_register >= 0x60 && dev->addr_register < 0x7F))) { - /* auto-increment registers */ - dev->addr_register++; - } - break; - } - - return ret; -} - - -static uint8_t -w83781d_smbus_read_byte(uint8_t addr, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - return w83781d_read(dev, dev->addr_register, 0); -} - - -static uint8_t -w83781d_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - return w83781d_read(dev, cmd, 0); -} - - -static uint16_t -w83781d_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - uint8_t rethi = 0; - uint8_t retlo = 0; - uint8_t bank = 0; - - if (addr == dev->smbus_addr_temp2 || addr == dev->smbus_addr_temp3) { - if (addr == dev->smbus_addr_temp2) - bank = 2; - else - bank = 3; - - switch (cmd & 0x3) { - case 0x0: /* temperature */ - rethi = w83781d_read(dev, 0x50, bank); - retlo = w83781d_read(dev, 0x51, bank); - break; - case 0x1: /* configuration */ - rethi = retlo = w83781d_read(dev, 0x52, bank); - break; - case 0x2: /* Thyst */ - rethi = w83781d_read(dev, 0x53, bank); - retlo = w83781d_read(dev, 0x54, bank); - break; - case 0x3: /* Tos */ - rethi = w83781d_read(dev, 0x55, bank); - retlo = w83781d_read(dev, 0x56, bank); - break; - } - } else { - rethi = retlo = w83781d_read(dev, cmd, bank); - } - - return (retlo << 8) | rethi; /* byte-swapped for some reason */ -} - - -static uint8_t -w83781d_read(w83781d_t *dev, uint8_t reg, uint8_t bank) -{ - uint8_t ret = 0; - - if ((reg >> 4) == 0x5 && bank != 0) { - /* bank-switched temperature registers */ - if (bank == 1) - ret = dev->regs_bank1[reg - 0x50]; - else - ret = dev->regs_bank2[reg - 0x50]; - } else { - /* regular registers */ - if (reg == 0x4F) /* special case for two-byte vendor ID register */ - ret = dev->hbacs ? (W83781D_VENDOR_ID >> 8) : (W83781D_VENDOR_ID & 0xFF); - else if (reg >= 0x60 && reg <= 0x7F) /* read auto-increment value RAM registers from their non-auto-increment locations */ - ret = dev->regs[reg - 0x40]; - else if (reg >= 0x80 && reg <= 0x92) /* AS99127F mirrors 00-12 to 80-92 */ - ret = dev->regs[reg - 0x80]; - else - ret = dev->regs[reg]; - } - - w83781d_log("w83781d_read(%02x, %d) = %02x\n", reg, bank, ret); - - return ret; -} - - -static void -w83781d_isa_write(uint16_t port, uint8_t val, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - switch (port - (dev->local & 0xFFFF)) { - case 0x0: - dev->addr_register = val & 0x7F; - break; - case 0x1: - w83781d_write(dev, dev->addr_register, val, dev->active_bank); - - if (dev->active_bank == 0 && - (dev->addr_register == 0x41 || dev->addr_register == 0x43 || dev->addr_register == 0x45 || dev->addr_register == 0x56 || - (dev->addr_register >= 0x60 && dev->addr_register < 0x7F))) { - /* auto-increment registers */ - dev->addr_register++; - } - break; - } -} - - -static void -w83781d_smbus_write_byte(uint8_t addr, uint8_t val, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - dev->addr_register = val; -} - - -static void -w83781d_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - w83781d_write(dev, cmd, val, 0); -} - - -static void -w83781d_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - uint8_t valhi = (val >> 8); - uint8_t vallo = (val & 0xFF); - uint8_t bank = 0; - - if (addr == dev->smbus_addr_temp2 || addr == dev->smbus_addr_temp3) { - if (addr == dev->smbus_addr_temp2) - bank = 2; - else - bank = 3; - - switch (cmd & 0x3) { - case 0x0: /* temperature */ - w83781d_write(dev, 0x50, valhi, bank); - w83781d_write(dev, 0x51, vallo, bank); - break; - case 0x1: /* configuration */ - w83781d_write(dev, 0x52, vallo, bank); - break; - case 0x2: /* Thyst */ - w83781d_write(dev, 0x53, valhi, bank); - w83781d_write(dev, 0x54, vallo, bank); - break; - case 0x3: /* Tos */ - w83781d_write(dev, 0x55, valhi, bank); - w83781d_write(dev, 0x56, vallo, bank); - break; - break; - } - return; - } - - w83781d_write(dev, cmd, vallo, bank); -} - - -static uint8_t -w83781d_write(w83781d_t *dev, uint8_t reg, uint8_t val, uint8_t bank) -{ - uint8_t remap = 0; - - if ((reg >> 4) == 0x5 && bank != 0) { - /* bank-switched temperature registers */ - switch (reg) { - case 0x50: case 0x51: - /* read-only registers */ - return 0; - } - - if (bank == 1) - dev->regs_bank1[reg - 0x50] = val; - else - dev->regs_bank2[reg - 0x50] = val; - - return 1; - } - - /* regular registers */ - switch (reg) { - case 0x41: case 0x42: case 0x4F: case 0x58: - case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2A: - case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6A: - /* read-only registers */ - return 0; - } - - if (reg >= 0x60 && reg <= 0x7F) /* write auto-increment value RAM registers to their non-auto-increment locations */ - dev->regs[reg - 0x40] = val; - else if (reg >= 0x80 && reg <= 0x92) /* AS99127F mirrors 00-12 to 80-92 */ - dev->regs[reg - 0x80] = val; - else - dev->regs[reg] = val; - - switch (reg) { - case 0x40: - if (val >> 7) { - /* INITIALIZATION bit resets all registers except main SMBus address */ - w83781d_reset(dev, 1); - } - break; - case 0x47: - /* update FAN1/FAN2 values to match the new divisor */ - dev->regs[0x28] = W83781D_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x47] >> 4) & 0x3)); - dev->regs[0x29] = W83781D_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x47] >> 6) & 0x3)); - break; - case 0x48: - /* set main SMBus address */ - if (dev->local & W83781D_SMBUS) { - dev->smbus_addr_main = (dev->regs[0x48] & 0x7F); - remap = 1; - } - break; - case 0x4A: - /* set TEMP2 and TEMP3 SMBus addresses */ - if (dev->local & W83781D_SMBUS) { - /* DIS_T2 and DIS_T3 bits disable those interfaces */ - if ((dev->regs[0x4A] >> 3) & 0x1) - dev->smbus_addr_temp2 = 0x00; - else - dev->smbus_addr_temp2 = 0x48 + (dev->regs[0x4A] & 0x7); - if (dev->regs[0x4A] >> 7) - dev->smbus_addr_temp3 = 0x00; - else - dev->smbus_addr_temp3 = 0x48 + ((dev->regs[0x4A] >> 4) & 0x7); - remap = 1; - } - break; - case 0x4B: - /* update FAN3 value to match the new divisor */ - dev->regs[0x2A] = W83781D_RPM_TO_REG(dev->values->fans[2], 1 << ((dev->regs[0x4B] >> 6) & 0x3)); - break; - case 0x4E: - dev->hbacs = (dev->regs[0x4E] & 0x80); - /* FIXME: Winbond's datasheet does not specify how BANKSEL[0:2] work */ - if (dev->regs[0x4E] & 0x1) - dev->active_bank = 0; - else if (dev->regs[0x4E] & 0x2) - dev->active_bank = 1; - else if (dev->regs[0x4E] & 0x4) - dev->active_bank = 2; - break; - } - - if (remap) - w83781d_remap(dev); - - return 1; -} - - -static void -w83781d_reset(w83781d_t *dev, uint8_t initialization) -{ - memset(dev->regs, 0, 256); - memset(dev->regs + 0xC0, 0xFF, 32); /* C0-DF are 0xFF at least on the AS99127F */ - memset(dev->regs_bank1, 0, 6); - memset(dev->regs_bank2, 0, 6); - - uint8_t i; - for (i = 0; i <= 6; i++) - dev->regs[0x20 + i] = W83781D_VOLTAGE_TO_REG(dev->values->voltages[i]); - dev->regs[0x27] = dev->values->temperatures[0]; - for (i = 0; i <= 2; i++) - dev->regs[0x28 + i] = W83781D_RPM_TO_REG(dev->values->fans[i], 2); - dev->regs[0x40] = 0x01; - dev->regs[0x46] = 0x40; - dev->regs[0x47] = 0x50; - if (dev->local & W83781D_SMBUS) { - if (!initialization) /* don't reset main SMBus address if the reset was triggered by the INITIALIZATION bit */ - dev->smbus_addr_main = 0x2D; - dev->regs[0x48] = dev->smbus_addr_main; - dev->regs[0x4A] = 0x01; - dev->smbus_addr_temp2 = 0x48 + (dev->regs[0x4A] & 0x7); - dev->smbus_addr_temp3 = 0x48 + ((dev->regs[0x4A] >> 4) & 0x7); - } else { - dev->regs[0x48] = 0x00; - dev->regs[0x4A] = 0x88; - dev->smbus_addr_temp2 = dev->smbus_addr_temp3 = 0x00; - } - dev->regs[0x49] = 0x02; - dev->regs[0x4B] = 0x44; - dev->regs[0x4C] = 0x01; - dev->regs[0x4D] = 0x15; - dev->regs[0x4E] = 0x80; - dev->hbacs = (dev->regs[0x4E] & 0x80); - dev->regs[0x4F] = W83781D_VENDOR_ID >> 8; - dev->regs[0x57] = 0x80; - dev->regs[0x58] = (dev->local & W83781D_AS99127F) ? 0x31 : 0x10; - - /* - * Initialize proprietary registers on the AS99127F. The BIOS accesses some - * of these on boot through read_byte_cmd on the TEMP2 address, hanging on - * POST code C1 if they're set to 0. There's no documentation on what these - * are for. The following values were dumped from a live, initialized - * AS99127F Rev. 2 on a P4B motherboard, and they seem to work well enough. - */ - if (dev->local & W83781D_AS99127F) { - /* 0x00 appears to mirror IN2 Low Limit */ - dev->regs[0x01] = dev->regs[0x23]; /* appears to mirror IN3 */ - dev->regs[0x02] = W83781D_VOLTAGE_TO_REG(2800); /* appears to be a "maximum VCORE" of some kind; mirrors VCORE on the P4 board, but the P3 boards require this to read 2.8V */ - dev->regs[0x03] = 0x60; - dev->regs[0x04] = dev->regs[0x23]; /* appears to mirror IN3 */ - dev->regs[0x05] = dev->regs[0x22]; /* appears to mirror IN2 */ - dev->regs[0x07] = 0xCD; - /* 0x08 appears to mirror IN3 Low Limit */ - dev->regs[0x09] = dev->regs[0x0F] = dev->regs[0x11] = 0xF8; /* three instances of */ - dev->regs[0x0A] = dev->regs[0x10] = dev->regs[0x12] = 0xA5; /* the same word */ - dev->regs[0x0B] = 0xAC; - dev->regs[0x0C] = 0x8C; - dev->regs[0x0D] = 0x68; - dev->regs[0x0E] = 0x54; - - dev->regs[0x53] = dev->regs[0x54] = dev->regs[0x55] = 0xFF; - dev->regs[0x59] = dev->regs[0x5A] = 0x8F; - dev->regs[0x5C] = 0xE0; - dev->regs[0x5D] = 0x48; - dev->regs[0x5E] = 0xE2; - dev->regs[0x5F] = 0x3F; - } - - /* WARNING: Array elements are register - 0x50. */ - uint16_t temp; - temp = W83781D_TEMP_TO_REG(dev->values->temperatures[1]); - dev->regs_bank1[0x0] = temp >> 8; - dev->regs_bank1[0x1] = temp & 0xFF; - dev->regs_bank1[0x3] = 0x4B; - dev->regs_bank1[0x5] = 0x50; - temp = W83781D_TEMP_TO_REG(dev->values->temperatures[2]); - dev->regs_bank2[0x0] = temp >> 8; - dev->regs_bank2[0x1] = temp & 0xFF; - dev->regs_bank2[0x3] = 0x4B; - dev->regs_bank2[0x5] = 0x50; - - w83781d_remap(dev); -} - - -static void -w83781d_close(void *priv) -{ - w83781d_t *dev = (w83781d_t *) priv; - - uint16_t isa_io = dev->local & 0xFFFF; - if (isa_io) - io_removehandler(isa_io, 2, w83781d_isa_read, NULL, NULL, w83781d_isa_write, NULL, NULL, dev); - - free(dev); -} - - -static void * -w83781d_init(const device_t *info) -{ - w83781d_t *dev = (w83781d_t *) malloc(sizeof(w83781d_t)); - memset(dev, 0, sizeof(w83781d_t)); - - dev->local = info->local; - dev->values = hwm_get_values(); - w83781d_reset(dev, 0); - - uint16_t isa_io = dev->local & 0xFFFF; - if (isa_io) - io_sethandler(isa_io, 2, w83781d_isa_read, NULL, NULL, w83781d_isa_write, NULL, NULL, dev); - - return dev; -} - - -/* - * Standard Winbond W83781D (or ASUS AS97127F) on ISA and SMBus. - */ -const device_t w83781d_device = { - "Winbond W83781D Hardware Monitor", - DEVICE_ISA, - 0x295 | W83781D_SMBUS, - w83781d_init, w83781d_close, NULL, - NULL, NULL, NULL, - NULL -}; - - -/* - * The ASUS AS99127F is a customized W83781D with no ISA interface (SMBus only), - * added proprietary registers and different chip/vendor IDs. - */ -const device_t as99127f_device = { - "ASUS AS99127F Rev. 1 Hardware Monitor", - DEVICE_ISA, - W83781D_SMBUS | W83781D_AS99127F_REV1, - w83781d_init, w83781d_close, NULL, - NULL, NULL, NULL, - NULL -}; - - -/* - * Rev. 2 changes the vendor ID back to Winbond's and brings some other changes. - */ -const device_t as99127f_rev2_device = { - "ASUS AS99127F Rev. 2 Hardware Monitor", - DEVICE_AT, - W83781D_SMBUS | W83781D_AS99127F_REV2, - w83781d_init, w83781d_close, NULL, - NULL, NULL, NULL, - NULL -}; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 38afdda57..ef0878b46 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -32,10 +32,15 @@ #ifdef RELEASE_BUILD #define EMU_VERSION "2.07" #define EMU_VERSION_W L"2.07" +#define EMU_VERSION_MAJ 2 +#define EMU_VERSION_MIN 7 #else #define EMU_VERSION "2.10" #define EMU_VERSION_W L"2.10" +#define EMU_VERSION_MAJ 2 +#define EMU_VERSION_MIN 10 #endif +#define COPYRIGHT_YEAR "2020" /* Filename and pathname info. */ #define CONFIG_FILE L"86box.cfg" diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index f4cace10d..0cae77dbb 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -11,6 +11,7 @@ * * * Author: RichardG, + * * Copyright 2020 RichardG. */ #ifndef EMU_HWM_H @@ -26,13 +27,34 @@ typedef struct _hwm_values_ { uint16_t voltages[8]; } hwm_values_t; +typedef struct { + uint32_t local; + hwm_values_t *values; + + uint8_t regs[8]; + uint8_t addr_register; + uint8_t temp_idx; + uint8_t smbus_addr; + + uint8_t as99127f_smbus_addr; +} lm75_t; + extern void hwm_set_values(hwm_values_t new_values); extern hwm_values_t* hwm_get_values(); +extern void lm75_remap(lm75_t *dev); +extern uint8_t lm75_read(lm75_t *dev, uint8_t reg); +extern uint8_t lm75_write(lm75_t *dev, uint8_t reg, uint8_t val); + +extern const device_t lm75_1_4a_device; +extern const device_t lm75_w83781d_device; + +extern const device_t lm78_device; extern const device_t w83781d_device; extern const device_t as99127f_device; +extern const device_t as99127f_rev2_device; #endif /*EMU_HWM_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4a523e3e4..3941836c3 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -187,15 +187,15 @@ extern int machine_at_tg286m_init(const machine_t *); extern int machine_at_ama932j_init(const machine_t *); extern int machine_at_px286_init(const machine_t *); extern int machine_at_quadt286_init(const machine_t *); +extern int machine_at_mr286_init(const machine_t *); extern int machine_at_neat_init(const machine_t *); extern int machine_at_neat_ami_init(const machine_t *); extern int machine_at_goldstar386_init(const machine_t *); -extern int machine_at_micronics386_init(const machine_t *); - extern int machine_at_award286_init(const machine_t *); +extern int machine_at_gdc212m_init(const machine_t *); extern int machine_at_gw286ct_init(const machine_t *); extern int machine_at_super286tr_init(const machine_t *); extern int machine_at_spc4200p_init(const machine_t *); @@ -213,7 +213,9 @@ extern const device_t *at_commodore_sl386sx_get_device(void); /* m_at_386dx_486.c */ +extern int machine_at_acc386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); +extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_pb410a_init(const machine_t *); @@ -222,9 +224,7 @@ extern int machine_at_winbios1429_init(const machine_t *); extern int machine_at_opti495_init(const machine_t *); extern int machine_at_opti495_ami_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(USE_MR495) extern int machine_at_opti495_mr_init(const machine_t *); -#endif extern int machine_at_ami471_init(const machine_t *); extern int machine_at_dtk486_init(const machine_t *); @@ -237,7 +237,9 @@ 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 *); +#endif /* m_at_commodore.c */ extern int machine_at_cmdpc_init(const machine_t *); @@ -266,7 +268,6 @@ 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_mb500n_init(const machine_t *); -extern int machine_at_president_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_VECTRA54) extern int machine_at_vectra54_init(const machine_t *); #endif @@ -277,10 +278,10 @@ extern const device_t *at_endeavor_get_device(void); #endif /* m_at_socket7_s7.c */ +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 *); -#if defined(DEV_BRANCH) && defined(USE_MRTHOR) extern int machine_at_mrthor_init(const machine_t *); -#endif extern int machine_at_pb640_init(const machine_t *); extern int machine_at_acerm3a_init(const machine_t *); @@ -299,15 +300,23 @@ extern int machine_at_i430vx_init(const machine_t *); extern int machine_at_brio80xx_init(const machine_t *); extern int machine_at_pb680_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_p55xb2_init(const machine_t *); +#endif extern int machine_at_tx97_init(const machine_t *); extern int machine_at_ym430tx_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_586t2_init(const machine_t *); extern int machine_at_807ds_init(const machine_t *); +#endif extern int machine_at_p5mms98_init(const machine_t *); -extern int machine_at_tx100_init(const machine_t *); +extern int machine_at_ficva502_init(const machine_t *); + +extern int machine_at_ficpa2012_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_advanceii_init(const machine_t *); +#endif #ifdef EMU_DEVICE_H extern const device_t *at_pb640_get_device(void); @@ -322,7 +331,6 @@ extern int machine_at_686nx_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 *); -extern int machine_at_vs440fx_init(const machine_t *); #ifdef EMU_DEVICE_H extern void machine_at_p65up5_common_init(const machine_t *, const device_t *northbridge); #endif @@ -332,16 +340,30 @@ extern int machine_at_p65up5_cp6nd_init(const machine_t *); extern int machine_at_p65up5_cpknd_init(const machine_t *); extern int machine_at_p6kfx_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_6bxc_init(const machine_t *); +#endif 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_borapro_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 *); + +/* m_at_slot2.c */ +#if defined(DEV_BRANCH) && defined(NO_SIO) +extern int machine_at_s2dge_init(const machine_t *); +#endif /* m_at_socket370.c */ +#if defined(DEV_BRANCH) && defined(NO_SIO) +extern int machine_at_s370slm_init(const machine_t *); +#endif extern int machine_at_cubx_init(const machine_t *); extern int machine_at_atc7020bxii_init(const machine_t *); extern int machine_at_63a_init(const machine_t *); +extern int machine_at_s370sba_init(const machine_t *); extern int machine_at_apas3_init(const machine_t *); /* m_at_t3100e.c */ diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index ef01bf7b1..7d084a2b0 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -178,7 +178,7 @@ extern uintptr_t *writelookup2; extern int writelnext; extern uint32_t ram_mapped_addr[64]; -mem_mapping_t base_mapping, +extern mem_mapping_t base_mapping, ram_low_mapping, #if 1 ram_mid_mapping, diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index a2590350d..2033ef02f 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -62,17 +62,17 @@ extern "C" { #endif /* Global variables residing in the platform module. */ -GLOBAL int dopause, /* system is paused */ +extern int dopause, /* system is paused */ doresize, /* screen resize requested */ quited, /* system exit requested */ mouse_capture; /* mouse is captured in app */ -GLOBAL uint64_t timer_freq; -GLOBAL int infocus; -GLOBAL char emu_version[200]; /* version ID string */ -GLOBAL int rctrl_is_lalt; -GLOBAL int update_icons; +extern uint64_t timer_freq; +extern int infocus; +extern char emu_version[200]; /* version ID string */ +extern int rctrl_is_lalt; +extern int update_icons; -GLOBAL int unscaled_size_x, /* current unscaled size X */ +extern int unscaled_size_x, /* current unscaled size X */ unscaled_size_y; /* current unscaled size Y */ /* System-related functions. */ diff --git a/src/include/86box/smbus.h b/src/include/86box/smbus.h index 058b70ffc..6923a7edb 100644 --- a/src/include/86box/smbus.h +++ b/src/include/86box/smbus.h @@ -24,7 +24,7 @@ extern void smbus_sethandler(uint8_t base, int size, uint8_t (*read_byte)(uint8_t addr, void *priv), uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), - uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), void (*write_byte)(uint8_t addr, uint8_t val, void *priv), void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), @@ -35,7 +35,7 @@ extern void smbus_removehandler(uint8_t base, int size, uint8_t (*read_byte)(uint8_t addr, void *priv), uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), - uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), void (*write_byte)(uint8_t addr, uint8_t val, void *priv), void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), @@ -46,7 +46,7 @@ extern void smbus_handler(int set, uint8_t base, int size, uint8_t (*read_byte)(uint8_t addr, void *priv), uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), - uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), void (*write_byte)(uint8_t addr, uint8_t val, void *priv), void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), @@ -57,7 +57,7 @@ extern uint8_t smbus_has_device(uint8_t addr); extern uint8_t smbus_read_byte(uint8_t addr); extern uint8_t smbus_read_byte_cmd(uint8_t addr, uint8_t cmd); extern uint16_t smbus_read_word_cmd(uint8_t addr, uint8_t cmd); -extern uint8_t smbus_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data); +extern uint8_t smbus_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len); extern void smbus_write_byte(uint8_t addr, uint8_t val); extern void smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val); extern void smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val); diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index c2549fe95..098fb3ed7 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -47,6 +47,16 @@ #define SPD_SDR_ATTR_VCC_HI_5 0x20 +typedef struct _spd_ { + const device_t *info; + uint8_t slot; + uint16_t size; + uint16_t row1; + uint16_t row2; + + uint8_t addr_register; +} spd_t; + typedef struct _spd_edo_ { uint8_t bytes_used, spd_size, mem_type, row_bits, col_bits, banks, @@ -72,7 +82,7 @@ typedef struct _spd_sdram_ { signal_level, tclk, tac, config, refresh_rate, sdram_width, ecc_width, - tccd, burst, banks, cas, cs, we, + tccd, burst, banks, cas, cslat, we, mod_attr, dev_attr, tclk2, tac2, tclk3, tac3, trp, trrd, trcd, tras, @@ -90,6 +100,9 @@ typedef struct _spd_sdram_ { } spd_sdram_t; +extern spd_t *spd_devices[SPD_MAX_SLOTS]; + + extern void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size); diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index d1495ebbd..acdea041c 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -72,7 +72,7 @@ typedef struct svga_t vram_mask, charseta, charsetb, adv_flags, ma_latch, - ma, maback, + ca_adj, ma, maback, write_bank, read_bank, extra_banks[2], banked_mask, @@ -117,6 +117,7 @@ typedef struct svga_t /*Called at the start of vertical sync*/ void (*vsync_callback)(struct svga_t *svga); + uint32_t (*translate_address)(uint32_t addr, void *p); /*If set then another device is driving the monitor output and the SVGA card should not attempt to display anything */ int override; @@ -132,7 +133,10 @@ typedef struct svga_t plane_mask, writemask, colourcompare, colournocare, dac_mask, dac_status, - ksc5601_sbyte_mask; + ksc5601_sbyte_mask, ksc5601_udc_area_msb[2]; + + int ksc5601_swap_mode; + uint16_t ksc5601_english_font_type; int vertical_linedbl; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 230d9623b..fb0c33b08 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -212,6 +212,7 @@ extern const device_t ati28800_wonderxl24_device; #endif /* Cirrus Logic CL-GD 54xx */ +extern const device_t gd5401_isa_device; extern const device_t gd5402_isa_device; extern const device_t gd5402_onboard_device; extern const device_t gd5420_isa_device; @@ -245,6 +246,7 @@ extern const device_t compaq_cga_2_device; extern const device_t et4000_isa_device; extern const device_t et4000k_isa_device; extern const device_t et4000k_tg286_isa_device; +extern const device_t et4000_kasan_isa_device; extern const device_t et4000_mca_device; /* Tseng ET4000-W32p */ @@ -292,26 +294,26 @@ extern const device_t paradise_wd90c11_device; extern const device_t paradise_wd90c30_device; /* S3 9XX/8XX/Vision/Trio */ -const device_t s3_orchid_86c911_isa_device; -const device_t s3_metheus_premier_86c928_isa_device; -const device_t s3_metheus_premier_86c928_vlb_device; -const device_t s3_v7mirage_86c801_isa_device; -const device_t s3_phoenix_86c805_vlb_device; -const device_t s3_bahamas64_vlb_device; -const device_t s3_bahamas64_pci_device; -const device_t s3_9fx_vlb_device; -const device_t s3_9fx_pci_device; -const device_t s3_phoenix_trio32_vlb_device; -const device_t s3_phoenix_trio32_pci_device; -const device_t s3_phoenix_trio64_vlb_device; -const device_t s3_phoenix_trio64_onboard_pci_device; -const device_t s3_phoenix_trio64_pci_device; -const device_t s3_phoenix_vision864_pci_device; -const device_t s3_phoenix_vision864_vlb_device; -const device_t s3_diamond_stealth64_pci_device; -const device_t s3_diamond_stealth64_vlb_device; -const device_t s3_diamond_stealth64_964_pci_device; -const device_t s3_diamond_stealth64_964_vlb_device; +extern const device_t s3_orchid_86c911_isa_device; +extern const device_t s3_metheus_premier_86c928_isa_device; +extern const device_t s3_metheus_premier_86c928_vlb_device; +extern const device_t s3_v7mirage_86c801_isa_device; +extern const device_t s3_phoenix_86c805_vlb_device; +extern const device_t s3_bahamas64_vlb_device; +extern const device_t s3_bahamas64_pci_device; +extern const device_t s3_9fx_vlb_device; +extern const device_t s3_9fx_pci_device; +extern const device_t s3_phoenix_trio32_vlb_device; +extern const device_t s3_phoenix_trio32_pci_device; +extern const device_t s3_phoenix_trio64_vlb_device; +extern const device_t s3_phoenix_trio64_onboard_pci_device; +extern const device_t s3_phoenix_trio64_pci_device; +extern const device_t s3_phoenix_vision864_pci_device; +extern const device_t s3_phoenix_vision864_vlb_device; +extern const device_t s3_diamond_stealth64_pci_device; +extern const device_t s3_diamond_stealth64_vlb_device; +extern const device_t s3_diamond_stealth64_964_pci_device; +extern const device_t s3_diamond_stealth64_964_vlb_device; /* S3 ViRGE */ extern const device_t s3_virge_vlb_device; diff --git a/src/intel_piix.c b/src/intel_piix.c index 885af6645..34ab4eb3b 100644 --- a/src/intel_piix.c +++ b/src/intel_piix.c @@ -98,55 +98,18 @@ piix_log(const char *fmt, ...) #endif -static void -smsc_ide_handlers(piix_t *dev) -{ - uint16_t main, side; - - ide_pri_disable(); - ide_sec_disable(); - - if (dev->regs[1][0x09] & 0x01) { - main = (dev->regs[1][0x11] << 8) | (dev->regs[1][0x10] & 0xf8); - side = ((dev->regs[1][0x15] << 8) | (dev->regs[1][0x14] & 0xfc)) + 2; - } else { - main = 0x1f0; - side = 0x3f6; - } - ide_set_base(0, main); - ide_set_side(0, side); - - if (dev->regs[1][0x09] & 0x04) { - main = (dev->regs[1][0x19] << 8) | (dev->regs[1][0x18] & 0xf8); - side = ((dev->regs[1][0x1d] << 8) | (dev->regs[1][0x1c] & 0xfc)) + 2; - } else { - main = 0x170; - side = 0x376; - } - ide_set_base(1, main); - ide_set_side(1, side); - - if (dev->regs[1][0x04] & PCI_COMMAND_IO) { - if (dev->regs[1][0x41] & 0x80) - ide_pri_enable(); - if (dev->regs[1][0x43] & 0x80) - ide_sec_enable(); - } -} - - static void smsc_ide_irqs(piix_t *dev) { int irq_line = 3, irq_mode[2] = { 0, 0 }; if (dev->regs[1][0x09] & 0x01) - irq_mode[0] = (dev->regs[0][0xe0] & 0x01) ? 3 : 1; + irq_mode[0] = (dev->regs[0][0xe1] & 0x01) ? 3 : 1; if (dev->regs[1][0x09] & 0x04) - irq_mode[1] = (dev->regs[0][0xe0] & 0x01) ? 3 : 1; + irq_mode[1] = (dev->regs[0][0xe1] & 0x01) ? 3 : 1; - switch ((dev->regs[0][0xe0] >> 1) & 0x07) { + switch ((dev->regs[0][0xe1] >> 1) & 0x07) { case 0x00: irq_line = 3; break; @@ -184,16 +147,46 @@ smsc_ide_irqs(piix_t *dev) static void -piix_ide_legacy_handlers(piix_t *dev, int bus) +piix_ide_handlers(piix_t *dev, int bus) { + uint16_t main, side; + if (bus & 0x01) { ide_pri_disable(); + + if (dev->type == 5) { + if (dev->regs[1][0x09] & 0x01) { + main = (dev->regs[1][0x11] << 8) | (dev->regs[1][0x10] & 0xf8); + side = ((dev->regs[1][0x15] << 8) | (dev->regs[1][0x14] & 0xfc)) + 2; + } else { + main = 0x1f0; + side = 0x3f6; + } + + ide_set_base(0, main); + ide_set_side(0, side); + } + if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x41] & 0x80)) ide_pri_enable(); } if (bus & 0x02) { ide_sec_disable(); + + if (dev->type == 5) { + if (dev->regs[1][0x09] & 0x04) { + main = (dev->regs[1][0x19] << 8) | (dev->regs[1][0x18] & 0xf8); + side = ((dev->regs[1][0x1d] << 8) | (dev->regs[1][0x1c] & 0xfc)) + 2; + } else { + main = 0x170; + side = 0x376; + } + + ide_set_base(1, main); + ide_set_side(1, side); + } + if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x43] & 0x80)) ide_sec_enable(); } @@ -266,12 +259,15 @@ nvr_update_io_mapping(piix_t *dev) if (dev->regs[0][0xcb] & 0x01) { piix_log("Adding low NVR at %04X...\n", dev->nvr_io_base); - nvr_at_handler(1, dev->nvr_io_base, dev->nvr); - nvr_at_handler(1, dev->nvr_io_base + 0x0004, dev->nvr); + if (dev->nvr_io_base != 0x0000) { + nvr_at_handler(1, dev->nvr_io_base, dev->nvr); + nvr_at_handler(1, dev->nvr_io_base + 0x0004, dev->nvr); + } } if (dev->regs[0][0xcb] & 0x04) { piix_log("Adding high NVR at %04X...\n", dev->nvr_io_base + 0x0002); - nvr_at_handler(1, dev->nvr_io_base + 0x0002, dev->nvr); + if (dev->nvr_io_base != 0x0000) + nvr_at_handler(1, dev->nvr_io_base + 0x0002, dev->nvr); } } @@ -529,8 +525,10 @@ piix_write(int func, int addr, uint8_t val, void *priv) } break; case 0xb0: - if (dev->type > 3) + if (dev->type == 4) fregs[addr] = (fregs[addr] & 0x8c) | (val & 0x73); + else if (dev->type == 5) + fregs[addr] = val & 0x7f; break; case 0xb1: if (dev->type > 3) @@ -585,10 +583,7 @@ piix_write(int func, int addr, uint8_t val, void *priv) fregs[0x04] = (val & 5); if (dev->type < 3) fregs[0x04] |= 0x02; - if (dev->type == 5) - smsc_ide_handlers(dev); - else - piix_ide_legacy_handlers(dev, 0x03); + piix_ide_handlers(dev, 0x03); piix_ide_bm_handlers(dev); break; case 0x07: @@ -602,7 +597,7 @@ piix_write(int func, int addr, uint8_t val, void *priv) case 0x09: if (dev->type == 5) { fregs[0x09] = (fregs[0x09] & 0xfa) | (val & 0x05); - smsc_ide_handlers(dev); + piix_ide_handlers(dev, 0x03); smsc_ide_irqs(dev); } break; @@ -611,35 +606,35 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0x10: fregs[0x10] = (val & 0xf8) | 1; - smsc_ide_handlers(dev); + piix_ide_handlers(dev, 0x01); break; case 0x11: fregs[0x11] = val; - smsc_ide_handlers(dev); + piix_ide_handlers(dev, 0x01); break; case 0x14: fregs[0x14] = (val & 0xfc) | 1; - smsc_ide_handlers(dev); + piix_ide_handlers(dev, 0x01); break; case 0x15: fregs[0x15] = val; - smsc_ide_handlers(dev); + piix_ide_handlers(dev, 0x01); break; case 0x18: fregs[0x18] = (val & 0xf8) | 1; - smsc_ide_handlers(dev); + piix_ide_handlers(dev, 0x02); break; case 0x19: fregs[0x19] = val; - smsc_ide_handlers(dev); + piix_ide_handlers(dev, 0x02); break; case 0x1c: fregs[0x1c] = (val & 0xfc) | 1; - smsc_ide_handlers(dev); + piix_ide_handlers(dev, 0x02); break; case 0x1d: fregs[0x1d] = val; - smsc_ide_handlers(dev); + piix_ide_handlers(dev, 0x02); break; case 0x20: fregs[0x20] = (val & 0xf0) | 1; @@ -652,15 +647,16 @@ piix_write(int func, int addr, uint8_t val, void *priv) case 0x3c: fregs[0x3c] = val; break; + case 0x3d: + if (dev->type == 5) + fregs[0x3d] = val; + break; case 0x40: case 0x42: fregs[addr] = val; break; case 0x41: case 0x43: fregs[addr] = val & ((dev->type > 1) ? 0xf3 : 0xb3); - if (dev->type == 5) - smsc_ide_handlers(dev); - else - piix_ide_legacy_handlers(dev, 1 << !!(addr & 0x02)); + piix_ide_handlers(dev, 1 << !!(addr & 0x02)); break; case 0x44: if (dev->type > 1) @@ -715,19 +711,19 @@ piix_write(int func, int addr, uint8_t val, void *priv) fregs[0x0c] = val; break; case 0x0d: - if (dev->type <= 4) + if (dev->type < 5) fregs[0x0d] = val & 0xf0; break; case 0x11: if (dev->type > 4) { fregs[addr] = val & 0xf0; - ohci_update_mem_mapping(dev->usb, fregs[0x11], fregs[0x12], fregs[0x13], fregs[PCI_REG_COMMAND] & PCI_COMMAND_MEM); + ohci_update_mem_mapping(dev->usb, fregs[0x11], fregs[0x12], fregs[0x13], 1 /*fregs[PCI_REG_COMMAND] & PCI_COMMAND_MEM*/); } break; case 0x12: case 0x13: if (dev->type > 4) { fregs[addr] = val; - ohci_update_mem_mapping(dev->usb, fregs[0x11], fregs[0x12], fregs[0x13], fregs[PCI_REG_COMMAND] & PCI_COMMAND_MEM); + ohci_update_mem_mapping(dev->usb, fregs[0x11], fregs[0x12], fregs[0x13], 1 /*fregs[PCI_REG_COMMAND] & PCI_COMMAND_MEM*/); } break; case 0x20: @@ -759,7 +755,7 @@ 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: @@ -1022,7 +1018,6 @@ piix_reset_hard(piix_t *dev) /* Function 1: IDE */ fregs = (uint8_t *) dev->regs[1]; piix_log("PIIX Function 1: %02X%02X:%02X%02X\n", fregs[0x01], fregs[0x00], fregs[0x03], fregs[0x02]); - fregs[0x04] = (dev->type > 3) ? 0x05 : 0x07; fregs[0x06] = 0x80; fregs[0x07] = 0x02; if (dev->type == 4) fregs[0x08] = dev->rev & 0x07; @@ -1050,7 +1045,6 @@ piix_reset_hard(piix_t *dev) if (dev->type > 1) { fregs = (uint8_t *) dev->regs[2]; piix_log("PIIX Function 2: %02X%02X:%02X%02X\n", fregs[0x01], fregs[0x00], fregs[0x03], fregs[0x02]); - fregs[0x04] = 0x05; fregs[0x06] = 0x80; fregs[0x07] = 0x02; if (dev->type == 4) fregs[0x08] = dev->rev & 0x07; @@ -1058,12 +1052,14 @@ piix_reset_hard(piix_t *dev) fregs[0x08] = dev->rev; else fregs[0x08] = 0x02; - if (dev->type == 5) + if (dev->type > 4) fregs[0x09] = 0x10; /* SMSC has OHCI rather than UHCI */ fregs[0x0a] = 0x03; fregs[0x0b] = 0x0c; - fregs[0x20] = 0x01; + if (dev->type < 5) + fregs[0x20] = 0x01; fregs[0x3d] = 0x04; - fregs[0x60] = (dev->type > 3) ? 0x10: 0x00; + if (dev->type > 4) + fregs[0x60] = (dev->type > 3) ? 0x10 : 0x00; if (dev->type < 5) { fregs[0x6a] = (dev->type == 3) ? 0x01 : 0x00; fregs[0xc1] = 0x20; diff --git a/src/io.c b/src/io.c index 5896a54de..5aaedc8d6 100644 --- a/src/io.c +++ b/src/io.c @@ -154,13 +154,14 @@ io_removehandler(uint16_t base, int size, void *priv) { int c; - io_t *p; + io_t *p, *q; for (c = 0; c < size; c++) { p = io[base + c]; if (!p) continue; while(p) { + q = p->next; if ((p->inb == inb) && (p->inw == inw) && (p->inl == inl) && (p->outb == outb) && (p->outw == outw) && (p->outl == outl) && @@ -177,7 +178,7 @@ io_removehandler(uint16_t base, int size, p = NULL; break; } - p = p->next; + p = q; } } } @@ -251,7 +252,7 @@ io_removehandler_interleaved(uint16_t base, int size, void *priv) { int c; - io_t *p; + io_t *p, *q; size <<= 2; for (c = 0; c < size; c += 2) { @@ -259,6 +260,7 @@ io_removehandler_interleaved(uint16_t base, int size, if (!p) return; while(p) { + q = p->next; if ((p->inb == inb) && (p->inw == inw) && (p->inl == inl) && (p->outb == outb) && (p->outw == outw) && (p->outl == outl) && @@ -270,7 +272,7 @@ io_removehandler_interleaved(uint16_t base, int size, free(p); break; } - p = p->next; + p = q; } } } @@ -328,8 +330,11 @@ outb(uint16_t port, uint8_t val) p = p->next; } - if (!found) + if (!found) { sub_cycles(io_delay); + if (cpu_use_dynarec && (port == 0xeb)) + update_tsc(); + } io_log("(%i, %i, %04i) outb(%04X, %02X)\n", in_smm, found, qfound, port, val); @@ -418,8 +423,11 @@ outw(uint16_t port, uint16_t val) } } - if (!found) + if (!found) { sub_cycles(io_delay); + if (cpu_use_dynarec && (port == 0xeb)) + update_tsc(); + } io_log("(%i, %i, %04i) outw(%04X, %04X)\n", in_smm, found, qfound, port, val); @@ -542,8 +550,11 @@ outl(uint16_t port, uint32_t val) } } - if (!found) + if (!found) { sub_cycles(io_delay); + if (cpu_use_dynarec && (port == 0xeb)) + update_tsc(); + } io_log("(%i, %i, %04i) outl(%04X, %08X)\n", in_smm, found, qfound, port, val); diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 069d80933..4e1bc3743 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -2048,7 +2048,7 @@ do_command: break; case 0x61: - ppi.pb = val; + ppi.pb = (ppi.pb & 0x10) | (val & 0x0f); speaker_update(); speaker_gated = val & 1; diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index c1ccd5d39..ddc349033 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -38,6 +38,25 @@ #include <86box/video.h> #include <86box/machine.h> +int +machine_at_mr286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved(L"roms/machines/mr286/V000B200-1", + L"roms/machines/mr286/V000B200-2", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + 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) @@ -120,26 +139,6 @@ machine_at_ama932j_init(const machine_t *model) return ret; } -int -machine_at_px286_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved(L"roms/machines/px286/286-Headland-LO.BIN", - L"roms/machines/px286/286-Headland-HI.BIN", - 0x000f0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_ide_init(model); - device_add(&keyboard_at_device); - device_add(&fdc_at_device); - device_add(&headland_device); - - return ret; -} - int machine_at_quadt286_init(const machine_t *model) { @@ -201,6 +200,26 @@ machine_at_neat_ami_init(const machine_t *model) return ret; } +int +machine_at_px286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/px286/KENITEC.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&keyboard_at_device); + device_add(&fdc_at_device); + device_add(&neat_device); + + return ret; +} + + int machine_at_goldstar386_init(const machine_t *model) { @@ -282,6 +301,21 @@ machine_at_award286_init(const machine_t *model) return ret; } +int +machine_at_gdc212m_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/gdc212m/gdc212m_72h.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 0); + + return ret; +} int machine_at_gw286ct_init(const machine_t *model) diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 3832ddc21..4bed55f9c 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -39,9 +39,30 @@ #include <86box/hdc.h> #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> +int +machine_at_acc386_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/acc386/acc386.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&acc2168_device); + device_add(&keyboard_at_ami_device); + device_add(&fdc_at_device); + + return ret; +} + int machine_at_ecs386_init(const machine_t *model) { @@ -184,7 +205,6 @@ machine_at_opti495_ami_init(const machine_t *model) } -#if defined(DEV_BRANCH) && defined(USE_MR495) int machine_at_opti495_mr_init(const machine_t *model) { @@ -200,7 +220,6 @@ machine_at_opti495_mr_init(const machine_t *model) return ret; } -#endif static void @@ -408,7 +427,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) { @@ -432,12 +451,14 @@ machine_at_486sp3g_init(const machine_t *model) pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_pci_device); + 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); - device_add(&intel_flash_bxt_ami_device); + device_add(&pc87306_device); /*PC87332*/ + device_add(&sst_flash_29ee010_device); + device_add(&ncr53c810_pci_device); device_add(&i420zx_device); return ret; } +#endif diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 628a58a5c..cdc86cdfb 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -114,7 +114,7 @@ machine_at_6bxc_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&um8669f_device); /*ITE 8671*/ device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } @@ -158,13 +158,11 @@ machine_at_p2bls_init(const machine_t *model) { /* fan speeds */ 3000, /* Chassis */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ 0, /* unused */ - 27, /* CPU */ - 0 + 27 /* CPU */ }, { /* voltages */ 2050, /* VCORE (2.05V by default) */ 0, /* unused */ @@ -172,8 +170,7 @@ machine_at_p2bls_init(const machine_t *model) 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) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) @@ -222,13 +219,11 @@ machine_at_p3bf_init(const machine_t *model) { /* fan speeds */ 3000, /* Chassis */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ - 0, /* unused */ - 30, /* CPU */ - 0 + 30, /* JTPWR */ + 30 /* CPU */ }, { /* voltages */ 2050, /* VCORE (2.05V by default) */ 0, /* unused */ @@ -236,8 +231,7 @@ machine_at_p3bf_init(const machine_t *model) RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 3, 1), /* +12V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 59, 20), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUM2) @@ -263,13 +257,13 @@ machine_at_bf6_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 3, 1, 2); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 1, 4, 3); - pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 3, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 1, 4, 3); + pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); 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); @@ -277,22 +271,23 @@ machine_at_bf6_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } int -machine_at_borapro_init(const machine_t *model) -{ - //AMI 440ZX Board. Packard Bell OEM of the MSI-6168 - //MIGHT REQUIRE MORE EXCESSIVE TESTING! - //Reports emmersive amounts of RAM like few Intel OEM boards - //we have. +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/borapro/MS6168V2.50", + ret = bios_load_linear(L"roms/machines/p6sba/SBAB21.ROM", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -302,18 +297,81 @@ machine_at_borapro_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); - device_add(&i440zx_device); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + 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); device_add(&piix4e_device); - device_add(&w83977ef_device); + device_add(&w83977tf_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); - spd_register(SPD_TYPE_SDRAM, 0x3, 256); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + hwm_values_t machine_hwm = { + { /* fan speeds */ + 3000, /* CPU1 */ + 0, /* CPU2 */ + 3000 /* Thermal Control */ + }, { /* temperatures */ + 0, /* unused */ + 30, /* CPU1 */ + 0 /* unused (CPU2?) */ + }, { /* voltages */ + 2050, /* CPU1 (2.05V by default) */ + 0, /* CPU2 */ + 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; +} + +#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 CPU's + + int ret; + + ret = bios_load_linear(L"roms/machines/tsunamiatx/bx46200f.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 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(&pc87306_device); //PC87309 + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } +#endif \ No newline at end of file diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c new file mode 100644 index 000000000..b85ce9a83 --- /dev/null +++ b/src/machine/m_at_slot2.c @@ -0,0 +1,110 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of Slot 2 machines. + * + * Slot 2 is quite a rare type of Slot. Used mostly by Pentium II & III Xeons + * These boards were also capable to take Slot 1 CPU's using Slot 2 to 1 adapters. + * + * Authors: Miran Grca, + * + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/keyboard.h> +#include <86box/intel_flash.h> +#include <86box/intel_sio.h> +#include <86box/piix.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_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", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + 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(&piix4e_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + + hwm_values_t machine_hwm = { + { /* fan speeds */ + 3000, /* CPU1 */ + 0, /* CPU2 */ + 3000 /* Thermal Control */ + }, { /* temperatures */ + 0, /* unused */ + 30, /* CPU1 */ + 20 /* unused (CPU2?) */ + }, { /* voltages */ + 2050, /* CPU1 (2.05V by default) */ + 0, /* CPU2 */ + 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; +} +#endif \ No newline at end of file diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 009999f07..8852ee804 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -41,6 +41,63 @@ #include "cpu.h" #include <86box/machine.h> +#if defined(DEV_BRANCH) && defined(NO_SIO) +int +machine_at_s370slm_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/s370slm/3LM1202.rom", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + 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); /*i440LX*/ + device_add(&piix4e_device); + device_add(&w83977tf_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + hwm_values_t machine_hwm = { + { /* fan speeds */ + 3000, /* CPU */ + 3000, /* Fan 2 */ + 3000 /* Chassis */ + }, { /* temperatures */ + 0, /* unused */ + 30, /* CPU */ + 0 /* unused */ + }, { /* voltages */ + 2050, /* CPU1 (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) */ + } + }; + hwm_set_values(machine_hwm); + device_add(&w83781d_device); + + return ret; +} +#endif + int machine_at_cubx_init(const machine_t *model) { @@ -75,13 +132,11 @@ machine_at_cubx_init(const machine_t *model) { /* fan speeds */ 3000, /* Chassis */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ - 0, /* unused */ - 30, /* CPU */ - 0 + 30, /* JTPWR */ + 30 /* CPU */ }, { /* voltages */ 2050, /* VCORE (2.05V by default) */ 0, /* unused */ @@ -89,8 +144,7 @@ machine_at_cubx_init(const machine_t *model) 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, 59, 20), /* -12V (divider values bruteforced) */ - RESISTOR_DIVIDER(5000, 1, 2), /* -5V (divider values bruteforced) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; hwm_set_values(machine_hwm); @@ -135,12 +189,9 @@ machine_at_atc7020bxii_init(const machine_t *model) int machine_at_63a_init(const machine_t *model) { - - /* 440ZX Board. 440ZX is basically an underpowered 440BX. There no - difference between to chipsets other than the name. */ int ret; - ret = bios_load_linear(L"roms/machines/63a/63a-q3.bin", + ret = bios_load_linear(L"roms/machines/63a1/63a-q3.bin", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -183,19 +234,18 @@ machine_at_apas3_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&via_apro_device); device_add(&via_vt82c586b_device); device_add(&fdc37c669_device); - device_add(&keyboard_ps2_pci_device); + device_add(&keyboard_ps2_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); return ret; } - diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index a73cba1d9..59e237567 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -351,37 +351,6 @@ machine_at_mb500n_init(const machine_t *model) return ret; } - -int -machine_at_president_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/president/bios.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(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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&i430fx_device); - device_add(&piix_device); - device_add(&keyboard_ps2_pci_device); - device_add(&w83877f_president_device); - device_add(&intel_flash_bxt_device); - - return ret; -} - - #if defined(DEV_BRANCH) && defined(USE_VECTRA54) int machine_at_vectra54_init(const machine_t *model) diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index d18132a49..c4792518c 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -45,6 +45,65 @@ #include "cpu.h" #include <86box/machine.h> +int +machine_at_chariot_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/chariot/P5IV183.ROM", + 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(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 2, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 3, 2, 1); + + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&pc87306_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + +int +machine_at_mr586_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/mr586/TRITON.BIO", + 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(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); + + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + + return ret; +} static void machine_at_thor_common_init(const machine_t *model, int mr) @@ -84,7 +143,6 @@ machine_at_thor_init(const machine_t *model) } -#if defined(DEV_BRANCH) && defined(USE_MRTHOR) int machine_at_mrthor_init(const machine_t *model) { @@ -100,7 +158,6 @@ machine_at_mrthor_init(const machine_t *model) return ret; } -#endif int @@ -136,7 +193,6 @@ machine_at_pb640_init(const machine_t *model) return ret; } - const device_t * at_pb640_get_device(void) { @@ -432,7 +488,7 @@ machine_at_p55tvp4_init(const machine_t *model) pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); @@ -589,6 +645,7 @@ machine_at_p55xb2_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); // device_add(&ali_m513x_device); device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } @@ -621,18 +678,17 @@ machine_at_tx97_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83877tf_acorp_device); device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); hwm_values_t machine_hwm = { { /* fan speeds */ 3000, /* Chassis */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Power */ }, { /* temperatures */ 30, /* MB */ 0, /* unused */ - 27, /* CPU */ - 0 + 8 /* CPU */ }, { /* voltages */ 3300, /* VCORE (3.3V by default) */ 0, /* unused */ @@ -640,20 +696,22 @@ machine_at_tx97_init(const machine_t *model) 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) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; /* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V). Pentium MMX: 2.8 V. AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233. AMD K6 Model 7: 2.2 V. */ - if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMMMX) - machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6_2) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ + switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { + case CPU_PENTIUMMMX: + machine_hwm.voltages[0] = 2800; + break; + case CPU_K6: + case CPU_K6_2: + machine_hwm.voltages[0] = 2200; + break; + } hwm_set_values(machine_hwm); device_add(&w83781d_device); @@ -688,31 +746,7 @@ machine_at_ym430tx_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000, /* Power */ - 0 - }, { /* temperatures */ - 30, /* MB */ - 0, /* unused */ - 27, /* CPU */ - 0 - }, { /* 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) */ - 0 - } - }; - hwm_set_values(machine_hwm); - device_add(&w83781d_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } @@ -743,6 +777,7 @@ machine_at_586t2_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&um8669f_device); /*Placeholder for ITE 8679*/ device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } @@ -773,41 +808,7 @@ machine_at_807ds_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&um8669f_device); /*Placeholder for ITE 8679*/ device_add(&intel_flash_bxt_device); - - hwm_values_t machine_hwm = { - { /* fan speeds */ - 3000, /* Chassis */ - 3000, /* CPU */ - 3000, /* Power */ - 0 - }, { /* temperatures */ - 30, /* MB */ - 0, /* unused */ - 27, /* CPU */ - 0 - }, { /* voltages */ - 3300, /* VCORE (3.3V 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) */ - 0 - } - }; - /* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V). - Pentium MMX: 2.8 V. - AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233. - AMD K6 Model 7: 2.2 V. */ - if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMMMX) - machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6_2) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ - hwm_set_values(machine_hwm); - device_add(&w83781d_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } @@ -838,52 +839,52 @@ machine_at_p5mms98_init(const machine_t *model) device_add(&keyboard_ps2_ami_pci_device); device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); hwm_values_t machine_hwm = { { /* fan speeds */ - 3000, /* Chassis */ + 3000, /* Thermal */ 3000, /* CPU */ - 3000, /* Power */ - 0 + 3000 /* Chassis */ }, { /* temperatures */ - 30, /* MB */ 0, /* unused */ - 27, /* CPU */ - 0 + 30 /* CPU */ }, { /* voltages */ 3300, /* VCORE (3.3V by default) */ - 0, /* unused */ + 3300, /* VIO (3.3V) */ 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) */ - 0 + RESISTOR_DIVIDER(5000, 1, 2) /* -5V (divider values bruteforced) */ } }; /* Pentium, Pentium OverDrive MMX, Pentium Mobile MMX: 3.3V (real Pentium Mobile MMX is 2.45V). Pentium MMX: 2.8 V. AMD K6 Model 6: 2.9 V for 166/200, 3.2 V for 233. AMD K6 Model 7: 2.2 V. */ - if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMMMX) - machine_hwm.voltages[0] = 2800; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ - else if (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_K6_2) - machine_hwm.voltages[0] = 2200; /* set higher VCORE (2.8V) for Pentium MMX */ + switch (model->cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { + case CPU_PENTIUMMMX: + machine_hwm.voltages[0] = 2800; + break; + case CPU_K6: + case CPU_K6_2: + machine_hwm.voltages[0] = 2200; + break; + } hwm_set_values(machine_hwm); - device_add(&w83781d_device); + device_add(&lm78_device); + device_add(&lm75_1_4a_device); return ret; } -#if defined(DEV_BRANCH) && defined(NO_SIO) int -machine_at_tx100_init(const machine_t *model) +machine_at_ficva502_init(const machine_t *model) { int ret; - ret = bios_load_linear(L"roms/machines/tx100/T100108E.rom", + ret = bios_load_linear(L"roms/machines/ficva502/VA502bp.BIN", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -896,18 +897,47 @@ machine_at_tx100_init(const machine_t *model) 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(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); device_add(&via_vpx_device); device_add(&via_vt82c586b_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&um8669f_device); //IT8661F + device_add(&keyboard_ps2_pci_device); + device_add(&fdc37c669_device); device_add(&sst_flash_29ee010_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 256); return ret; } +int +machine_at_ficpa2012_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/ficpa2012/113jb16.awd", + 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(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(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + device_add(&via_vp3_device); + device_add(&via_vt82c586b_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83877f_device); + device_add(&sst_flash_39sf010_device); + + return ret; +} + +#if defined(DEV_BRANCH) && defined(NO_SIO) int machine_at_advanceii_init(const machine_t *model) { @@ -932,7 +962,6 @@ machine_at_advanceii_init(const machine_t *model) device_add(&keyboard_ps2_pci_device); device_add(&um8669f_device); //IT8661F device_add(&sst_flash_39sf010_device); - spd_register(SPD_TYPE_SDRAM, 0xF, 64); return ret; } diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index dba53237b..fd7b5bcea 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -158,38 +158,6 @@ machine_at_m6mi_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(NO_SIO) -int -machine_at_vs440fx_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear_combined2(L"roms/machines/vs440fx/1011CS1_.BIO", - L"roms/machines/vs440fx/1011CS1_.BI1", - L"roms/machines/vs440fx/1011CS1_.BI2", - L"roms/machines/vs440fx/1011CS1_.BI3", - L"roms/machines/vs440fx/1011CS1_.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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&i440fx_device); - device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - //device_add(&pc87307_device); - device_add(&pc87306_device); - device_add(&intel_flash_bxt_ami_device); - - return ret; -} -#endif - void machine_at_p65up5_common_init(const machine_t *model, const device_t *northbridge) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d4fd4b315..291c6ce24 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -37,11 +37,13 @@ #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) #define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"Cyrix", cpus_6x863V}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_S73VCH {{ "Intel", cpus_Pentium3V}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"Cyrix", cpus_6x86SS7}, {"", NULL}} #else #define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_S73VCH {{ "Intel", cpus_Pentium3V}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"", NULL}, {"", NULL}} #endif @@ -49,11 +51,13 @@ #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) #define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x863V}, {"", NULL}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_S73VCH {{ "Intel", cpus_Pentium3V}, {"", NULL }, {"", NULL}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"Cyrix", cpus_6x86SS7}, {"", NULL}} #else #define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_S73VCH {{ "Intel", cpus_Pentium3V}, {"", NULL }, {"", NULL}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"", NULL}, {"", NULL}} #define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"", NULL}, {"", NULL}} #endif @@ -106,10 +110,12 @@ const machine_t machines[] = { { "[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 }, @@ -153,15 +159,14 @@ const machine_t machines[] = { /* 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] ECS 386/32", "ecs386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_ecs386_init, NULL }, + { "[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] 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 }, /* 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 }, -#if defined(DEV_BRANCH) && defined(USE_MR495) { "[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 }, -#endif /* 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 }, @@ -184,9 +189,7 @@ const machine_t machines[] = { #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 }, -#if defined(DEV_BRANCH) && defined(USE_MR495) { "[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 }, -#endif { "[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 }, #if defined(DEV_BRANCH) && defined(USE_PS2M70T4) @@ -194,7 +197,9 @@ const machine_t machines[] = { #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 }, @@ -208,7 +213,6 @@ const machine_t machines[] = { #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 }, - /* 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 }, @@ -222,16 +226,15 @@ const machine_t machines[] = { { "[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 }, - { "[Socket 5 FX] President Award 430FX PCI","president", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_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 }, -#if defined(DEV_BRANCH) && defined(USE_MRTHOR) { "[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 }, -#endif { "[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 }, /* 430HX */ @@ -263,13 +266,15 @@ const machine_t machines[] = { { "[Socket 7 TX] Iwill P55XB2", "p55xb2", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p55xb2_init, NULL }, { "[Socket 7 TX] PC Partner TXA807DS", "807ds", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_807ds_init, NULL }, #endif - { "[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 }, + { "[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 }, + -#if defined(DEV_BRANCH) && defined(NO_SIO) /* Apollo VPX */ - { "[Socket 7 VPX] Zida Tomato TX100", "tx100", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_tx100_init, NULL }, + { "[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 }, /* 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 }, +#if defined(DEV_BRANCH) && defined(NO_SIO) { "[Socket 7 VP3] QDI Advance II", "advanceii", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_advanceii_init, NULL }, #endif @@ -284,9 +289,6 @@ const machine_t machines[] = { { "[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, 512, 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 }, -#if defined(DEV_BRANCH) && defined(NO_SIO) - { "[Socket 8 FX] Intel VS440FX", "vs440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_vs440fx_init, NULL }, -#endif { "[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 }, @@ -306,11 +308,22 @@ const machine_t machines[] = { { "[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 }, +#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, 8, 1024, 8, 255, machine_at_tsunamiatx_init, NULL }, +#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 }, - /* 440ZX */ - { "[Slot 1 ZX] Packard Bell Bora Pro", "borapro", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_borapro_init, NULL }, + /* Slot 2 machines */ + /* 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 /* PGA370 machines */ + /* 440LX */ +#if defined(DEV_BRANCH) && defined(NO_SIO) + { "[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 }, +#endif /* 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 }, diff --git a/src/pc.c b/src/pc.c index 55c0f8356..9bc25aa54 100644 --- a/src/pc.c +++ b/src/pc.c @@ -78,6 +78,15 @@ #include <86box/plat_midi.h> +/* Stuff that used to be globally declared in plat.h but is now extern there + and declared here instead. */ +int dopause, /* system is paused */ + doresize, /* screen resize requested */ + quited; /* system exit requested */ +uint64_t timer_freq; +char emu_version[200]; /* version ID string */ + + /* Commandline options. */ int dump_on_exit = 0; /* (O) dump regs on exit */ int do_dump_config = 0; /* (O) dump config on load */ @@ -101,7 +110,7 @@ int window_w, window_h, /* (C) window size and */ window_x, window_y, /* position info */ window_remember, vid_resize, /* (C) allow resizing */ - invert_display, /* (C) invert the display */ + invert_display = 0, /* (C) invert the display */ suppress_overscan = 0; /* (C) suppress overscans */ int scale = 0; /* (C) screen scale factor */ int vid_api = 0; /* (C) video renderer */ @@ -141,8 +150,8 @@ extern int int fps, framecount; /* emulator % */ -int CPUID; -int output; +extern int CPUID; +extern int output; int atfullspeed; int clockrate; diff --git a/src/pit.c b/src/pit.c index b04f23001..61d18e317 100644 --- a/src/pit.c +++ b/src/pit.c @@ -1017,7 +1017,7 @@ pit_set_clock(int clock) xt_cpu_multi <<= 32ULL; /* Delay for empty I/O ports. */ - io_delay = (int) round(((double) machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed) / 1000000.0); + io_delay = (int) round(((double) machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed) / 3000000.0); MDACONST = (uint64_t) (cpuclock / 2032125.0 * (double)(1ull << 32)); HERCCONST = MDACONST; diff --git a/src/postcard.c b/src/postcard.c index 134af04b7..91275ee16 100644 --- a/src/postcard.c +++ b/src/postcard.c @@ -26,6 +26,7 @@ #include <86box/plat.h> #include <86box/ui.h> #include <86box/postcard.h> +#include "cpu.h" static uint16_t postcard_port; @@ -98,6 +99,9 @@ postcard_write(uint16_t port, uint8_t val, void *priv) if (postcard_written && val == postcard_code) return; + if (val == 0x13) + pclog("[%04X:%08X] POST 13\n", CS, cpu_state.pc); + postcard_prev_code = postcard_code; postcard_code = val; if (postcard_written < 2) diff --git a/src/ppi.c b/src/ppi.c index d9eb03cb3..c70d01ece 100644 --- a/src/ppi.c +++ b/src/ppi.c @@ -20,8 +20,8 @@ PPI ppi; int ppispeakon; -void ppi_reset(void) +void +ppi_reset(void) { - ppi.pa=0x0; - ppi.pb=0x40; + memset(&ppi, 0x00, sizeof(PPI)); } diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 106e2bb87..0c4748505 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -273,7 +273,7 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = { 0, 0 }, { 0, 0 }, { GPMODE_CDROM_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0x8E, 0xE, 0xFF, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0x8E, 0xE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0, 0 }, { 0, 0 }, { 0, 0 }, diff --git a/src/smbus.c b/src/smbus.c index d24435cc7..d86b167c1 100644 --- a/src/smbus.c +++ b/src/smbus.c @@ -33,7 +33,7 @@ typedef struct _smbus_ { uint8_t (*read_byte)(uint8_t addr, void *priv); uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv); uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv); - uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv); + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv); void (*write_byte)(uint8_t addr, uint8_t val, void *priv); void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv); @@ -69,18 +69,6 @@ smbus_log(const char *fmt, ...) #endif -#ifdef ENABLE_SMBUS_LOG -static uint8_t smbus_null_read_byte(uint8_t addr, void *priv) { smbus_log("SMBus: read_byte(%02x)\n", addr); return(0xff); } -static uint8_t smbus_null_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) { smbus_log("SMBus: read_byte_cmd(%02x, %02x)\n", addr, cmd); return(0xff); } -static uint16_t smbus_null_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) { smbus_log("SMBus: read_word_cmd(%02x, %02x)\n", addr, cmd); return(0xffff); } -static uint8_t smbus_null_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv) { smbus_log("SMBus: read_block_cmd(%02x, %02x)\n", addr, cmd); return(0x00); }; -static void smbus_null_write_byte(uint8_t addr, uint8_t val, void *priv) { smbus_log("SMBus: write_byte(%02x, %02x)\n", addr, val); } -static void smbus_null_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv) { smbus_log("SMBus: write_byte_cmd(%02x, %02x, %02x)\n", addr, cmd, val); } -static void smbus_null_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv) { smbus_log("SMBus: write_word_cmd(%02x, %02x, %04x)\n", addr, cmd, val); } -static void smbus_null_write_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv) { smbus_log("SMBus: write_block_cmd(%02x, %02x, %02x)\n", addr, cmd, len); } -#endif - - void smbus_init(void) { @@ -106,26 +94,8 @@ smbus_init(void) p = NULL; } -#ifdef ENABLE_SMBUS_LOG - /* smbus[c] should be the only handler, pointing at the NULL catch handler. */ - p = (smbus_t *) malloc(sizeof(smbus_t)); - memset(p, 0, sizeof(smbus_t)); - smbus[c] = smbus_last[c] = p; - p->next = NULL; - p->prev = NULL; - p->read_byte = smbus_null_read_byte; - p->read_byte_cmd = smbus_null_read_byte_cmd; - p->read_word_cmd = smbus_null_read_word_cmd; - p->read_block_cmd = smbus_null_read_block_cmd; - p->write_byte = smbus_null_write_byte; - p->write_byte_cmd = smbus_null_write_byte_cmd; - p->write_word_cmd = smbus_null_write_word_cmd; - p->write_block_cmd = smbus_null_write_block_cmd; - p->priv = NULL; -#else /* smbus[c] should be NULL. */ smbus[c] = smbus_last[c] = NULL; -#endif } } @@ -135,7 +105,7 @@ smbus_sethandler(uint8_t base, int size, uint8_t (*read_byte)(uint8_t addr, void *priv), uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), - uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), void (*write_byte)(uint8_t addr, uint8_t val, void *priv), void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), @@ -180,7 +150,7 @@ smbus_removehandler(uint8_t base, int size, uint8_t (*read_byte)(uint8_t addr, void *priv), uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), - uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), void (*write_byte)(uint8_t addr, uint8_t val, void *priv), void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), @@ -223,7 +193,7 @@ smbus_handler(int set, uint8_t base, int size, uint8_t (*read_byte)(uint8_t addr, void *priv), uint8_t (*read_byte_cmd)(uint8_t addr, uint8_t cmd, void *priv), uint16_t (*read_word_cmd)(uint8_t addr, uint8_t cmd, void *priv), - uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, void *priv), + uint8_t (*read_block_cmd)(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv), void (*write_byte)(uint8_t addr, uint8_t val, void *priv), void (*write_byte_cmd)(uint8_t addr, uint8_t cmd, uint8_t val, void *priv), void (*write_word_cmd)(uint8_t addr, uint8_t cmd, uint16_t val, void *priv), @@ -262,6 +232,8 @@ smbus_read_byte(uint8_t addr) } } + smbus_log("SMBus: read_byte(%02X) = %02X\n", addr, ret); + return(ret); } @@ -283,6 +255,8 @@ smbus_read_byte_cmd(uint8_t addr, uint8_t cmd) } } + smbus_log("SMBus: read_byte_cmd(%02X, %02X) = %02X\n", addr, cmd, ret); + return(ret); } @@ -304,11 +278,13 @@ smbus_read_word_cmd(uint8_t addr, uint8_t cmd) } } + smbus_log("SMBus: read_word_cmd(%02X, %02X) = %04X\n", addr, cmd, ret); + return(ret); } uint8_t -smbus_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data) +smbus_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len) { uint8_t ret = 0; smbus_t *p; @@ -318,13 +294,15 @@ smbus_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data) if (p) { while(p) { if (p->read_block_cmd) { - ret = MAX(ret, p->read_block_cmd(addr, cmd, data, p->priv)); + ret = MAX(ret, p->read_block_cmd(addr, cmd, data, len, p->priv)); found++; } p = p->next; } } + smbus_log("SMBus: read_block_cmd(%02X, %02X) = %02X\n", addr, cmd, len); + return(ret); } @@ -346,6 +324,8 @@ smbus_write_byte(uint8_t addr, uint8_t val) } } + smbus_log("SMBus: write_byte(%02X, %02X)\n", addr, val); + return; } @@ -366,6 +346,8 @@ smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val) } } + smbus_log("SMBus: write_byte_cmd(%02X, %02X, %02X)\n", addr, cmd, val); + return; } @@ -386,6 +368,8 @@ smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val) } } + smbus_log("SMBus: write_word_cmd(%02X, %02X, %04X)\n", addr, cmd, val); + return; } @@ -406,5 +390,7 @@ smbus_write_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len) } } + smbus_log("SMBus: write_block_cmd(%02X, %02X, %02X)\n", addr, cmd, len); + return; } diff --git a/src/smbus_piix4.c b/src/smbus_piix4.c index 8a1a0a762..ad8ff64d0 100644 --- a/src/smbus_piix4.c +++ b/src/smbus_piix4.c @@ -157,7 +157,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) break; case 0x5: /* block R/W */ if (smbus_read) - dev->data0 = smbus_read_block_cmd(smbus_addr, dev->cmd, dev->data); + dev->data0 = smbus_read_block_cmd(smbus_addr, dev->cmd, dev->data, SMBUS_PIIX4_BLOCK_DATA_SIZE); else smbus_write_block_cmd(smbus_addr, dev->cmd, dev->data, dev->data0); dev->next_stat = 0x2; diff --git a/src/spd.c b/src/spd.c index 5b00c1178..84ba3eb84 100644 --- a/src/spd.c +++ b/src/spd.c @@ -27,16 +27,11 @@ #include <86box/spd.h> -#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define SPD_ROLLUP(x) ((x) >= 16 ? ((x) - 15) : (x)) -typedef struct _spd_ { - uint8_t slot; - uint8_t addr_register; -} spd_t; - - -device_t *spd_devices[SPD_MAX_SLOTS]; +spd_t *spd_devices[SPD_MAX_SLOTS]; uint8_t spd_data[SPD_MAX_SLOTS][SPD_DATA_SIZE]; @@ -78,11 +73,29 @@ spd_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv) { spd_t *dev = (spd_t *) priv; uint8_t ret = *(spd_data[dev->slot] + cmd); - spd_log("SPD: read(%02x, %02x) = %02x\n", addr, cmd, ret); + spd_log("SPD: read(%02X, %02X) = %02X\n", addr, cmd, ret); return ret; } +uint16_t +spd_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv) +{ + return (spd_read_byte_cmd(addr, cmd + 1, priv) << 8) | spd_read_byte_cmd(addr, cmd, priv); +} + + +uint8_t +spd_read_block_cmd(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t len, void *priv) +{ + uint8_t read = 0; + for (uint8_t i = cmd; i < len && i < SPD_DATA_SIZE; i++) { + data[read++] = spd_read_byte_cmd(addr, i, priv); + } + return read; +} + + void spd_write_byte(uint8_t addr, uint8_t val, void *priv) { @@ -99,7 +112,7 @@ spd_close(void *priv) spd_log("SPD: closing slot %d (SMBus %02Xh)\n", dev->slot, SPD_BASE_ADDR + dev->slot); smbus_removehandler(SPD_BASE_ADDR + dev->slot, 1, - spd_read_byte, spd_read_byte_cmd, NULL, NULL, + spd_read_byte, spd_read_byte_cmd, spd_read_word_cmd, spd_read_block_cmd, spd_write_byte, NULL, NULL, NULL, dev); @@ -110,17 +123,14 @@ spd_close(void *priv) static void * spd_init(const device_t *info) { - spd_t *dev = (spd_t *) malloc(sizeof(spd_t)); - memset(dev, 0, sizeof(spd_t)); - - dev->slot = info->local; + spd_t *dev = spd_devices[info->local]; spd_log("SPD: initializing slot %d (SMBus %02Xh)\n", dev->slot, SPD_BASE_ADDR + dev->slot); smbus_sethandler(SPD_BASE_ADDR + dev->slot, 1, - spd_read_byte, spd_read_byte_cmd, NULL, NULL, - spd_write_byte, NULL, NULL, NULL, - dev); + spd_read_byte, spd_read_byte_cmd, spd_read_word_cmd, spd_read_block_cmd, + spd_write_byte, NULL, NULL, NULL, + dev); return dev; } @@ -139,8 +149,8 @@ log2_ui16(uint16_t i) int comp_ui16_rev(const void *elem1, const void *elem2) { - uint16_t a = *((uint16_t *)elem1); - uint16_t b = *((uint16_t *)elem2); + uint16_t a = *((uint16_t *) elem1); + uint16_t b = *((uint16_t *) elem2); return ((a > b) ? -1 : ((a < b) ? 1 : 0)); } @@ -149,7 +159,8 @@ void spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) { uint8_t slot, slot_count, vslot, next_empty_vslot, i, split; - uint16_t min_module_size, total_size, vslots[SPD_MAX_SLOTS]; + uint16_t min_module_size, total_size, vslots[SPD_MAX_SLOTS], asym; + device_t *info; spd_edo_t *edo_data; spd_sdram_t *sdram_data; @@ -184,7 +195,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) /* populate slot */ vslots[vslot] = (1 << log2_ui16(MIN(total_size, max_module_size))); if (total_size >= vslots[vslot]) { - spd_log("SPD: vslot %d = %d MB\n", vslot, vslots[vslot]); + spd_log("SPD: initial vslot %d = %d MB\n", vslot, vslots[vslot]); total_size -= vslots[vslot]; } else { vslots[vslot] = 0; @@ -192,8 +203,21 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) } } - if (total_size > 0) /* did we populate everything? */ - spd_log("SPD: not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size); + /* did we populate all the RAM? */ + if (total_size) { + /* work backwards to add the missing RAM as asymmetric modules */ + vslot = slot_count - 1; + do { + asym = (1 << log2_ui16(MIN(total_size, vslots[vslot]))); + if (vslots[vslot] + asym <= max_module_size) { + vslots[vslot] += asym; + total_size -= asym; + } + } while (vslot-- > 0 && total_size); + + if (total_size) /* still not enough */ + spd_log("SPD: not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size); + } /* populate empty vslots by splitting modules... */ split = (total_size == 0); /* ...if possible */ @@ -201,8 +225,8 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) /* look for a module to split */ split = 0; for (vslot = 0; vslot < slot_count; vslot++) { - if (vslots[vslot] < (min_module_size << 1)) - continue; /* no module here or module is too small to be split */ + if ((vslots[vslot] < (min_module_size << 1)) || (vslots[vslot] != (1 << log2_ui16(vslots[vslot])))) + continue; /* no module here, module is too small to be split, or asymmetric module */ /* find next empty vslot */ next_empty_vslot = 0; @@ -230,14 +254,28 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) if (!(slot_mask & (1 << slot))) continue; /* slot disabled */ - spd_log("SPD: registering slot %d = vslot %d = %d MB\n", slot, vslot, vslots[vslot]); + info = (device_t *) malloc(sizeof(device_t)); + memset(info, 0, sizeof(device_t)); + info->name = "Serial Presence Detect ROM"; + info->local = slot; + info->init = spd_init; + info->close = spd_close; - spd_devices[slot] = (device_t *) malloc(sizeof(device_t)); - memset(spd_devices[slot], 0, sizeof(device_t)); - spd_devices[slot]->name = "Serial Presence Detect ROM"; - spd_devices[slot]->local = slot; - spd_devices[slot]->init = spd_init; - spd_devices[slot]->close = spd_close; + spd_devices[slot] = (spd_t *) malloc(sizeof(spd_t)); + memset(spd_devices[slot], 0, sizeof(spd_t)); + spd_devices[slot]->info = info; + spd_devices[slot]->slot = slot; + spd_devices[slot]->size = vslots[vslot]; + + /* determine the second row size, from which the first row size can be obtained */ + asym = (vslots[vslot] - (1 << log2_ui16(vslots[vslot]))); /* separate the powers of 2 */ + if (!asym) /* is the module asymmetric? */ + asym = (vslots[vslot] >> 1); /* symmetric, therefore divide by 2 */ + + spd_devices[slot]->row1 = (vslots[vslot] - asym); + spd_devices[slot]->row2 = asym; + + spd_log("SPD: registering slot %d = vslot %d = %d MB (%d/%d)\n", slot, vslot, vslots[vslot], spd_devices[slot]->row1, spd_devices[slot]->row2); switch (ram_type) { case SPD_TYPE_FPM: @@ -245,13 +283,18 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data = (spd_edo_t *) &spd_data[slot]; memset(edo_data, 0, sizeof(spd_edo_t)); - /* FIXME: very little information about EDO SPD is available, - let alone software to interpret it correctly. */ + /* EDO SPD is specified by JEDEC and present in some modules, but + most utilities cannot interpret it correctly. SIV32 at least gets + the module capacities right, so it was used as a reference here. */ edo_data->bytes_used = 0x80; edo_data->spd_size = 0x08; edo_data->mem_type = ram_type; - edo_data->row_bits = 6 + log2_ui16(vslots[vslot]); + edo_data->row_bits = SPD_ROLLUP(7 + log2_ui16(spd_devices[slot]->row1)); /* first row */ edo_data->col_bits = 9; + if (spd_devices[slot]->row1 != spd_devices[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */ + edo_data->row_bits |= (SPD_ROLLUP(7 + log2_ui16(spd_devices[slot]->row2)) << 4); /* second row, if different from first */ + edo_data->col_bits |= (9 << 4); /* same as first row, but just in case */ + } edo_data->banks = 2; edo_data->data_width_lsb = 64; edo_data->signal_level = SPD_SIGNAL_LVTTL; @@ -261,9 +304,11 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) edo_data->dram_width = 8; edo_data->spd_rev = 0x12; - sprintf(edo_data->part_no, "86Box-%s-%03dM", (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", vslots[vslot]); + sprintf(edo_data->part_no, EMU_NAME "-%s-%03dM", (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", vslots[vslot]); for (i = strlen(edo_data->part_no); i < sizeof(edo_data->part_no); i++) - edo_data->part_no[i] = ' '; + edo_data->part_no[i] = ' '; /* part number should be space-padded */ + edo_data->rev_code[0] = EMU_VERSION_MAJ; + edo_data->rev_code[1] = (((EMU_VERSION_MIN / 10) << 4) | (EMU_VERSION_MIN % 10)); edo_data->mfg_year = 20; edo_data->mfg_week = 17; @@ -280,8 +325,12 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->bytes_used = 0x80; sdram_data->spd_size = 0x08; sdram_data->mem_type = ram_type; - sdram_data->row_bits = 5 + log2_ui16(vslots[vslot]); + sdram_data->row_bits = SPD_ROLLUP(6 + log2_ui16(spd_devices[slot]->row1)); /* first row */ sdram_data->col_bits = 9; + if (spd_devices[slot]->row1 != spd_devices[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */ + sdram_data->row_bits |= (SPD_ROLLUP(6 + log2_ui16(spd_devices[slot]->row2)) << 4); /* second row, if different from first */ + sdram_data->col_bits |= (9 << 4); /* same as first row, but just in case */ + } sdram_data->rows = 2; sdram_data->data_width_lsb = 64; sdram_data->signal_level = SPD_SIGNAL_LVTTL; @@ -292,20 +341,29 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->tccd = 1; sdram_data->burst = SPD_SDR_BURST_PAGE | 1 | 2 | 4 | 8; sdram_data->banks = 4; - sdram_data->cas = sdram_data->cs = sdram_data->we = 0x7F; + sdram_data->cas = 0x1c; /* CAS 5/4/3 supported */ + sdram_data->cslat = sdram_data->we = 0x7f; sdram_data->dev_attr = SPD_SDR_ATTR_EARLY_RAS | SPD_SDR_ATTR_AUTO_PC | SPD_SDR_ATTR_PC_ALL | SPD_SDR_ATTR_W1R_BURST; sdram_data->tclk2 = 0xA0; /* 10 ns = 100 MHz */ sdram_data->tclk3 = 0xF0; /* 15 ns = 66.7 MHz */ sdram_data->tac2 = sdram_data->tac3 = 0x10; sdram_data->trp = sdram_data->trrd = sdram_data->trcd = sdram_data->tras = 1; - sdram_data->bank_density = 1 << (log2_ui16(vslots[vslot] >> 1) - 2); + if (spd_devices[slot]->row1 != spd_devices[slot]->row2) { + /* Utilities interpret bank_density a bit differently on asymmetric modules. */ + sdram_data->bank_density = (1 << (log2_ui16(spd_devices[slot]->row1 >> 1) - 2)); /* first row */ + sdram_data->bank_density |= (1 << (log2_ui16(spd_devices[slot]->row2 >> 1) - 2)); /* second row */ + } else { + sdram_data->bank_density = (1 << (log2_ui16(spd_devices[slot]->row1 >> 1) - 1)); /* symmetric module = only one bit is set */ + } sdram_data->ca_setup = sdram_data->data_setup = 0x15; sdram_data->ca_hold = sdram_data->data_hold = 0x08; sdram_data->spd_rev = 0x12; - sprintf(sdram_data->part_no, "86Box-SDR-%03dM", vslots[vslot]); + sprintf(sdram_data->part_no, EMU_NAME "-SDR-%03dM", vslots[vslot]); for (i = strlen(sdram_data->part_no); i < sizeof(sdram_data->part_no); i++) - sdram_data->part_no[i] = ' '; + sdram_data->part_no[i] = ' '; /* part number should be space-padded */ + sdram_data->rev_code[0] = EMU_VERSION_MAJ; + sdram_data->rev_code[1] = (((EMU_VERSION_MIN / 10) << 4) | (EMU_VERSION_MIN % 10)); sdram_data->mfg_year = 20; sdram_data->mfg_week = 13; @@ -319,7 +377,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) break; } - device_add(spd_devices[slot]); + device_add(info); vslot++; } } diff --git a/src/usb.c b/src/usb.c index 9b04c0383..067294496 100644 --- a/src/usb.c +++ b/src/usb.c @@ -27,6 +27,7 @@ #include <86box/io.h> #include <86box/mem.h> #include <86box/usb.h> +#include "cpu.h" #ifdef ENABLE_USB_LOG @@ -103,20 +104,180 @@ static void ohci_mmio_write(uint32_t addr, uint8_t val, void *p) { usb_t *dev = (usb_t *) p; + uint8_t old; addr &= 0x00000fff; switch (addr) { + case 0x04: + if ((val & 0xc0) == 0x00) { + /* UsbReset */ + dev->ohci_mmio[0x56] = dev->ohci_mmio[0x5a] = 0x16; + } + break; case 0x08: /* HCCOMMANDSTATUS */ - /* bit HostControllerReset must be cleared for the controller to be seen as initialized */ - val &= ~0x01; - /* bit OwnershipChangeRequest triggers an ownership change (SMM <-> OS) */ - if (val & 0x0f) { + if (val & 0x08) { dev->ohci_mmio[0x0f] = 0x40; - dev->ohci_mmio[0x05] &= ~(dev->ohci_mmio[0x05] & 0x01); - } + if ((dev->ohci_mmio[0x13] & 0xc0) == 0xc0) + smi_line = 1; + } + + /* bit HostControllerReset must be cleared for the controller to be seen as initialized */ + if (val & 0x01) { + memset(dev->ohci_mmio, 0x00, 4096); + dev->ohci_mmio[0x00] = 0x10; + dev->ohci_mmio[0x01] = 0x01; + dev->ohci_mmio[0x48] = 0x02; + val &= ~0x01; + } break; + case 0x0c: + dev->ohci_mmio[addr] &= ~(val & 0x7f); + return; + case 0x0d: case 0x0e: + return; + case 0x0f: + dev->ohci_mmio[addr] &= ~(val & 0x40); + return; + case 0x3b: + dev->ohci_mmio[addr] = (val & 0x80); + return; + case 0x39: case 0x41: + dev->ohci_mmio[addr] = (val & 0x3f); + return; + case 0x45: + dev->ohci_mmio[addr] = (val & 0x0f); + return; + case 0x3a: + case 0x3e: case 0x3f: case 0x42: case 0x43: + case 0x46: case 0x47: case 0x48: case 0x4a: + return; + case 0x49: + dev->ohci_mmio[addr] = (val & 0x1b); + if (val & 0x02) { + dev->ohci_mmio[0x55] |= 0x01; + dev->ohci_mmio[0x59] |= 0x01; + } + return; + case 0x4b: + dev->ohci_mmio[addr] = (val & 0x03); + return; + case 0x4c: case 0x4e: + dev->ohci_mmio[addr] = (val & 0x06); + if ((addr == 0x4c) && !(val & 0x04)) { + if (!(dev->ohci_mmio[0x58] & 0x01)) + dev->ohci_mmio[0x5a] |= 0x01; + dev->ohci_mmio[0x58] |= 0x01; + } if ((addr == 0x4c) && !(val & 0x02)) { + if (!(dev->ohci_mmio[0x54] & 0x01)) + dev->ohci_mmio[0x56] |= 0x01; + dev->ohci_mmio[0x54] |= 0x01; + } + return; + case 0x4d: case 0x4f: + return; + case 0x50: + if (val & 0x01) { + if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) { + dev->ohci_mmio[0x55] &= ~0x01; + dev->ohci_mmio[0x54] &= ~0x17; + dev->ohci_mmio[0x56] &= ~0x17; + dev->ohci_mmio[0x59] &= ~0x01; + dev->ohci_mmio[0x58] &= ~0x17; + dev->ohci_mmio[0x5a] &= ~0x17; + } else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) { + if (!(dev->ohci_mmio[0x4e] & 0x02)) { + dev->ohci_mmio[0x55] &= ~0x01; + dev->ohci_mmio[0x54] &= ~0x17; + dev->ohci_mmio[0x56] &= ~0x17; + } + if (!(dev->ohci_mmio[0x4e] & 0x04)) { + dev->ohci_mmio[0x59] &= ~0x01; + dev->ohci_mmio[0x58] &= ~0x17; + dev->ohci_mmio[0x5a] &= ~0x17; + } + } + } + return; + case 0x51: + if (val & 0x80) + dev->ohci_mmio[addr] |= 0x80; + return; + case 0x52: + dev->ohci_mmio[addr] &= ~(val & 0x02); + if (val & 0x01) { + if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) { + dev->ohci_mmio[0x55] |= 0x01; + dev->ohci_mmio[0x59] |= 0x01; + } else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) { + if (!(dev->ohci_mmio[0x4e] & 0x02)) + dev->ohci_mmio[0x55] |= 0x01; + if (!(dev->ohci_mmio[0x4e] & 0x04)) + dev->ohci_mmio[0x59] |= 0x01; + } + } + return; + case 0x53: + if (val & 0x80) + dev->ohci_mmio[0x51] &= ~0x80; + return; + case 0x54: case 0x58: + old = dev->ohci_mmio[addr]; + + 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; + dev->ohci_mmio[addr + 2] |= 0x10; + } else + dev->ohci_mmio[addr + 2] |= 0x01; + } + if (val & 0x08) + dev->ohci_mmio[addr] &= ~0x04; + if (val & 0x04) + dev->ohci_mmio[addr] |= 0x04; + if (val & 0x02) { + if (old & 0x01) + dev->ohci_mmio[addr] |= 0x02; + else + dev->ohci_mmio[addr + 2] |= 0x01; + } + if (val & 0x01) { + if (old & 0x01) + dev->ohci_mmio[addr] &= ~0x02; + else + dev->ohci_mmio[addr + 2] |= 0x01; + } + + if (!(dev->ohci_mmio[addr] & 0x04) && (old & 0x04)) + dev->ohci_mmio[addr + 2] |= 0x04; + /* if (!(dev->ohci_mmio[addr] & 0x02)) + dev->ohci_mmio[addr + 2] |= 0x02; */ + return; + case 0x55: + if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) { + dev->ohci_mmio[addr] &= ~0x01; + dev->ohci_mmio[0x54] &= ~0x17; + dev->ohci_mmio[0x56] &= ~0x17; + } if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) { + dev->ohci_mmio[addr] |= 0x01; + dev->ohci_mmio[0x58] &= ~0x17; + dev->ohci_mmio[0x5a] &= ~0x17; + } + return; + case 0x59: + if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04)) + dev->ohci_mmio[addr] &= ~0x01; + if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04)) + dev->ohci_mmio[addr] |= 0x01; + return; + case 0x56: case 0x5a: + dev->ohci_mmio[addr] &= ~(val & 0x1f); + return; + case 0x57: case 0x5b: + return; } dev->ohci_mmio[addr] = val; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 5ffcf14e8..3545cb69d 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -495,6 +495,10 @@ ati28800k_init(const device_t *info) ati28800->svga.miscout = 1; ati28800->svga.ksc5601_sbyte_mask = 0; + ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; + ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; + ati28800->svga.ksc5601_swap_mode = 0; + ati28800->svga.ksc5601_english_font_type = 0; ati_eeprom_load(&ati28800->eeprom, L"atikorvga.nvr", 0); diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 7ac6ac8c1..f3f428f7e 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -36,6 +36,7 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#define BIOS_GD5401_PATH L"roms/video/cirruslogic/avga1.rom" #define BIOS_GD5402_PATH L"roms/video/cirruslogic/avga2.rom" #define BIOS_GD5402_ONBOARD_PATH L"roms/video/machines/cbm_sl386sx25/Commodore386SX-25_AVGA2.bin" #define BIOS_GD5420_PATH L"roms/video/cirruslogic/5420.vbi" @@ -57,6 +58,7 @@ #define BIOS_GD5446_STB_PATH L"roms/video/cirruslogic/stb nitro64v.BIN" #define BIOS_GD5480_PATH L"roms/video/cirruslogic/clgd5480.rom" +#define CIRRUS_ID_CLGD5401 0x88 #define CIRRUS_ID_CLGD5402 0x89 #define CIRRUS_ID_CLGD5420 0x8a #define CIRRUS_ID_CLGD5422 0x8c @@ -2963,6 +2965,11 @@ static void gd54xx->has_bios = 1; switch (id) { + + case CIRRUS_ID_CLGD5401: + romfn = BIOS_GD5401_PATH; + break; + case CIRRUS_ID_CLGD5402: if (info->local & 0x200) romfn = BIOS_GD5402_ONBOARD_PATH; @@ -3154,6 +3161,12 @@ static void return gd54xx; } +static int +gd5401_available(void) +{ + return rom_present(BIOS_GD5401_PATH); +} + static int gd5402_available(void) { @@ -3376,6 +3389,19 @@ static const device_config_t gd5434_config[] = } }; +const device_t gd5401_isa_device = +{ + "Cirrus Logic GD-5401 (ACUMOS AVGA1)", + DEVICE_AT | DEVICE_ISA, + CIRRUS_ID_CLGD5401, + gd54xx_init, gd54xx_close, + NULL, + gd5401_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + NULL, +}; + const device_t gd5402_isa_device = { "Cirrus Logic GD-5402 (ACUMOS AVGA2)", diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index a468ceb52..e5aaac302 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -57,7 +57,8 @@ #define BIOS_ROM_PATH L"roms/video/et4000/et4000.bin" #define KOREAN_BIOS_ROM_PATH L"roms/video/et4000/tgkorvga.bin" #define KOREAN_FONT_ROM_PATH L"roms/video/et4000/tg_ksc5601.rom" - +#define KASAN_BIOS_ROM_PATH L"roms/video/et4000/et4000_kasan16.bin" +#define KASAN_FONT_ROM_PATH L"roms/video/et4000/kasan_ksc5601.rom" typedef struct { const char *name; @@ -78,6 +79,11 @@ typedef struct { int get_korean_font_enabled; int get_korean_font_index; uint16_t get_korean_font_base; + + uint8_t kasan_cfg_index; + uint8_t kasan_cfg_regs[16]; + uint16_t kasan_access_addr; + uint8_t kasan_font_data[4]; } et4000_t; @@ -95,6 +101,8 @@ static const uint8_t crtc_mask[0x40] = { static video_timings_t timing_et4000_isa = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; static video_timings_t timing_et4000_mca = {VIDEO_MCA, 4, 5, 10, 5, 5, 10}; +static void et4000_kasan_out(uint16_t addr, uint8_t val, void *p); +static uint8_t et4000_kasan_in(uint16_t addr, void *p); static uint8_t et4000_in(uint16_t addr, void *priv) @@ -393,62 +401,251 @@ et4000k_out(uint16_t addr, uint8_t val, void *priv) } } +static uint8_t +et4000_kasan_in(uint16_t addr, void *priv) +{ + et4000_t *et4000 = (et4000_t *)priv; + uint8_t val = 0xFF; + + if (addr == 0x258) { + val = et4000->kasan_cfg_index; + } else if (addr == 0x259) { + if (et4000->kasan_cfg_index >= 0xF0) { + val = et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0]; + if (et4000->kasan_cfg_index == 0xF4 && et4000->kasan_cfg_regs[0] & 0x20) + val |= 0x80; + } + } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { + switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { + case 2: + val = 0; + break; + case 5: + if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) + val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index]; + else if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) + val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index]; + else + val = fontdatksc5601[et4000->get_korean_font_base].chr[et4000->get_korean_font_index]; + break; + default: + break; + } + } else + val = et4000_in(addr, priv); + + return val; +} + +static void +et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) +{ + et4000_t *et4000 = (et4000_t *)priv; + + if (addr == 0x258) { + et4000->kasan_cfg_index = val; + } else if (addr == 0x259) { + if (et4000->kasan_cfg_index >= 0xF0) { + switch (et4000->kasan_cfg_index - 0xF0) { + case 0: + if (et4000->kasan_cfg_regs[4] & 8) + val = (val & 0xFC) | (et4000->kasan_cfg_regs[0] & 3); + et4000->kasan_cfg_regs[0] = val; + svga_recalctimings(&et4000->svga); + break; + case 1: + case 2: + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1]; + io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + break; + case 4: + if (et4000->kasan_cfg_regs[0] & 0x20) + val |= 0x80; + et4000->svga.ksc5601_swap_mode = (val & 4) >> 2; + et4000->kasan_cfg_regs[4] = val; + svga_recalctimings(&et4000->svga); + break; + case 5: + et4000->kasan_cfg_regs[5] = val; + et4000->svga.ksc5601_english_font_type = 0x100 | val; + case 6: + case 7: + et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; + default: + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + svga_recalctimings(&et4000->svga); + break; + } + } + } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { + switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { + case 0: + if (et4000->kasan_cfg_regs[0] & 2) { + et4000->get_korean_font_index = ((val & 1) << 4) | ((val & 0x1E) >> 1); + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~7) | (val >> 5); + } + break; + case 1: + if (et4000->kasan_cfg_regs[0] & 2) + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F8) | (val << 3); + break; + case 2: + if (et4000->kasan_cfg_regs[0] & 2) + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F800) | ((val & 7) << 11); + break; + case 3: + case 4: + case 5: + if (et4000->kasan_cfg_regs[0] & 1) + et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val; + break; + case 6: + if ((et4000->kasan_cfg_regs[0] & 1) && (et4000->kasan_font_data[3] & !(val & 0x80)) && (et4000->get_korean_font_base & 0x7F) >= 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F) { + if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) + fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index] = et4000->kasan_font_data[2]; + else if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) + fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index] = et4000->kasan_font_data[2]; + } + et4000->kasan_font_data[3] = val; + break; + default: + break; + } + } else + et4000_out(addr, val, priv); +} + +uint32_t +get_et4000_addr(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + uint32_t nbank; + + switch (svga->crtc[0x37] & 0x0B) { + case 0x00: + case 0x01: + nbank = 0; + addr &= 0xFFFF; + break; + case 0x02: + nbank = (addr & 1) << 1; + addr = (addr >> 1) & 0xFFFF; + break; + case 0x03: + nbank = addr & 3; + addr = (addr >> 2) & 0xFFFF; + break; + case 0x08: + case 0x09: + nbank = 0; + addr &= 0x3FFFF; + break; + case 0x0A: + nbank = (addr & 1) << 1; + addr = (addr >> 1) & 0x3FFFF; + break; + case 0x0B: + nbank = addr & 3; + addr = (addr >> 2) & 0x3FFFF; + break; + default: + nbank = 0; + break; + } + + if (svga->vram_max >= 1024 * 1024) { + addr = (addr << 2) | (nbank & 3); + if ((svga->crtc[0x37] & 3) == 2) + addr >>= 1; + else if ((svga->crtc[0x37] & 3) < 2) + addr >>= 2; + } else if (svga->vram_max >= 512 * 1024) { + addr = (addr << 1) | ((nbank & 2) >> 1) | ((nbank & 1) << 19); + if ((svga->crtc[0x37] & 3) < 2) + addr >>= 1; + } else if(svga->vram_max >= 256 * 1024) + addr = addr | (nbank << 18); + else if (svga->vram_max > 128 * 1024) { + addr = (addr << 1) | ((nbank & 2) >> 1) | ((nbank & 1) << 17); + if ((svga->crtc[0x37] & 3) < 2) + addr >>= 1; + } else + addr = addr | (nbank << 16); + + return addr; +} static void et4000_recalctimings(svga_t *svga) { - et4000_t *dev = (et4000_t *)svga->p; + et4000_t *dev = (et4000_t *)svga->p; - svga->ma_latch |= (svga->crtc[0x33]&3)<<16; - if (svga->crtc[0x35] & 1) svga->vblankstart += 0x400; - if (svga->crtc[0x35] & 2) svga->vtotal += 0x400; - if (svga->crtc[0x35] & 4) svga->dispend += 0x400; - if (svga->crtc[0x35] & 8) svga->vsyncstart += 0x400; - if (svga->crtc[0x35] & 0x10) svga->split += 0x400; - if (!svga->rowoffset) svga->rowoffset = 0x100; - if (svga->crtc[0x3f] & 1) svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; + svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; + if (svga->crtc[0x35] & 1) svga->vblankstart += 0x400; + if (svga->crtc[0x35] & 2) svga->vtotal += 0x400; + if (svga->crtc[0x35] & 4) svga->dispend += 0x400; + if (svga->crtc[0x35] & 8) svga->vsyncstart += 0x400; + if (svga->crtc[0x35] & 0x10) svga->split += 0x400; + if (!svga->rowoffset) svga->rowoffset = 0x100; + if (svga->crtc[0x3f] & 1) svga->htotal += 256; + if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; - switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { - case 0: - case 1: - break; + switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { + case 0: + case 1: + break; + case 3: + svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; + break; + case 5: + svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; + break; + default: + svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; + break; + } + + switch (svga->bpp) { + case 15: + case 16: + svga->hdisp /= 2; + break; - case 3: - svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; - break; + case 24: + svga->hdisp /= 3; + break; + } - case 5: - svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; - break; - - default: - svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; - break; - } - - switch (svga->bpp) { - case 15: - case 16: - svga->hdisp /= 2; - break; - - case 24: - svga->hdisp /= 3; - break; - } - - if (dev->type == 2 || dev->type == 3) { -#if NOT_YET - if ((svga->render == svga_render_text_80) && ((svga->crtc[0x37] & 0x0A) == 0x0A)) { - if ((dev->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) { - svga->render = svga_render_text_80_ksc5601; + if (dev->type == 2 || dev->type == 3 || dev->type == 4) { + if ((svga->render == svga_render_text_80) && ((svga->crtc[0x37] & 0x0A) == 0x0A)) { + if (dev->port_32cb_val & 0x80) { + svga->ma_latch -= 2; + svga->ca_adj = -2; + } + if ((dev->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) { + svga->render = svga_render_text_80_ksc5601; + } } } -#endif - } } +static void +et4000_kasan_recalctimings(svga_t *svga) +{ + et4000_t *et4000 = (et4000_t *)svga->p; + + et4000_recalctimings(svga); + + if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { + svga->ma_latch -= 3; + svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; + svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; + if((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) + svga->render = svga_render_text_80_ksc5601; + } +} static uint8_t et4000_mca_read(int port, void *priv) @@ -484,6 +681,7 @@ et4000_init(const device_t *info) { const wchar_t *fn; et4000_t *dev; + int i; dev = (et4000_t *)malloc(sizeof(et4000_t)); memset(dev, 0x00, sizeof(et4000_t)); @@ -521,6 +719,10 @@ et4000_init(const device_t *info) dev->port_22cb_val = 0x60; dev->port_32cb_val = 0; dev->svga.ksc5601_sbyte_mask = 0x80; + dev->svga.ksc5601_udc_area_msb[0] = 0xC9; + dev->svga.ksc5601_udc_area_msb[1] = 0xFE; + dev->svga.ksc5601_swap_mode = 0; + dev->svga.ksc5601_english_font_type = 0; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); svga_init(info, &dev->svga, dev, dev->vram_size, et4000_recalctimings, et4000k_in, et4000k_out, @@ -536,6 +738,40 @@ et4000_init(const device_t *info) loadfont(KOREAN_FONT_ROM_PATH, 6); fn = KOREAN_BIOS_ROM_PATH; break; + case 4: /* Kasan ET4000 */ + dev->vram_size = device_get_config_int("memory") << 10; + dev->svga.ksc5601_sbyte_mask = 0; + dev->svga.ksc5601_udc_area_msb[0] = 0xC9; + dev->svga.ksc5601_udc_area_msb[1] = 0xFE; + dev->svga.ksc5601_swap_mode = 0; + dev->svga.ksc5601_english_font_type = 0x1FF; + dev->kasan_cfg_index = 0; + for (i=0; i<16; i++) + dev->kasan_cfg_regs[i] = 0; + for(i=0; i<4; i++) + dev->kasan_font_data[i] = 0; + dev->kasan_cfg_regs[1] = 0x50; + dev->kasan_cfg_regs[2] = 2; + dev->kasan_cfg_regs[3] = 6; + dev->kasan_cfg_regs[4] = 0x78; + dev->kasan_cfg_regs[5] = 0xFF; + dev->kasan_cfg_regs[6] = 0xC9; + dev->kasan_cfg_regs[7] = 0xFE; + dev->kasan_access_addr = 0x250; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); + svga_init(info, &dev->svga, dev, dev->vram_size, + et4000_kasan_recalctimings, et4000_in, et4000_out, + NULL, NULL); + io_sethandler(0x03c0, 32, + et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev); + io_sethandler(0x0250, 8, + et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, dev); + io_sethandler(0x0258, 2, + et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, dev); + loadfont(KASAN_FONT_ROM_PATH, 6); + fn = KASAN_BIOS_ROM_PATH; + break; + } dev->svga.ramdac = device_add(&sc1502x_ramdac_device); @@ -545,6 +781,8 @@ et4000_init(const device_t *info) rom_init(&dev->bios_rom, (wchar_t *) fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + dev->svga.translate_address = get_et4000_addr; + return(dev); } @@ -592,6 +830,12 @@ et4000k_available(void) rom_present(KOREAN_FONT_ROM_PATH); } +static int +et4000_kasan_available(void) +{ + return rom_present(KASAN_BIOS_ROM_PATH) && + rom_present(KASAN_FONT_ROM_PATH); +} static const device_config_t et4000_config[] = { @@ -660,3 +904,14 @@ const device_t et4000k_tg286_isa_device = { et4000_force_redraw, et4000_config }; + +const device_t et4000_kasan_isa_device = { + "Kasan Hangulmadang-16 VGA (Tseng Labs ET4000AX Korean)", + DEVICE_ISA, + 4, + et4000_init, et4000_close, NULL, + et4000_kasan_available, + et4000_speed_changed, + et4000_force_redraw, + et4000_config +}; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 0a21ad1a3..2140f7d7e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -431,7 +431,7 @@ svga_recalctimings(svga_t *svga) svga->vblankstart |= 0x200; svga->vblankstart++; - svga->hdisp = svga->crtc[1]; + svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); svga->hdisp++; svga->htotal = svga->crtc[0]; @@ -445,7 +445,8 @@ svga_recalctimings(svga_t *svga) svga->interlace = 0; - svga->ma_latch = (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->ca_adj = 0; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; @@ -805,11 +806,11 @@ svga_poll(void *p) changeframecount = svga->interlace ? 3 : 2; svga->vslines = 0; - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); else - svga->ma = svga->maback = svga->ma_latch; - svga->ca = (svga->crtc[0xe] << 8) | svga->crtc[0xf]; + 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); @@ -911,6 +912,9 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize, svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 32; svga->dac_hwcursor.yoff = 32; + + svga->translate_address = NULL; + svga->ksc5601_english_font_type = 0; if ((info->flags & DEVICE_PCI) || (info->flags & DEVICE_VLB)) { mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, @@ -1036,6 +1040,9 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) addr &= svga->decode_mask; + if (svga->translate_address) + addr = svga->translate_address(addr, p); + if (addr >= svga->vram_max) return; @@ -1168,6 +1175,8 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) addr <<= 3; else if (svga->chain4 || svga->fb_only) { addr &= svga->decode_mask; + if (svga->translate_address) + addr = svga->translate_address(addr, p); if (addr >= svga->vram_max) return 0xff; return svga->vram[addr & svga->vram_mask]; @@ -1179,6 +1188,10 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) addr <<= 2; addr &= svga->decode_mask; + if (svga->translate_address) { + latch_addr = svga->translate_address(latch_addr, p); + addr = svga->translate_address(addr, p); + } /* standard VGA latched access */ if (latch_addr >= svga->vram_max) { @@ -1375,6 +1388,19 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p) } addr &= svga->decode_mask; + if(svga->translate_address) { + uint32_t addr2 = svga->translate_address(addr, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = val & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + addr2 = svga->translate_address(addr+1, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = (val >> 8) & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + return; + } if (addr >= svga->vram_max) return; addr &= svga->vram_mask; @@ -1423,6 +1449,29 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p) } addr &= svga->decode_mask; + if (svga->translate_address) { + uint32_t addr2 = svga->translate_address(addr, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = val & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + addr2 = svga->translate_address(addr+1, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = (val >> 8) & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + addr2 = svga->translate_address(addr+2, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = (val >> 16) & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + addr2 = svga->translate_address(addr+3, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = (val >> 24) & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + return; + } if (addr >= svga->vram_max) return; addr &= svga->vram_mask; @@ -1484,6 +1533,16 @@ svga_readw_common(uint32_t addr, uint8_t linear, void *p) } addr &= svga->decode_mask; + if (svga->translate_address) { + uint8_t val1 = 0xff, val2 = 0xff; + uint32_t addr2 = svga->translate_address(addr, p); + if (addr2 < svga->vram_max) + val1 = svga->vram[addr2 & svga->vram_mask]; + addr2 = svga->translate_address(addr+1, p); + if (addr2 < svga->vram_max) + val2 = svga->vram[addr2 & svga->vram_mask]; + return (val2 << 8) | val1; + } if (addr >= svga->vram_max) return 0xffff; @@ -1527,6 +1586,22 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *p) } addr &= svga->decode_mask; + if (svga->translate_address) { + uint8_t val1 = 0xff, val2 = 0xff, val3 = 0xff, val4 = 0xff; + uint32_t addr2 = svga->translate_address(addr, p); + if (addr2 < svga->vram_max) + val1 = svga->vram[addr2 & svga->vram_mask]; + addr2 = svga->translate_address(addr+1, p); + if (addr2 < svga->vram_max) + val2 = svga->vram[addr2 & svga->vram_mask]; + addr2 = svga->translate_address(addr+2, p); + if (addr2 < svga->vram_max) + val3 = svga->vram[addr2 & svga->vram_mask]; + addr2 = svga->translate_address(addr+3, p); + if (addr2 < svga->vram_max) + val4 = svga->vram[addr2 & svga->vram_mask]; + return (val4 << 24) | (val3 << 16) | (val2 << 8) | val1; + } if (addr >= svga->vram_max) return 0xffffffff; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 11605fec4..30b274067 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -258,17 +258,24 @@ svga_render_text_80_ksc5601(svga_t *svga) } if ((x + xinc) < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { - if (((chr == 0xc9) || (chr == 0xfe)) && ((nextchr > 0xa0) && (nextchr < 0xff))) - dat = fontdatksc5601_user[((chr == 0xfe) ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc]; - else if (nextchr & 0x80) + if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc]; + else if (nextchr & 0x80) { + if (svga->ksc5601_swap_mode == 1 && (nextchr > 0xa0 && nextchr < 0xff)) { + if(chr >= 0x80 && chr < 0x99) chr += 0x30; + else if(chr >= 0xB0 && chr < 0xC9) chr -= 0x30; + } dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; - else + } else dat = 0xff; } else { if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); - dat = svga->vram[charaddr + (svga->sc << 2)]; + if ((svga->ksc5601_english_font_type >> 8) == 1) + dat = fontdatksc5601[((svga->ksc5601_english_font_type & 0x7F) << 7) | (chr >> 1)].chr[((chr & 1) << 4) | svga->sc]; + else + dat = svga->vram[charaddr + (svga->sc << 2)]; } if (svga->seqregs[1] & 1) { @@ -301,8 +308,8 @@ svga_render_text_80_ksc5601(svga_t *svga) } } - if (((chr == 0xc9) || (chr == 0xfe)) && ((nextchr > 0xa0) && (nextchr < 0xff))) - dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16]; + if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16]; else if(nextchr & 0x80) dat = fontdatksc5601[((chr & 0x7f) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; else diff --git a/src/video/vid_table.c b/src/video/vid_table.c index f1f10835b..acff552ea 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -68,6 +68,7 @@ video_cards[] = { #endif { "[ISA] CGA", "cga", &cga_device }, { "[ISA] Chips & Technologies SuperEGA", "superega", &sega_device }, + { "[ISA] Cirrus Logic CL-GD 5401", "cl_gd5401_isa", &gd5401_isa_device }, { "[ISA] Cirrus Logic CL-GD 5402", "cl_gd5402_isa", &gd5402_isa_device }, { "[ISA] Cirrus Logic CL-GD 5420", "cl_gd5420_isa", &gd5420_isa_device }, #if defined(DEV_BRANCH) && defined(USE_CL5422) @@ -86,6 +87,7 @@ video_cards[] = { { "[ISA] Hercules Plus", "hercules_plus", &herculesplus_device }, { "[ISA] Hercules InColor", "incolor", &incolor_device }, { "[ISA] Image Manager 1024", "im1024", &im1024_device }, + { "[ISA] Kasan Hangulmadang-16 VGA (ET4000AX)", "kasan16vga", &et4000_kasan_isa_device }, { "[ISA] MDA", "mda", &mda_device }, { "[ISA] MDSI Genius", "genius", &genius_device }, { "[ISA] OAK OTI-037C", "oti037c", &oti037c_device }, diff --git a/src/video/video.c b/src/video/video.c index 4a168d41c..ce77e9abf 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -109,7 +109,6 @@ int video_res_x = 0, video_res_y = 0, video_bpp = 0; static int video_force_resize; -int invert_display = 0; int video_grayscale = 0; int video_graytype = 0; static int vid_type; diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 068f8d6ed..3be96434c 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -281,13 +281,8 @@ FONT 9, "Segoe UI" BEGIN DEFPUSHBUTTON "OK",IDOK,129,94,71,12 ICON 100,IDC_ABOUT_ICON,7,7,20,20 -#ifdef RELEASE_BUILD - LTEXT "86Box v2.07 - 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.", + 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 -#else - LTEXT "86Box v2.10 - 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 -#endif CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, 86,208,1 END @@ -1043,8 +1038,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,10,0,0 - PRODUCTVERSION 2,10,0,0 + FILEVERSION EMU_VERSION_MAJ,EMU_VERSION_MIN,0,0 + PRODUCTVERSION EMU_VERSION_MAJ,EMU_VERSION_MIN,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -1059,14 +1054,14 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "CompanyName", "86Box\0" - VALUE "FileDescription", "86Box\0" - VALUE "FileVersion", "2.10\0" - VALUE "InternalName", "86Box\0" - VALUE "LegalCopyright", "Copyright © 2007-2020 86Box contributors\0" - VALUE "OriginalFilename", "86Box.exe\0" - VALUE "ProductName", "86Box Emulator\0" - VALUE "ProductVersion", "2.10\0" + VALUE "CompanyName", EMU_NAME "\0" + VALUE "FileDescription", EMU_NAME "\0" + VALUE "FileVersion", EMU_VERSION "\0" + VALUE "InternalName", EMU_NAME "\0" + VALUE "LegalCopyright", "Copyright © 2007-" COPYRIGHT_YEAR " " EMU_NAME " contributors\0" + VALUE "OriginalFilename", EMU_NAME ".exe\0" + VALUE "ProductName", EMU_NAME " Emulator\0" + VALUE "ProductVersion", EMU_VERSION "\0" END END BLOCK "VarFileInfo" diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index cebd6d8d3..9e2ad81d9 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -27,9 +27,6 @@ endif ifndef DEV_BUILD DEV_BUILD := n endif -ifndef FLTO -FLTO := full -endif ifeq ($(DEV_BUILD), y) ifndef DEBUG @@ -50,12 +47,6 @@ ifeq ($(DEV_BUILD), y) ifndef MGA MGA := y endif - ifndef MR495 - MR495 := y - endif - ifndef MRTHOR - MRTHOR := y - endif ifndef PAS16 PAS16 := n endif @@ -114,12 +105,6 @@ else ifndef MGA MGA := n endif - ifndef MR495 - MR495 := n - endif - ifndef MRTHOR - MRTHOR := n - endif ifndef PAS16 PAS16 := n endif @@ -320,7 +305,7 @@ else ifeq ($(OPTIM), y) AOPTIM := -mtune=native ifndef COPTIM - COPTIM := -O3 -ffp-contract=fast -flto=$(FLTO) + COPTIM := -O3 -ffp-contract=fast -flto endif else ifndef COPTIM @@ -437,14 +422,6 @@ OPTS += -DUSE_MGA DEVBROBJ += vid_mga.o endif -ifeq ($(MR495), y) -OPTS += -DUSE_MR495 -endif - -ifeq ($(MRTHOR), y) -OPTS += -DUSE_MRTHOR -endif - ifeq ($(PAS16), y) OPTS += -DUSE_PAS16 DEVBROBJ += snd_pas16.o @@ -556,9 +533,9 @@ MCHOBJ := machine.o machine_table.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_socket370.o + m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ +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 \ diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index e33767ad4..29ff11093 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -27,9 +27,6 @@ endif ifndef DEV_BUILD DEV_BUILD := n endif -ifndef FLTO -FLTO := full -endif ifeq ($(DEV_BUILD), y) ifndef DEBUG @@ -50,12 +47,6 @@ ifeq ($(DEV_BUILD), y) ifndef MGA MGA := y endif - ifndef MR495 - MR495 := y - endif - ifndef MRTHOR - MRTHOR := y - endif ifndef PAS16 PAS16 := n endif @@ -114,12 +105,6 @@ else ifndef MGA MGA := n endif - ifndef MR495 - MR495 := n - endif - ifndef MRTHOR - MRTHOR := n - endif ifndef PAS16 PAS16 := n endif @@ -317,7 +302,7 @@ else ifeq ($(OPTIM), y) AOPTIM := -mtune=native ifndef COPTIM - COPTIM := -O3 -ffp-contract=fast -flto=$(FLTO) + COPTIM := -O3 -ffp-contract=fast -flto endif else ifndef COPTIM @@ -446,14 +431,6 @@ OPTS += -DUSE_MGA DEVBROBJ += vid_mga.o endif -ifeq ($(MR495), y) -OPTS += -DUSE_MR495 -endif - -ifeq ($(MRTHOR), y) -OPTS += -DUSE_MRTHOR -endif - ifeq ($(PAS16), y) OPTS += -DUSE_PAS16 DEVBROBJ += snd_pas16.o @@ -560,9 +537,9 @@ MCHOBJ := machine.o machine_table.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_socket370.o + m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o -DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \ +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 \ diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c index 6ff7d06e6..fe3d6153d 100644 --- a/src/win/win_media_menu.c +++ b/src/win/win_media_menu.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include <86box/86box.h> #include <86box/cdrom.h> #include <86box/config.h> @@ -526,4 +526,4 @@ HMENU media_menu_get_mo(int id) { return menus[MO_FIRST + id]; -} \ No newline at end of file +} diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 814484a92..b33114ba2 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -59,8 +59,8 @@ int infocus = 1; int rctrl_is_lalt = 0; int user_resize = 0; -char openfilestring[512]; -WCHAR wopenfilestring[512]; +extern char openfilestring[512]; +extern WCHAR wopenfilestring[512]; /* Local data. */