diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 1b017c411..555b20e37 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -8,7 +8,7 @@ * * CPU type handler. * - * Version: @(#)cpu.c 1.0.11 2018/02/18 + * Version: @(#)cpu.c 1.0.12 2018/03/02 * * Authors: Sarah Walker, * leilei, @@ -97,6 +97,7 @@ enum }; CPU *cpu_s; +int cpu_effective; int cpu_multi; int cpu_iscyrix; int cpu_16bitbus; @@ -181,9 +182,21 @@ int timing_misaligned; msr_t msr; +void cpu_dynamic_switch(int new_cpu) +{ + if (cpu_effective == new_cpu) + return; + + int c = cpu; + cpu = new_cpu; + cpu_set(); + speedchanged(); + cpu = c; +} + void cpu_set_edx() { - EDX = machines[machine].cpu[cpu_manufacturer].cpus[cpu].edx_reset; + EDX = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].edx_reset; } @@ -198,7 +211,8 @@ void cpu_set() cpu = 0; } - cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu]; + cpu_effective = cpu; + cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective]; CPUID = cpu_s->cpuid_model; cpuspeed = cpu_s->speed; @@ -1277,7 +1291,7 @@ cpu_current_pc(char *bufp) void cpu_CPUID() { - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type) + switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_i486DX: if (!EAX) @@ -1708,7 +1722,7 @@ void cpu_CPUID() void cpu_RDMSR() { - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type) + switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: EAX = EDX = 0; @@ -1936,7 +1950,7 @@ i686_invalid_rdmsr: void cpu_WRMSR() { - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type) + switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: switch (ECX) @@ -1959,7 +1973,7 @@ void cpu_WRMSR() if (EAX & (1 << 29)) CPUID = 0; else - CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpuid_model; + CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpuid_model; break; case 0x108: msr.fcr2 = EAX | ((uint64_t)EDX << 32); @@ -2027,7 +2041,7 @@ void cpu_WRMSR() tsc = EAX | ((uint64_t)EDX << 32); break; case 0x17: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type != CPU_PENTIUM2D) goto i686_invalid_wrmsr; + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type != CPU_PENTIUM2D) goto i686_invalid_wrmsr; ecx17_msr = EAX | ((uint64_t)EDX << 32); break; case 0x1B: @@ -2055,15 +2069,15 @@ void cpu_WRMSR() ecx11e_msr = EAX | ((uint64_t)EDX << 32); break; case 0x174: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; cs_msr = EAX & 0xFFFF; break; case 0x175: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; esp_msr = EAX; break; case 0x176: - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; eip_msr = EAX; break; case 0x186: @@ -2141,10 +2155,10 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv) if ((ccr3 & 0xf0) == 0x10) { ccr4 = val; - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_Cx6x86) + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_Cx6x86) { if (val & 0x80) - CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpuid_model; + CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpuid_model; else CPUID = 0; } @@ -2174,11 +2188,11 @@ uint8_t cyrix_read(uint16_t addr, void *priv) case 0xe8: return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff; case 0xe9: return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff; case 0xea: return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff; - case 0xfe: return machines[machine].cpu[cpu_manufacturer].cpus[cpu].cyrix_id & 0xff; - case 0xff: return machines[machine].cpu[cpu_manufacturer].cpus[cpu].cyrix_id >> 8; + case 0xfe: return machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cyrix_id & 0xff; + case 0xff: return machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cyrix_id >> 8; } if ((cyrix_addr & 0xf0) == 0xc0) return 0xff; - if (cyrix_addr == 0x20 && machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_Cx5x86) return 0xff; + if (cyrix_addr == 0x20 && machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_Cx5x86) return 0xff; } return 0xff; } @@ -2201,7 +2215,7 @@ void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f) void cpu_update_waitstates() { - cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu]; + cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective]; cpu_prefetch_width = cpu_16bitbus ? 2 : 4; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 5c383b013..d07ed7d05 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -8,7 +8,7 @@ * * CPU type handler. * - * Version: @(#)cpu.h 1.0.7 2018/02/18 + * Version: @(#)cpu.h 1.0.8 2018/03/02 * * Authors: Sarah Walker, * leilei, @@ -462,5 +462,7 @@ extern void x86ts(char *s, uint16_t error); extern void x87_dumpregs(void); extern void x87_reset(void); +extern int cpu_effective; + #endif /*EMU_CPU_H*/ diff --git a/src/keyboard_at.c b/src/keyboard_at.c index c789f409b..f2fe83b7f 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -8,7 +8,7 @@ * * Intel 8042 (AT keyboard controller) emulation. * - * Version: @(#)keyboard_at.c 1.0.26 2018/02/24 + * Version: @(#)keyboard_at.c 1.0.27 2018/03/02 * * Authors: Sarah Walker, * Miran Grca, @@ -36,6 +36,7 @@ #include "device.h" #include "timer.h" #include "machine/machine.h" +#include "machine/m_xt_xi8088.h" #include "machine/m_at_t3100e.h" #include "floppy/fdd.h" #include "floppy/fdc.h" @@ -1428,6 +1429,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv) int bad = 1; uint8_t mask; + if (romset == ROM_XI8088 && port == 0x63) + port = 0x61; + switch (port) { case 0x60: if (kbd->want60) { @@ -1656,6 +1660,13 @@ kbd_write(uint16_t port, uint8_t val, void *priv) if (speaker_enable) was_speaker_enable = 1; pit_set_gate(&pit, 2, val & 1); + + if (romset == ROM_XI8088) { + if (val & 0x04) + xi8088_turbo_set(1); + else + xi8088_turbo_set(0); + } break; case 0x64: @@ -1782,6 +1793,9 @@ kbd_read(uint16_t port, void *priv) atkbd_t *kbd = (atkbd_t *)priv; uint8_t ret = 0xff; + if (romset == ROM_XI8088 && port == 0x63) + port = 0x61; + switch (port) { case 0x60: ret = kbd->out; @@ -1800,6 +1814,12 @@ kbd_read(uint16_t port, void *priv) else ret &= ~0x10; } + if (romset == ROM_XI8088){ + if (xi8088_turbo_get()) + ret |= 0x04; + else + ret &= ~0x04; + } break; case 0x64: diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index 7327cd23d..ca350dfd9 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -385,13 +385,11 @@ void t3100e_turbo_set(uint8_t value) if (!value) { int c = cpu; - cpu = 0; /* 286/6 */ - cpu_set(); - cpu = c; + cpu_dynamic_switch(0); /* 286/6 */ } else { - cpu_set(); + cpu_dynamic_switch(cpu); } } diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index f6d6e846c..61301dc70 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -401,14 +401,11 @@ static void t1200_turbo_set(uint8_t value) t1000.turbo = value; if (!value) { - int c = cpu; - cpu = 0; /* 8088/4.77MHz */ - cpu_set(); - cpu = c; + cpu_dynamic_switch(0); } else { - cpu_set(); + cpu_dynamic_switch(cpu); } } diff --git a/src/machine/machine.h b/src/machine/machine.h index be4840664..d7fcbcce8 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -190,7 +190,11 @@ extern void machine_xt_laserxt_init(machine_t *); extern void machine_xt_t1000_init(machine_t *); extern void machine_xt_t1200_init(machine_t *); +extern void machine_xt_xi8088_init(machine_t *); + #ifdef EMU_DEVICE_H +extern device_t *xi8088_get_device(void); + extern device_t *pcjr_get_device(void); extern device_t *tandy1k_get_device(void); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index c54e3c403..8a78890da 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.21 2018/03/02 + * Version: @(#)machine_table.c 1.0.22 2018/03/02 * * Authors: Sarah Walker, * Miran Grca, @@ -51,6 +51,7 @@ machine_t machines[] = { #if defined(DEV_BRANCH) && defined(USE_LASERXT) { "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL, NULL }, #endif + { "[8088] Xi8088", ROM_XI8088, "xi8088", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device, nvr_at_close }, { "[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL, nvr_at_close }, { "[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL, nvr_at_close }, diff --git a/src/mem.c b/src/mem.c index b213d9e88..7c40b6b0a 100644 --- a/src/mem.c +++ b/src/mem.c @@ -11,6 +11,7 @@ #include "cpu/x86_ops.h" #include "cpu/x86.h" #include "machine/machine.h" +#include "machine/m_xt_xi8088.h" #include "config.h" #include "io.h" #include "mem.h" @@ -1278,7 +1279,7 @@ void mem_set_mem_state(uint32_t base, uint32_t size, int state) void mem_add_bios() { - if (AT) + if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb())) { mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL, 0); mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL, 0); diff --git a/src/pc.c b/src/pc.c index 8b5813a06..aee2d5b47 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.60 2018/02/24 + * Version: @(#)pc.c 1.0.61 2018/03/02 * * Authors: Sarah Walker, * Miran Grca, @@ -495,7 +495,7 @@ pc_full_speed(void) if (! atfullspeed) { pclog("Set fullspeed - %i %i %i\n", is386, AT, cpuspeed2); if (AT) - setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed); + setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); else setpitclock(14318184.0); } @@ -509,7 +509,7 @@ void pc_speed_changed(void) { if (AT) - setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed); + setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); else setpitclock(14318184.0); @@ -886,7 +886,7 @@ pc_reset_hard_init(void) cpu_cache_int_enabled = cpu_cache_ext_enabled = 0; if (AT) - setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed); + setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); else setpitclock(14318184.0); } @@ -1019,7 +1019,7 @@ pc_thread(void *param) /* Run a block of code. */ startblit(); - clockrate = machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed; + clockrate = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed; if (is386) { #ifdef USE_DYNAREC @@ -1093,8 +1093,8 @@ pc_thread(void *param) if (title_update) { mbstowcs(wmachine, machine_getname(), strlen(machine_getname())+1); - mbstowcs(wcpu, machines[machine].cpu[cpu_manufacturer].cpus[cpu].name, - strlen(machines[machine].cpu[cpu_manufacturer].cpus[cpu].name)+1); + mbstowcs(wcpu, machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name, + strlen(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name)+1); swprintf(temp, sizeof_w(temp), L"%ls v%ls - %i%% - %ls - %ls - %ls", EMU_NAME_W,EMU_VERSION_W,fps,wmachine,wcpu, diff --git a/src/pit.c b/src/pit.c index 220aece1f..c7dbdc365 100644 --- a/src/pit.c +++ b/src/pit.c @@ -51,7 +51,7 @@ void setpitclock(float clock) bus_timing = clock/(double)cpu_busspeed; video_update_timing(); - xt_cpu_multi = (int64_t)((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed); + xt_cpu_multi = (int64_t)((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); RTCCONST=clock/32768.0; TIMER_USEC = (int64_t)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT)); device_speed_changed(); diff --git a/src/rom.c b/src/rom.c index d8ade5075..363bfbc37 100644 --- a/src/rom.c +++ b/src/rom.c @@ -13,7 +13,7 @@ * - c386sx16 BIOS fails checksum * - the loadfont() calls should be done elsewhere * - * Version: @(#)rom.c 1.0.32 2018/03/02 + * Version: @(#)rom.c 1.0.33 2018/03/02 * * Authors: Sarah Walker, * Miran Grca, @@ -35,6 +35,7 @@ #include "rom.h" #include "video/video.h" /* for loadfont() */ #include "plat.h" +#include "machine/m_xt_xi8088.h" int romspresent[ROM_MAX]; @@ -158,6 +159,42 @@ rom_load_linear(wchar_t *fn, uint32_t addr, int sz, int off, uint8_t *ptr) } +/* Load a ROM BIOS from its chips, linear mode with high bit flipped. */ +int +rom_load_linear_inverted(wchar_t *fn, uint32_t addr, int sz, int off, uint8_t *ptr) +{ + FILE *f = rom_fopen(fn, L"rb"); + + if (f == NULL) { + pclog("ROM: image '%ls' not found\n", fn); + return(0); + } + + /* Make sure we only look at the base-256K offset. */ + if (addr >= 0x40000) + { + addr = 0; + } + else + { + addr &= 0x03ffff; + } + + (void)fseek(f, 0, SEEK_END); + if (ftell(f) < sz) { + (void)fclose(f); + return(0); + } + + (void)fseek(f, off, SEEK_SET); + (void)fread(ptr+addr+0x10000, sz >> 1, 1, f); + (void)fread(ptr+addr, sz >> 1, 1, f); + (void)fclose(f); + + return(1); +} + + /* Load a ROM BIOS from its chips, interleaved mode. */ int rom_load_interleaved(wchar_t *fnl, wchar_t *fnh, uint32_t addr, int sz, int off, uint8_t *ptr) @@ -314,6 +351,23 @@ rom_load_bios(int rom_id) 0x008000, 32768, 0, rom)) return(1); break; + case ROM_XI8088: + if (rom_load_linear_inverted( + L"roms/machines/xi8088/bios-xi8088.bin", + 0x000000, 131072, 128, rom)) { + biosmask = 0x1ffff; + xi8088_bios_128kb_set(1); + return(1); + } else { + if (rom_load_linear( + L"roms/machines/xi8088/bios-xi8088.bin", + 0x000000, 65536, 128, rom)) { + xi8088_bios_128kb_set(0); + return(1); + } + } + break; + case ROM_IBMXT286: /* IBM PX-XT 286 */ if (rom_load_interleaved( L"roms/machines/ibmxt286/bios_5162_21apr86_u34_78x7460_27256.bin", diff --git a/src/rom.h b/src/rom.h index 936576844..d1fcfe4ee 100644 --- a/src/rom.h +++ b/src/rom.h @@ -8,7 +8,7 @@ * * Definitions for the ROM image handler. * - * Version: @(#)rom.h 1.0.15 2018/03/02 + * Version: @(#)rom.h 1.0.16 2018/03/02 * * Author: Fred N. van Kempen, * Copyright 2018 Fred N. van Kempen. @@ -55,6 +55,8 @@ enum { ROM_T1000, ROM_T1200, + ROM_XI8088, + ROM_IBMPCJR, ROM_TANDY, ROM_TANDY1000HX, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 07a08fc50..5a5ae9284 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.105 2018/03/02 +# Version: @(#)Makefile.mingw 1.0.106 2018/03/02 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -395,7 +395,7 @@ CPUOBJ := cpu.o cpu_table.o \ MCHOBJ := machine.o machine_table.o \ m_xt.o m_xt_compaq.o \ - m_xt_t1000.o \ + m_xt_t1000.o m_xt_xi8088.o \ m_pcjr.o \ m_amstrad.o \ m_europc.o m_europc_hdc.o \