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 \