From 719534c518c817f850391d355d84f1ce4473f9b4 Mon Sep 17 00:00:00 2001 From: nerd73 Date: Mon, 16 Dec 2019 13:54:59 -0700 Subject: [PATCH] IBM 386SLC/486SLC/486BL emulation --- src/cpu_new/808x.c | 5 ++- src/cpu_new/cpu.c | 82 ++++++++++++++++++++++++++++++++-- src/cpu_new/cpu.h | 63 ++++++++++++++------------ src/cpu_new/cpu_table.c | 28 ++++++++++++ src/cpu_new/x86_ops_mov_ctrl.h | 8 ++-- 5 files changed, 151 insertions(+), 35 deletions(-) diff --git a/src/cpu_new/808x.c b/src/cpu_new/808x.c index 285f9644b..818174b01 100644 --- a/src/cpu_new/808x.c +++ b/src/cpu_new/808x.c @@ -909,7 +909,10 @@ reset_common(int hard) cr0 = 1 << 30; else cr0 = 0; - cpu_cache_int_enabled = 0; + if (isibmcpu) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; cpu_state.eflags = 0; diff --git a/src/cpu_new/cpu.c b/src/cpu_new/cpu.c index 4dde87a96..8ed4a5937 100644 --- a/src/cpu_new/cpu.c +++ b/src/cpu_new/cpu.c @@ -151,6 +151,7 @@ int is286, is386, is486 = 1, cpu_iscyrix, + isibmcpu, israpidcad, is_pentium; @@ -259,12 +260,13 @@ cpu_set(void) is8086 = (cpu_s->cpu_type > CPU_8088); is286 = (cpu_s->cpu_type >= CPU_286); is386 = (cpu_s->cpu_type >= CPU_386SX); + isibmcpu = (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL); israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); - is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD); + is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL ); is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP); hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); - cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC); + cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC ); if (cpu_s->multi) { if (cpu_s->pci_speed) cpu_busspeed = cpu_s->pci_speed; @@ -484,7 +486,8 @@ cpu_set(void) timing_jmp_pm = 23; timing_jmp_pm_gate = 38; break; - + + case CPU_IBM386SLC: case CPU_386SX: timing_rr = 2; /*register dest - register src*/ timing_rm = 6; /*register dest - memory src*/ @@ -546,6 +549,79 @@ cpu_set(void) timing_jmp_pm = 27; timing_jmp_pm_gate = 45; break; + + case CPU_IBM486SLC: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); +#else + x86_setopcodes(ops_386, ops_486_0f); +#endif + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 5; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 4; /*register dest - memory src long*/ + timing_mrl = 5; /*memory dest - register src long*/ + timing_mml = 5; + timing_bt = 3-1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 4; + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 15; + timing_iret_v86 = 36; /*unknown*/ + timing_iret_pm = 20; + timing_iret_pm_outer = 36; + timing_call_rm = 18; + timing_call_pm = 20; + timing_call_pm_gate = 35; + timing_call_pm_gate_inner = 69; + timing_retf_rm = 13; + timing_retf_pm = 17; + timing_retf_pm_outer = 35; + timing_jmp_rm = 17; + timing_jmp_pm = 19; + timing_jmp_pm_gate = 32; + timing_misaligned = 3; + break; + case CPU_IBM486BL: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); +#else + x86_setopcodes(ops_386, ops_486_0f); +#endif + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 3-1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 4; + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 15; + timing_iret_v86 = 36; /*unknown*/ + timing_iret_pm = 20; + timing_iret_pm_outer = 36; + timing_call_rm = 18; + timing_call_pm = 20; + timing_call_pm_gate = 35; + timing_call_pm_gate_inner = 69; + timing_retf_rm = 13; + timing_retf_pm = 17; + timing_retf_pm_outer = 35; + timing_jmp_rm = 17; + timing_jmp_pm = 19; + timing_jmp_pm_gate = 32; + timing_misaligned = 3; + break; case CPU_RAPIDCAD: #ifdef USE_DYNAREC diff --git a/src/cpu_new/cpu.h b/src/cpu_new/cpu.h index 953f0bee1..0e868d99a 100644 --- a/src/cpu_new/cpu.h +++ b/src/cpu_new/cpu.h @@ -27,34 +27,37 @@ #define CPU_286 2 /* 286 class CPUs */ #define CPU_386SX 3 /* 386 class CPUs */ #define CPU_386DX 4 -#define CPU_RAPIDCAD 5 -#define CPU_486SLC 6 -#define CPU_486DLC 7 -#define CPU_i486SX 8 /* 486 class CPUs */ -#define CPU_Am486SX 9 -#define CPU_Cx486S 10 -#define CPU_i486DX 11 -#define CPU_Am486DX 12 -#define CPU_Cx486DX 13 -#define CPU_iDX4 14 -#define CPU_Cx5x86 15 -#define CPU_WINCHIP 16 /* 586 class CPUs */ -#define CPU_WINCHIP2 17 -#define CPU_PENTIUM 18 -#define CPU_PENTIUMMMX 19 -#define CPU_Cx6x86 20 -#define CPU_Cx6x86MX 21 -#define CPU_Cx6x86L 22 -#define CPU_CxGX1 23 -#define CPU_K5 24 -#define CPU_5K86 25 -#define CPU_K6 26 -#define CPU_K6_2 27 -#define CPU_K6_3 28 -#define CPU_K6_2P 29 -#define CPU_K6_3P 30 -#define CPU_PENTIUMPRO 31 /* 686 class CPUs */ -#define CPU_PENTIUM2D 32 +#define CPU_IBM386SLC 5 +#define CPU_IBM486SLC 6 +#define CPU_IBM486BL 7 +#define CPU_RAPIDCAD 8 +#define CPU_486SLC 9 +#define CPU_486DLC 10 +#define CPU_i486SX 11 /* 486 class CPUs */ +#define CPU_Am486SX 12 +#define CPU_Cx486S 13 +#define CPU_i486DX 14 +#define CPU_Am486DX 15 +#define CPU_Cx486DX 16 +#define CPU_iDX4 17 +#define CPU_Cx5x86 18 +#define CPU_WINCHIP 19 /* 586 class CPUs */ +#define CPU_WINCHIP2 20 +#define CPU_PENTIUM 21 +#define CPU_PENTIUMMMX 22 +#define CPU_Cx6x86 23 +#define CPU_Cx6x86MX 24 +#define CPU_Cx6x86L 25 +#define CPU_CxGX1 26 +#define CPU_K5 27 +#define CPU_5K86 28 +#define CPU_K6 29 +#define CPU_K6_2 30 +#define CPU_K6_3 31 +#define CPU_K6_2P 32 +#define CPU_K6_3P 33 +#define CPU_PENTIUMPRO 34 /* 686 class CPUs */ +#define CPU_PENTIUM2D 35 #define MANU_INTEL 0 #define MANU_AMD 1 @@ -90,6 +93,9 @@ extern CPU cpus_Am386SX[]; extern CPU cpus_Am386DX[]; extern CPU cpus_486SLC[]; extern CPU cpus_486DLC[]; +extern CPU cpus_IBM386SLC[]; +extern CPU cpus_IBM486SLC[]; +extern CPU cpus_IBM486BL[]; extern CPU cpus_i486[]; extern CPU cpus_Am486[]; extern CPU cpus_Cx486[]; @@ -324,6 +330,7 @@ extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ extern int is8086, is286, is386, is486; +extern int isibmcpu; extern int is_rapidcad; extern int hasfpu; #define CPU_FEATURE_RDTSC (1 << 0) diff --git a/src/cpu_new/cpu_table.c b/src/cpu_new/cpu_table.c index ee1d4d2ec..feee2e2b4 100644 --- a/src/cpu_new/cpu_table.c +++ b/src/cpu_new/cpu_table.c @@ -186,6 +186,34 @@ CPU cpus_486SLC[] = { {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; +CPU cpus_IBM386SLC[] = { + /*IBM 386SLC*/ + {"386SLC/16", CPU_IBM386SLC, 16000000, 1, 0, 0x300, 0, 0, 0, 3,3,3,3, 2}, + {"386SLC/20", CPU_IBM386SLC, 20000000, 1, 0, 0x300, 0, 0, 0, 4,4,3,3, 3}, + {"386SLC/25", CPU_IBM386SLC, 25000000, 1, 0, 0x300, 0, 0, 0, 4,4,3,3, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM486SLC[] = { + /*IBM 486SLC*/ + {"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, + {"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, + {"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 7}, + {"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, + {"486SLC3/100", CPU_IBM486SLC, 100000000, 3, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM486BL[] = { + /*IBM Blue Lightning*/ + {"486BL2/50", CPU_IBM486BL, 50000000, 2, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, + {"486BL2/66", CPU_IBM486BL, 66666666, 2, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, + {"486BL3/75", CPU_IBM486BL, 75000000, 3, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, + {"486BL3/100", CPU_IBM486BL, 100000000, 3, 0, 0x400, 0, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + CPU cpus_486DLC[] = { /*Cx486DLC*/ {"Cx486DLC/25", CPU_486DLC, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3}, diff --git a/src/cpu_new/x86_ops_mov_ctrl.h b/src/cpu_new/x86_ops_mov_ctrl.h index 55326dfe1..06a89884b 100644 --- a/src/cpu_new/x86_ops_mov_ctrl.h +++ b/src/cpu_new/x86_ops_mov_ctrl.h @@ -120,9 +120,11 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) mmu_perm=4; if (is486 && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) + else if (isibmcpu) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) cpu_update_waitstates(); if (cr0 & 1) cpu_cur_status |= CPU_STATUS_PMODE;