diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 0fb6e17d9..32025b1b7 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -443,10 +443,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case INTEL_440BX: case INTEL_440ZX: regs[0x51] = (regs[0x50] & 0x70) | (val & 0x8f); -#if defined(DEV_BRANCH) && defined(USE_VIRTUALPC) - if (!strcmp(machines[machine].internal_name, "vpc2007")) + if (is_vpc) regs[0x51] |= 0x10; /* Virtual PC 2007 BIOS requires a reserved bus speed bit to be set */ -#endif break; case INTEL_440GX: regs[0x51] = (regs[0x50] & 0x88) | (val & 0x08); @@ -1556,10 +1554,8 @@ static void regs[0x51] |= 0x20; else if ((cpu_busspeed > 66666667) && (cpu_busspeed <= 100000000)) regs[0x51] |= 0x00; -#if defined(DEV_BRANCH) && defined(USE_VIRTUALPC) - if (!strcmp(machines[machine].internal_name, "vpc2007")) + if (is_vpc) regs[0x51] |= 0x10; /* Virtual PC 2007 BIOS requires a reserved bus speed bit to be set */ -#endif regs[0x57] = 0x28; /* 4 DIMMs, SDRAM */ regs[0x58] = 0x03; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; diff --git a/src/config.c b/src/config.c index da58b02e8..9aead9a0f 100644 --- a/src/config.c +++ b/src/config.c @@ -531,7 +531,18 @@ load_machine(void) machine = machine_count() - 1; cpu_manufacturer = config_get_int(cat, "cpu_manufacturer", 0); + if ((cpu_manufacturer >= (sizeof(machines[machine].cpu) / sizeof(machines[machine].cpu[0]))) || + (machines[machine].cpu[cpu_manufacturer].cpus == NULL)) + cpu_manufacturer = 0; + cpu = config_get_int(cat, "cpu", 0); + for (int i = 0; i != cpu; i++) { + if (machines[machine].cpu[cpu_manufacturer].cpus[i].cpu_type == -1) { + cpu = 0; + break; + } + } + cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); p = (char *)config_get_string(cat, "fpu_type", "none"); @@ -543,7 +554,7 @@ load_machine(void) if (mem_size < (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram)) mem_size = (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); -#endif +#endif if (mem_size > 2097152) mem_size = 2097152; diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 33f7365dd..2b6be6aa9 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -204,11 +204,15 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_shift.h" #include "x86_ops_amd.h" #include "x86_ops_3dnow.h" +#include static int opVPCEXT(uint32_t fetchdat) { uint8_t b1, b2; + uint16_t cent; + time_t now; + struct tm *tm; if (!is_vpc) return ILLEGAL(fetchdat); @@ -222,23 +226,68 @@ static int opVPCEXT(uint32_t fetchdat) CLOCK_CYCLES(1); + if (b1 == 0x03) { + (void)time(&now); + tm = localtime(&now); + } + if ((b1 == 0x07) && (b2 == 0x0b)) { - EBX = 0x00000000; - EDX = 0x00000003; + switch (EAX) { + case 0x00000000: + EDX = 0x00000003; + break; + + case 0x00000001: + EDX = 0x00000012; + break; + + case 0x00000002: + case 0x00000003: + case 0x00000004: + case 0x00000005: + EDX = 0x00000001; + break; + + case 0x00000007: + EDX = 0x0000009c; + break; + + default: + EDX = 0x00000000; + if (EAX > 0x00000012) + cpu_state.flags &= ~(Z_FLAG); + } } else if ((b1 == 0x03) && (b2 == 0x00)) { - /* TODO: Return host BCD time in DX/CX/AX */ - EDX = 0x00000000; - ECX = 0x00000000; - EAX = 0x00000000; + EDX = BCD8(tm->tm_hour); + ECX = BCD8(tm->tm_min); + EAX = BCD8(tm->tm_sec); } else if ((b1 == 0x03) && (b2 == 0x01)) { - /* TODO: Return host BCD date in DX/CX/AX */ - EDX = 0x00000001; - ECX = 0x00000001; - EAX = 0x00001980; + EDX = BCD8(tm->tm_year % 100); + ECX = BCD8(tm->tm_mon + 1); + EAX = BCD8(tm->tm_mday); + cent = (((tm->tm_year - (tm->tm_year % 100)) / 100) % 4); + EBX = ((tm->tm_mday + tm->tm_mon + (tm->tm_year % 100) + cent + 3) % 7); + } else if ((b1 == 0x03) && (b2 == 0x03)) { + EDX = tm->tm_hour; + ECX = tm->tm_min; + EAX = tm->tm_sec; + } else if ((b1 == 0x03) && (b2 == 0x04)) { + EDX = 1900 + tm->tm_year; + ECX = tm->tm_mon + 1; + EBX = tm->tm_mday; + } else if ((b1 == 0x03) && (b2 == 0x05)) { + EBX = 0x0000000F; + ECX = 0x0000000A; + } else if ((b1 == 0x03) && (b2 == 0x06)) { + /* Some kind of timestamp. BX jumps around very quickly, CX not so much. */ + EBX = 0x00000000; + ECX = 0x00000000; + } else if ((b1 == 0x03) && (b2 >= 0x07)) { + cpu_state.flags &= ~(Z_FLAG); } else if ((b1 == 0x0a) && (b2 == 0x00)) { EAX = mem_size; } else if ((b1 == 0x11) && (b2 == 0x00)) - ; /* Do nothing */ + EAX = 0x00000000; else if ((b1 == 0x11) && (b2 == 0x01)) { EAX = 0x00000000; cpu_state.flags &= ~(Z_FLAG); diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 11c250201..885f81011 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -45,8 +45,11 @@ # define ENABLE_LOG_COMMANDS 1 #endif -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define ABS(x) ((x) > 0 ? (x) : -(x)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define ABS(x) ((x) > 0 ? (x) : -(x)) +#define BCD8(x) ((((x) / 10) << 4) | ((x) % 10)) +#define BCD16(x) ((((x) / 1000) << 12) | (((x) / 100) << 8) | BCD8(x)) +#define BCD32(x) ((((x) / 10000000) << 28) | (((x) / 1000000) << 24) | (((x) / 100000) << 20) | (((x) / 10000) << 16) | BCD16(x)) #ifdef __cplusplus extern "C" { diff --git a/src/mem/spd.c b/src/mem/spd.c index f65417f9f..0268c1d5a 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -29,7 +29,6 @@ #include <86box/machine.h> -#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define SPD_ROLLUP(x) ((x) >= 16 ? ((x) - 15) : (x)) @@ -328,8 +327,8 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) 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] = ' '; /* 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->rev_code[0] = BCD8(EMU_VERSION_MAJ); + edo_data->rev_code[1] = BCD8(EMU_VERSION_MIN); edo_data->mfg_year = 20; edo_data->mfg_week = 17; @@ -383,8 +382,8 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) 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] = ' '; /* 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->rev_code[0] = BCD8(EMU_VERSION_MAJ); + sdram_data->rev_code[1] = BCD8(EMU_VERSION_MIN); sdram_data->mfg_year = 20; sdram_data->mfg_week = 13;