From 0f00cc432dcee09190c9f88777e2d9efb3750f8e Mon Sep 17 00:00:00 2001 From: "K.Ohta" Date: Tue, 21 May 2019 19:29:40 +0900 Subject: [PATCH] [VM][I386_DOSBOX] . --- .../vm/libcpu_newdev/dosbox-i386/core_normal.cpp | 20 +- .../libcpu_newdev/dosbox-i386/core_normal/string.h | 3 + .../dosbox-i386/core_normal/support.h | 4 +- .../dosbox-i386/core_normal/table_ea.h | 114 ++-- source/src/vm/libcpu_newdev/dosbox-i386/cpu.cpp | 198 +++---- source/src/vm/libcpu_newdev/dosbox-i386/flags.cpp | 7 +- .../src/vm/libcpu_newdev/dosbox-i386/include/cpu.h | 6 +- .../src/vm/libcpu_newdev/dosbox-i386/include/mem.h | 8 +- .../vm/libcpu_newdev/dosbox-i386/include/paging.h | 299 ++++------- .../vm/libcpu_newdev/dosbox-i386/instructions.h | 6 +- .../src/vm/libcpu_newdev/dosbox-i386/lazyflags.h | 29 +- source/src/vm/libcpu_newdev/dosbox-i386/modrm.cpp | 13 +- source/src/vm/libcpu_newdev/dosbox-i386/paging.cpp | 125 +++-- .../vm/libcpu_newdev/dosbox-i386/types_compat.h | 575 +++++++++++++++++++++ 14 files changed, 909 insertions(+), 498 deletions(-) create mode 100644 source/src/vm/libcpu_newdev/dosbox-i386/types_compat.h diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal.cpp index 1c0347430..f0525d537 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal.cpp +++ b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal.cpp @@ -16,21 +16,23 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include +#include "device.h" +#include "./types_compat.h" +//#include -#include "dosbox.h" -#include "mem.h" +//#include "dosbox.h" +//#include "mem.h" #include "cpu.h" #include "lazyflags.h" -#include "inout.h" -#include "callback.h" -#include "pic.h" +//#include "inout.h" +//#include "callback.h" +//#include "pic.h" #include "fpu.h" #include "paging.h" -#if C_DEBUG -#include "debug.h" -#endif +//#if C_DEBUG +//#include "debug.h" +//#endif #if (!C_CORE_INLINE) #define LoadMb(off) mem_readb(off) diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/string.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/string.h index 992ed42cb..2370264fe 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/string.h +++ b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/string.h @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +namespace I386_DOSBOX { enum STRING_OP { R_OUTSB,R_OUTSW,R_OUTSD, R_INSB,R_INSW,R_INSD, @@ -255,3 +256,5 @@ static void DoString(STRING_OP type) { reg_ecx|=(count & add_mask); } } + +}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/support.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/support.h index 6fe9a17c2..f52a3d6a4 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/support.h +++ b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/support.h @@ -15,7 +15,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#pragma once +namespace I386_DOSBOX { #define LoadMbs(off) (Bit8s)(LoadMb(off)) #define LoadMws(off) (Bit16s)(LoadMw(off)) @@ -88,6 +89,7 @@ static INLINE Bit32s Fetchds() { if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \ else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \ } +}; #include "helpers.h" #include "table_ea.h" diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/table_ea.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/table_ea.h index 920f5ce8f..df641b780 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/table_ea.h +++ b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/table_ea.h @@ -15,41 +15,43 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#pragma once +namespace I386_DOSBOX { + typedef PhysPt (*EA_LookupHandler)(void); /* The MOD/RM Decoder for EA for this decoder's addressing modes */ -static PhysPt EA_16_00_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si); } -static PhysPt EA_16_01_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di); } -static PhysPt EA_16_02_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si); } -static PhysPt EA_16_03_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di); } -static PhysPt EA_16_04_n(void) { return BaseDS+(Bit16u)(reg_si); } -static PhysPt EA_16_05_n(void) { return BaseDS+(Bit16u)(reg_di); } -static PhysPt EA_16_06_n(void) { return BaseDS+(Bit16u)(Fetchw());} -static PhysPt EA_16_07_n(void) { return BaseDS+(Bit16u)(reg_bx); } +__OPCALL PhysPt EA_16_00_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si); } +__OPCALL PhysPt EA_16_01_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di); } +__OPCALL PhysPt EA_16_02_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si); } +__OPCALL PhysPt EA_16_03_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di); } +__OPCALL PhysPt EA_16_04_n(void) { return BaseDS+(Bit16u)(reg_si); } +__OPCALL PhysPt EA_16_05_n(void) { return BaseDS+(Bit16u)(reg_di); } +__OPCALL PhysPt EA_16_06_n(void) { return BaseDS+(Bit16u)(Fetchw());} +__OPCALL PhysPt EA_16_07_n(void) { return BaseDS+(Bit16u)(reg_bx); } -static PhysPt EA_16_40_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_41_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_42_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } -static PhysPt EA_16_43_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } -static PhysPt EA_16_44_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchbs()); } -static PhysPt EA_16_45_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchbs()); } -static PhysPt EA_16_46_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchbs()); } -static PhysPt EA_16_47_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchbs()); } +__OPCALL PhysPt EA_16_40_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } +__OPCALL PhysPt EA_16_41_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } +__OPCALL PhysPt EA_16_42_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } +__OPCALL PhysPt EA_16_43_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } +__OPCALL PhysPt EA_16_44_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchbs()); } +__OPCALL PhysPt EA_16_45_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchbs()); } +__OPCALL PhysPt EA_16_46_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchbs()); } +__OPCALL PhysPt EA_16_47_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchbs()); } -static PhysPt EA_16_80_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_81_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_82_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } -static PhysPt EA_16_83_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } -static PhysPt EA_16_84_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchws()); } -static PhysPt EA_16_85_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchws()); } -static PhysPt EA_16_86_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchws()); } -static PhysPt EA_16_87_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchws()); } +__OPCALL PhysPt EA_16_80_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } +__OPCALL PhysPt EA_16_81_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } +__OPCALL PhysPt EA_16_82_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } +__OPCALL PhysPt EA_16_83_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } +__OPCALL PhysPt EA_16_84_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchws()); } +__OPCALL PhysPt EA_16_85_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchws()); } +__OPCALL PhysPt EA_16_86_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchws()); } +__OPCALL PhysPt EA_16_87_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchws()); } -static Bit32u SIBZero=0; -static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; +__OPCALL Bit32u SIBZero=0; +__OPCALL Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; -static INLINE PhysPt Sib(Bitu mode) { +__OPCALL_INLINE PhysPt Sib(Bitu mode) { Bit8u sib=Fetchb(); PhysPt base; switch (sib&7) { @@ -78,36 +80,36 @@ static INLINE PhysPt Sib(Bitu mode) { return base; } -static PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; } -static PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; } -static PhysPt EA_32_02_n(void) { return BaseDS+reg_edx; } -static PhysPt EA_32_03_n(void) { return BaseDS+reg_ebx; } -static PhysPt EA_32_04_n(void) { return Sib(0);} -static PhysPt EA_32_05_n(void) { return BaseDS+Fetchd(); } -static PhysPt EA_32_06_n(void) { return BaseDS+reg_esi; } -static PhysPt EA_32_07_n(void) { return BaseDS+reg_edi; } +__OPCALL PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; } +__OPCALL PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; } +__OPCALL PhysPt EA_32_02_n(void) { return BaseDS+reg_edx; } +__OPCALL PhysPt EA_32_03_n(void) { return BaseDS+reg_ebx; } +__OPCALL PhysPt EA_32_04_n(void) { return Sib(0);} +__OPCALL PhysPt EA_32_05_n(void) { return BaseDS+Fetchd(); } +__OPCALL PhysPt EA_32_06_n(void) { return BaseDS+reg_esi; } +__OPCALL PhysPt EA_32_07_n(void) { return BaseDS+reg_edi; } -static PhysPt EA_32_40_n(void) { return BaseDS+reg_eax+Fetchbs(); } -static PhysPt EA_32_41_n(void) { return BaseDS+reg_ecx+Fetchbs(); } -static PhysPt EA_32_42_n(void) { return BaseDS+reg_edx+Fetchbs(); } -static PhysPt EA_32_43_n(void) { return BaseDS+reg_ebx+Fetchbs(); } -static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();} -//static PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();} -static PhysPt EA_32_45_n(void) { return BaseSS+reg_ebp+Fetchbs(); } -static PhysPt EA_32_46_n(void) { return BaseDS+reg_esi+Fetchbs(); } -static PhysPt EA_32_47_n(void) { return BaseDS+reg_edi+Fetchbs(); } +__OPCALL PhysPt EA_32_40_n(void) { return BaseDS+reg_eax+Fetchbs(); } +__OPCALL PhysPt EA_32_41_n(void) { return BaseDS+reg_ecx+Fetchbs(); } +__OPCALL PhysPt EA_32_42_n(void) { return BaseDS+reg_edx+Fetchbs(); } +__OPCALL PhysPt EA_32_43_n(void) { return BaseDS+reg_ebx+Fetchbs(); } +__OPCALL PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();} +//__OPCALL PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();} +__OPCALL PhysPt EA_32_45_n(void) { return BaseSS+reg_ebp+Fetchbs(); } +__OPCALL PhysPt EA_32_46_n(void) { return BaseDS+reg_esi+Fetchbs(); } +__OPCALL PhysPt EA_32_47_n(void) { return BaseDS+reg_edi+Fetchbs(); } -static PhysPt EA_32_80_n(void) { return BaseDS+reg_eax+Fetchds(); } -static PhysPt EA_32_81_n(void) { return BaseDS+reg_ecx+Fetchds(); } -static PhysPt EA_32_82_n(void) { return BaseDS+reg_edx+Fetchds(); } -static PhysPt EA_32_83_n(void) { return BaseDS+reg_ebx+Fetchds(); } -static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();} -//static PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();} -static PhysPt EA_32_85_n(void) { return BaseSS+reg_ebp+Fetchds(); } -static PhysPt EA_32_86_n(void) { return BaseDS+reg_esi+Fetchds(); } -static PhysPt EA_32_87_n(void) { return BaseDS+reg_edi+Fetchds(); } +__OPCALL PhysPt EA_32_80_n(void) { return BaseDS+reg_eax+Fetchds(); } +__OPCALL PhysPt EA_32_81_n(void) { return BaseDS+reg_ecx+Fetchds(); } +__OPCALL PhysPt EA_32_82_n(void) { return BaseDS+reg_edx+Fetchds(); } +__OPCALL PhysPt EA_32_83_n(void) { return BaseDS+reg_ebx+Fetchds(); } +__OPCALL PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();} +//__OPCALL PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();} +__OPCALL PhysPt EA_32_85_n(void) { return BaseSS+reg_ebp+Fetchds(); } +__OPCALL PhysPt EA_32_86_n(void) { return BaseDS+reg_esi+Fetchds(); } +__OPCALL PhysPt EA_32_87_n(void) { return BaseDS+reg_edi+Fetchds(); } -static GetEAHandler EATable[512]={ +__OPCALL GetEAHandler EATable[512]={ /* 00 */ EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, @@ -182,4 +184,4 @@ static GetEAHandler EATable[512]={ eaa=BaseDS+Fetchw(); \ } \ - +}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/cpu.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/cpu.cpp index 90b79b664..12432b10a 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/cpu.cpp +++ b/source/src/vm/libcpu_newdev/dosbox-i386/cpu.cpp @@ -31,6 +31,62 @@ #include "lazyflags.h" #include "support.h" + + +Bitu TaskStateSegment::Get_back(void) { + d_cpu->cpu.mpl=0; + Bit16u backlink = d_cpu->mem_readw(base); + d_cpu->cpu.mpl=3; + return backlink; +} +void TaskStateSegment::SaveSelector(void) +{ + d_cpu->gdt.SetDescriptor(selector,desc); +} + +void TaskStateSegment::Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp) { + d_cpu->cpu.mpl=0; + if (is386) { + PhysPt where = base+ offsetof(TSS_32,esp0)+level*8; + _esp = d_cpu->mem_readd(where); + _ss = d_cpu->mem_readw(where+4); + } else { + PhysPt where=base+offsetof(TSS_16,sp0)+level*4; + _esp = d_cpu->mem_readw(where); + _ss = d_cpu->mem_readw(where+2); + } + d_cpu->cpu.mpl=3; +} + +bool TaskStateSegment::SetSelector(Bitu new_sel) +{ + valid=false; + if ((new_sel & 0xfffc)==0) { + selector=0; + base=0; + limit=0; + is386=1; + return true; + } + if (new_sel&4) return false; + if (!d_cpu->cpu.gdt.GetDescriptor(new_sel,desc)) return false; + switch (desc.Type()) { + case DESC_286_TSS_A: case DESC_286_TSS_B: + case DESC_386_TSS_A: case DESC_386_TSS_B: + break; + default: + return false; + } + if (!desc.saved.seg.p) return false; + selector = new_sel; + valid=true; + base = desc.GetBase(); + limit = desc.GetLimit(); + is386 = desc.Is386(); + return true; +} + +namespace I386_DOSBOX { Bitu DEBUG_EnableDebugger(void); extern void GFX_SetTitle(Bit32s cycles ,Bits frameskip,bool paused); @@ -44,43 +100,7 @@ extern void GFX_SetTitle(Bit32s cycles ,Bits frameskip,bool paused); #endif #endif -CPU_Regs cpu_regs; -CPUBlock cpu; -Segments Segs; - -Bit32s CPU_Cycles = 0; -Bit32s CPU_CycleLeft = 3000; -Bit32s CPU_CycleMax = 3000; -Bit32s CPU_OldCycleMax = 3000; -Bit32s CPU_CyclePercUsed = 100; -Bit32s CPU_CycleLimit = -1; -Bit32s CPU_CycleUp = 0; -Bit32s CPU_CycleDown = 0; -Bit64s CPU_IODelayRemoved = 0; -CPU_Decoder * cpudecoder; -bool CPU_CycleAutoAdjust = false; -bool CPU_SkipCycleAutoAdjust = false; -Bitu CPU_AutoDetermineMode = 0; - -Bitu CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; - -Bitu CPU_extflags_toggle=0; // ID and AC flags may be toggled depending on emulated CPU architecture - -Bitu CPU_PrefetchQueueSize=0; - -void CPU_Core_Full_Init(void); -void CPU_Core_Normal_Init(void); -void CPU_Core_Simple_Init(void); -#if (C_DYNAMIC_X86) -void CPU_Core_Dyn_X86_Init(void); -void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); -void CPU_Core_Dyn_X86_Cache_Close(void); -void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu); -#elif (C_DYNREC) -void CPU_Core_Dynrec_Init(void); -void CPU_Core_Dynrec_Cache_Init(bool enable_cache); -void CPU_Core_Dynrec_Cache_Close(void); -#endif + /* In debug mode exceptions are tested and dosbox exits when * a unhandled exception state is detected. @@ -270,73 +290,6 @@ void CPU_CheckSegments(void) { if (needs_invalidation) CPU_SetSegGeneral(gs,0); } - -class TaskStateSegment { -public: - TaskStateSegment() { - valid=false; - } - bool IsValid(void) { - return valid; - } - Bitu Get_back(void) { - cpu.mpl=0; - Bit16u backlink=mem_readw(base); - cpu.mpl=3; - return backlink; - } - void SaveSelector(void) { - cpu.gdt.SetDescriptor(selector,desc); - } - void Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp) { - cpu.mpl=0; - if (is386) { - PhysPt where=base+offsetof(TSS_32,esp0)+level*8; - _esp=mem_readd(where); - _ss=mem_readw(where+4); - } else { - PhysPt where=base+offsetof(TSS_16,sp0)+level*4; - _esp=mem_readw(where); - _ss=mem_readw(where+2); - } - cpu.mpl=3; - } - bool SetSelector(Bitu new_sel) { - valid=false; - if ((new_sel & 0xfffc)==0) { - selector=0; - base=0; - limit=0; - is386=1; - return true; - } - if (new_sel&4) return false; - if (!cpu.gdt.GetDescriptor(new_sel,desc)) return false; - switch (desc.Type()) { - case DESC_286_TSS_A: case DESC_286_TSS_B: - case DESC_386_TSS_A: case DESC_386_TSS_B: - break; - default: - return false; - } - if (!desc.saved.seg.p) return false; - selector=new_sel; - valid=true; - base=desc.GetBase(); - limit=desc.GetLimit(); - is386=desc.Is386(); - return true; - } - TSS_Descriptor desc; - Bitu selector; - PhysPt base; - Bitu limit; - Bitu is386; - bool valid; -}; - -TaskStateSegment cpu_tss; - enum TSwitchType { TSwitch_JMP,TSwitch_CALL_INT,TSwitch_IRET }; @@ -344,6 +297,7 @@ enum TSwitchType { bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) { FillFlags(); TaskStateSegment new_tss; + new_tss.SetCpuDomain(this); if (!new_tss.SetSelector(new_tss_selector)) E_Exit("Illegal TSS for switch, selector=%x, switchtype=%x",new_tss_selector,tstype); if (tstype==TSwitch_IRET) { @@ -2163,15 +2117,13 @@ void CPU_Disable_SkipAutoAdjust(void) { } -extern Bit32s ticksDone; -extern Bit32u ticksScheduled; void CPU_Reset_AutoAdjust(void) { CPU_IODelayRemoved = 0; ticksDone = 0; ticksScheduled = 0; } - +#if 0 class CPU: public Module_base { private: static bool inited; @@ -2407,21 +2359,21 @@ public: } ~CPU(){ /* empty */}; }; - -static CPU * test; - -void CPU_ShutDown(Section* sec) { -#if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Cache_Close(); -#elif (C_DYNREC) - CPU_Core_Dynrec_Cache_Close(); -#endif - delete test; -} +#endif +//static CPU * test; + +//void CPU_ShutDown(Section* sec) { +//#if (C_DYNAMIC_X86) +// CPU_Core_Dyn_X86_Cache_Close(); +//#elif (C_DYNREC) +// CPU_Core_Dynrec_Cache_Close(); +//#endif +// delete test; +//} + +//void CPU_Init(Section* sec) { +// test = new CPU(sec); +// sec->AddDestroyFunction(&CPU_ShutDown,true); +//} -void CPU_Init(Section* sec) { - test = new CPU(sec); - sec->AddDestroyFunction(&CPU_ShutDown,true); } -//initialize static members -bool CPU::inited=false; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/flags.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/flags.cpp index 1559af1ed..b5cf940a7 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/flags.cpp +++ b/source/src/vm/libcpu_newdev/dosbox-i386/flags.cpp @@ -21,12 +21,12 @@ Probably still some bugs left in here. */ -#include "dosbox.h" +//#include "dosbox.h" #include "cpu.h" -#include "lazyflags.h" +#include "./lazyflags.h" #include "pic.h" -LazyFlags lflags; +namespace I386_DOSBOX { /* CF Carry Flag -- Set on high-order bit carry or borrow; cleared otherwise. @@ -1186,3 +1186,4 @@ void DestroyConditionFlags(void) { } #endif +}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/cpu.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/cpu.h index 2f27f2c06..d3d4e0b06 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/cpu.h +++ b/source/src/vm/libcpu_newdev/dosbox-i386/include/cpu.h @@ -475,14 +475,14 @@ struct CPUBlock { Bit32u trx[8]; }; -extern CPUBlock cpu; +//extern CPUBlock cpu; -static INLINE void CPU_SetFlagsd(Bitu word) { +INLINE void I386_DOSBOX::CPU_SetFlagsd(Bitu word) { Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL; CPU_SetFlags(word,mask); } -static INLINE void CPU_SetFlagsw(Bitu word) { +INLINE void I386_DOSBOX::CPU_SetFlagsw(Bitu word) { Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff; CPU_SetFlags(word,mask); } diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/mem.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/mem.h index d362cb030..3a4b28ca0 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/mem.h +++ b/source/src/vm/libcpu_newdev/dosbox-i386/include/mem.h @@ -19,9 +19,7 @@ #ifndef DOSBOX_MEM_H #define DOSBOX_MEM_H -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif +#include "../types_compat.h" typedef Bit32u PhysPt; typedef Bit8u * HostPt; @@ -31,6 +29,8 @@ typedef Bit32s MemHandle; #define MEM_PAGESIZE 4096 +namespace DOSBOX_I386 { + extern HostPt MemBase; HostPt GetMemBase(void); @@ -60,6 +60,7 @@ MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); #if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) static INLINE Bit8u host_readb(HostPt off) { + return off[0]; } static INLINE Bit16u host_readw(HostPt off) { @@ -214,6 +215,7 @@ static INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) { static INLINE RealPt RealGetVec(Bit8u vec) { return mem_readd(vec<<2); } +}; #endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/paging.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/paging.h index bf01dfa38..8766238c7 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/paging.h +++ b/source/src/vm/libcpu_newdev/dosbox-i386/include/paging.h @@ -20,17 +20,16 @@ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif // disable this to reduce the size of the TLB // NOTE: does not work with the dynamic core (dynrec is fine) #define USE_FULL_TLB +#include "../types_compat.h" + +class I386_DOSBOX; +namespace I386_DOSBOX { + class PageDirectory; #define MEM_PAGE_SIZE (4096) @@ -57,9 +56,32 @@ class PageDirectory; //Allow 128 mb of memory to be linked #define PAGING_LINKS (128*1024/4) -class PageHandler { +#define LINK_TOTAL (64*1024) + +#define USERWRITE_PROHIBITED ((cpu.cpl&cpu.mpl)==3) + +struct PF_Entry { + Bitu cs; + Bitu eip; + Bitu page_addr; + Bitu mpl; +}; + +#define PF_QUEUESIZE 16 +static struct { + Bitu used; + PF_Entry entries[PF_QUEUESIZE]; +} pf_queue; + + +class PageHandler : public MinimumSkelton{ + I386_DOSBOX *d_parent; public: - virtual ~PageHandler(void) { } + PageHandler(DEVICE *parent) : MinimumSkelton(parent) + { + d_parent = static_cast(parent); + } + virtual ~PageHandler() { } virtual Bitu readb(PhysPt addr); virtual Bitu readw(PhysPt addr); virtual Bitu readd(PhysPt addr); @@ -74,29 +96,73 @@ public: virtual bool writeb_checked(PhysPt addr,Bitu val); virtual bool writew_checked(PhysPt addr,Bitu val); virtual bool writed_checked(PhysPt addr,Bitu val); + + inline Bit8u phys_readb(Bit32u addr); + inline Bit16u phys_readw(Bit32u addr); + inline Bit32u phys_readd(Bit32u addr); + + inline void phys_writeb(Bit32u addr, Bit8u val); + inline void phys_writew(Bit32u addr, Bit16u val); + inline void phys_writed(Bit32u addr, Bit32u val); + + INLINE void InitPageUpdateLink(Bitu relink,PhysPt addr); + INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry); + INLINE bool InitPage_CheckUseraccess(Bitu u1,Bitu u2); + INLINE void InitPageCheckPresence(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry); + + PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode); + Bits PageFaultCore(void); Bitu flags; }; +inline Bit8u PageHandler::phys_readb(Bit32u addr) +{ + return d_parent->read_data8(addr); +} +inline Bit16u PageHandler::phys_readw(Bit32u addr) +{ + return d_parent->read_data16(addr); +} + +inline Bit32u PageHandler::phys_readd(Bit32u addr) +{ + return d_parent->read_data32(addr); +} + +inline void PageHandler::phys_writeb(Bit32u addr, Bit32u val) +{ + d_parent->write_data8(addr, val); +} + +inline void PageHandler::phys_writew(Bit32u addr, Bit32u val) +{ + d_parent->write_data16(addr, val); +} + +inline void PageHandler::phys_writed(Bit32u addr, Bit32u val) +{ + d_parent->write_data32(addr, val); +} /* Some other functions */ -void PAGING_Enable(bool enabled); -bool PAGING_Enabled(void); +//void PAGING_Enable(bool enabled); +//bool PAGING_Enabled(void); -Bitu PAGING_GetDirBase(void); -void PAGING_SetDirBase(Bitu cr3); -void PAGING_InitTLB(void); -void PAGING_ClearTLB(void); +//Bitu PAGING_GetDirBase(void); +//void PAGING_SetDirBase(Bitu cr3); +//void PAGING_InitTLB(void); +//void PAGING_ClearTLB(void); -void PAGING_LinkPage(Bitu lin_page,Bitu phys_page); -void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page); -void PAGING_UnlinkPages(Bitu lin_page,Bitu pages); +//void PAGING_LinkPage(Bitu lin_page,Bitu phys_page); +//void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page); +//void PAGING_UnlinkPages(Bitu lin_page,Bitu pages); /* This maps the page directly, only use when paging is disabled */ -void PAGING_MapPage(Bitu lin_page,Bitu phys_page); -bool PAGING_MakePhysPage(Bitu & page); -bool PAGING_ForcePageInit(Bitu lin_addr); +//void PAGING_MapPage(Bitu lin_page,Bitu phys_page); +//bool PAGING_MakePhysPage(Bitu & page); +//bool PAGING_ForcePageInit(Bitu lin_addr); -void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler); -void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler); -void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); +//void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler); +//void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler); +//void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); #ifdef _MSC_VER @@ -176,189 +242,24 @@ struct PagingBlock { bool enabled; }; -extern PagingBlock paging; +//extern PagingBlock paging; /* Some support functions */ -PageHandler * MEM_GetPageHandler(Bitu phys_page); +//PageHandler * MEM_GetPageHandler(Bitu phys_page); /* Unaligned address handlers */ -Bit16u mem_unalignedreadw(PhysPt address); -Bit32u mem_unalignedreadd(PhysPt address); -void mem_unalignedwritew(PhysPt address,Bit16u val); -void mem_unalignedwrited(PhysPt address,Bit32u val); - -bool mem_unalignedreadw_checked(PhysPt address,Bit16u * val); -bool mem_unalignedreadd_checked(PhysPt address,Bit32u * val); -bool mem_unalignedwritew_checked(PhysPt address,Bit16u val); -bool mem_unalignedwrited_checked(PhysPt address,Bit32u val); - -#if defined(USE_FULL_TLB) - -static INLINE HostPt get_tlb_read(PhysPt address) { - return paging.tlb.read[address>>12]; -} -static INLINE HostPt get_tlb_write(PhysPt address) { - return paging.tlb.write[address>>12]; -} -static INLINE PageHandler* get_tlb_readhandler(PhysPt address) { - return paging.tlb.readhandler[address>>12]; -} -static INLINE PageHandler* get_tlb_writehandler(PhysPt address) { - return paging.tlb.writehandler[address>>12]; -} +//Bit16u mem_unalignedreadw(PhysPt address); +//Bit32u mem_unalignedreadd(PhysPt address); +//void mem_unalignedwritew(PhysPt address,Bit16u val); +//void mem_unalignedwrited(PhysPt address,Bit32u val); -/* Use these helper functions to access linear addresses in readX/writeX functions */ -static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { - return (paging.tlb.phys_page[linePage>>12]<<12); -} - -static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { - return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); -} - -#else - -void PAGING_InitTLBBank(tlb_entry **bank); - -static INLINE tlb_entry *get_tlb_entry(PhysPt address) { - Bitu index=(address>>12); - if (TLB_BANKS && (index > TLB_SIZE)) { - Bitu bank=(address>>BANK_SHIFT) - 1; - if (!paging.tlbh_banks[bank]) - PAGING_InitTLBBank(&paging.tlbh_banks[bank]); - return &paging.tlbh_banks[bank][index & BANK_MASK]; - } - return &paging.tlbh[index]; -} - -static INLINE HostPt get_tlb_read(PhysPt address) { - return get_tlb_entry(address)->read; -} -static INLINE HostPt get_tlb_write(PhysPt address) { - return get_tlb_entry(address)->write; -} -static INLINE PageHandler* get_tlb_readhandler(PhysPt address) { - return get_tlb_entry(address)->readhandler; -} -static INLINE PageHandler* get_tlb_writehandler(PhysPt address) { - return get_tlb_entry(address)->writehandler; -} - -/* Use these helper functions to access linear addresses in readX/writeX functions */ -static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { - tlb_entry *entry = get_tlb_entry(linePage); - return (entry->phys_page<<12); -} - -static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { - tlb_entry *entry = get_tlb_entry(linAddr); - return (entry->phys_page<<12)|(linAddr&0xfff); -} -#endif - -/* Special inlined memory reading/writing */ -static INLINE Bit8u mem_readb_inline(PhysPt address) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) return host_readb(tlb_addr+address); - else return (Bit8u)(get_tlb_readhandler(address))->readb(address); -} - -static INLINE Bit16u mem_readw_inline(PhysPt address) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) return host_readw(tlb_addr+address); - else return (Bit16u)(get_tlb_readhandler(address))->readw(address); - } else return mem_unalignedreadw(address); -} - -static INLINE Bit32u mem_readd_inline(PhysPt address) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) return host_readd(tlb_addr+address); - else return (get_tlb_readhandler(address))->readd(address); - } else return mem_unalignedreadd(address); -} - -static INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) host_writeb(tlb_addr + address, val); - else (get_tlb_writehandler(address))->writeb(address,val); -} - -static INLINE void mem_writew_inline(PhysPt address,Bit16u val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) host_writew(tlb_addr+address,val); - else (get_tlb_writehandler(address))->writew(address,val); - } else mem_unalignedwritew(address,val); -} - -static INLINE void mem_writed_inline(PhysPt address,Bit32u val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) host_writed(tlb_addr+address,val); - else (get_tlb_writehandler(address))->writed(address,val); - } else mem_unalignedwrited(address,val); -} - - -static INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *val=host_readb(tlb_addr+address); - return false; - } else return (get_tlb_readhandler(address))->readb_checked(address, val); -} - -static INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *val=host_readw(tlb_addr+address); - return false; - } else return (get_tlb_readhandler(address))->readw_checked(address, val); - } else return mem_unalignedreadw_checked(address, val); -} - -static INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *val=host_readd(tlb_addr+address); - return false; - } else return (get_tlb_readhandler(address))->readd_checked(address, val); - } else return mem_unalignedreadd_checked(address, val); -} - -static INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - host_writeb(tlb_addr+address,val); - return false; - } else return (get_tlb_writehandler(address))->writeb_checked(address,val); -} - -static INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - host_writew(tlb_addr+address,val); - return false; - } else return (get_tlb_writehandler(address))->writew_checked(address,val); - } else return mem_unalignedwritew_checked(address,val); -} - -static INLINE bool mem_writed_checked(PhysPt address,Bit32u val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - host_writed(tlb_addr+address,val); - return false; - } else return (get_tlb_writehandler(address))->writed_checked(address,val); - } else return mem_unalignedwrited_checked(address,val); -} +//bool mem_unalignedreadw_checked(PhysPt address,Bit16u * val); +//bool mem_unalignedreadd_checked(PhysPt address,Bit32u * val); +//bool mem_unalignedwritew_checked(PhysPt address,Bit16u val); +//bool mem_unalignedwrited_checked(PhysPt address,Bit32u val); +}; #endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/instructions.h b/source/src/vm/libcpu_newdev/dosbox-i386/instructions.h index 28af3314c..5c0fb47a0 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/instructions.h +++ b/source/src/vm/libcpu_newdev/dosbox-i386/instructions.h @@ -15,9 +15,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#pragma once /* Jumps */ - +namespace I386_DOSBOX { /* All Byte general instructions */ #define ADDB(op1,op2,load,save) \ lf_var1b=load(op1);lf_var2b=op2; \ @@ -961,3 +961,5 @@ #define BSWAPD(op1) \ op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000); + +}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/lazyflags.h b/source/src/vm/libcpu_newdev/dosbox-i386/lazyflags.h index c5e599f53..a5d310599 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/lazyflags.h +++ b/source/src/vm/libcpu_newdev/dosbox-i386/lazyflags.h @@ -19,31 +19,7 @@ #ifndef DOSBOX_LAZYFLAGS_H #define DOSBOX_LAZYFLAGS_H -//Flag Handling -Bit32u get_CF(void); -Bit32u get_AF(void); -Bit32u get_ZF(void); -Bit32u get_SF(void); -Bit32u get_OF(void); -Bit32u get_PF(void); - -Bitu FillFlags(void); -void FillFlagsNoCFOF(void); -void DestroyConditionFlags(void); - -#ifndef DOSBOX_REGS_H -#include "regs.h" -#endif - -struct LazyFlags { - GenReg32 var1,var2,res; - Bitu type; - Bitu prev_type; - Bitu oldcf; -}; - -extern LazyFlags lfags; - +namespace I386_DOSBOX { #define lf_var1b lflags.var1.byte[BL_INDEX] #define lf_var2b lflags.var2.byte[BL_INDEX] #define lf_resb lflags.res.byte[BL_INDEX] @@ -57,8 +33,6 @@ extern LazyFlags lfags; #define lf_resd lflags.res.dword[DW_INDEX] -extern LazyFlags lflags; - #define SETFLAGSb(FLAGB) \ { \ SETFLAGBIT(OF,get_OF()); \ @@ -131,4 +105,5 @@ enum { t_LASTFLAG }; +}; #endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/modrm.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/modrm.cpp index 028e4d71e..88fdd7eb1 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/modrm.cpp +++ b/source/src/vm/libcpu_newdev/dosbox-i386/modrm.cpp @@ -18,8 +18,9 @@ #include "cpu.h" +namespace DOSBOX_I386 { -Bit8u * lookupRMregb[]= +const Bit8u * lookupRMregb[]= { ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, @@ -58,7 +59,7 @@ Bit8u * lookupRMregb[]= ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh }; -Bit16u * lookupRMregw[]={ +const Bit16u * lookupRMregw[]={ ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, @@ -96,7 +97,7 @@ Bit16u * lookupRMregw[]={ ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di }; -Bit32u * lookupRMregd[256]={ +const Bit32u * lookupRMregd[256]={ ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, @@ -135,7 +136,7 @@ Bit32u * lookupRMregd[256]={ }; -Bit8u * lookupRMEAregb[256]={ +const Bit8u * lookupRMEAregb[256]={ /* 12 lines of 16*0 should give nice errors when used */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -159,7 +160,7 @@ Bit8u * lookupRMEAregb[256]={ ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh }; -Bit16u * lookupRMEAregw[256]={ +const Bit16u * lookupRMEAregw[256]={ /* 12 lines of 16*0 should give nice errors when used */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -183,7 +184,7 @@ Bit16u * lookupRMEAregw[256]={ ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di }; -Bit32u * lookupRMEAregd[256]={ +const Bit32u * lookupRMEAregd[256]={ /* 12 lines of 16*0 should give nice errors when used */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/paging.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/paging.cpp index 7be15e1ab..86168280a 100644 --- a/source/src/vm/libcpu_newdev/dosbox-i386/paging.cpp +++ b/source/src/vm/libcpu_newdev/dosbox-i386/paging.cpp @@ -23,18 +23,14 @@ #include "dosbox.h" #include "mem.h" -#include "paging.h" -#include "regs.h" -#include "lazyflags.h" -#include "cpu.h" -#include "debug.h" -#include "setup.h" - -#define LINK_TOTAL (64*1024) - -#define USERWRITE_PROHIBITED ((cpu.cpl&cpu.mpl)==3) - - +#include "./include/paging.h" +#include "./include/regs.h" +#include "./lazyflags.h" +#include "./include/cpu.h" +//#include "debug.h" +//#include "setup.h" + +namespace I386_DOSBOX { PagingBlock paging; @@ -98,32 +94,18 @@ bool PageHandler::writed_checked(PhysPt addr,Bitu val) { } - -struct PF_Entry { - Bitu cs; - Bitu eip; - Bitu page_addr; - Bitu mpl; -}; - -#define PF_QUEUESIZE 16 -static struct { - Bitu used; - PF_Entry entries[PF_QUEUESIZE]; -} pf_queue; - -static Bits PageFaultCore(void) { - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=1; - Bits ret=CPU_Core_Full_Run(); - CPU_CycleLeft+=CPU_Cycles; +Bits PageHandler::PageFaultCore(void) { + d_parent->CPU_CycleLeft += d_parent->CPU_Cycles; + d_parent->CPU_Cycles=1; + Bits ret= d_parent->CPU_Core_Full_Run(); + d_parent->CPU_CycleLeft += d_parent->CPU_Cycles; if (ret<0) E_Exit("Got a dosbox close machine in pagefault core?"); if (ret) return ret; if (!pf_queue.used) E_Exit("PF Core without PF"); - PF_Entry * entry=&pf_queue.entries[pf_queue.used-1]; + PF_Entry * entry=&(d_parent->pf_queue.entries[pf_queue.used-1]); X86PageEntry pentry; - pentry.load=phys_readd(entry->page_addr); + pentry.load = phys_readd(entry->page_addr); if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) { cpu.mpl=entry->mpl; return -1; @@ -136,7 +118,7 @@ Bitu DEBUG_EnableDebugger(void); bool first=false; -void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) { +void PageHandler::PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) { /* Save the state of the cpu cores */ LazyFlags old_lflags; memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); @@ -166,7 +148,7 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) { // LOG_MSG("SS:%04x SP:%08X",SegValue(ss),reg_esp); } -static INLINE void InitPageUpdateLink(Bitu relink,PhysPt addr) { +INLINE void PageHandler::InitPageUpdateLink(Bitu relink,PhysPt addr) { if (relink==0) return; if (paging.links.used) { if (paging.links.entries[paging.links.used-1]==(addr>>12)) { @@ -177,7 +159,7 @@ static INLINE void InitPageUpdateLink(Bitu relink,PhysPt addr) { if (relink>1) PAGING_LinkPage_ReadOnly(addr>>12,relink); } -static INLINE void InitPageCheckPresence(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { +INLINE void PageHandler::InitPageCheckPresence(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { Bitu lin_page=lin_addr >> 12; Bitu d_index=lin_page >> 10; Bitu t_index=lin_page & 0x3ff; @@ -203,7 +185,7 @@ static INLINE void InitPageCheckPresence(PhysPt lin_addr,bool writing,X86PageEnt } } -static INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { +INLINE bool PageHandler::InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { Bitu lin_page=lin_addr >> 12; Bitu d_index=lin_page >> 10; Bitu t_index=lin_page & 0x3ff; @@ -227,7 +209,7 @@ static INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing, } // check if a user-level memory access would trigger a privilege page fault -static INLINE bool InitPage_CheckUseraccess(Bitu u1,Bitu u2) { +INLINE bool PageHandler::InitPage_CheckUseraccess(Bitu u1,Bitu u2) { switch (CPU_ArchitectureType) { case CPU_ARCHTYPE_MIXED: case CPU_ARCHTYPE_386SLOW: @@ -244,75 +226,76 @@ static INLINE bool InitPage_CheckUseraccess(Bitu u1,Bitu u2) { class InitPageHandler : public PageHandler { public: - InitPageHandler() { + InitPageHandler(DEVICE* parent) : PageHandler(parent) + { flags=PFLAG_INIT|PFLAG_NOCODE; } Bitu readb(PhysPt addr) { Bitu needs_reset=InitPage(addr,false); - Bit8u val=mem_readb(addr); + Bit8u val=d_dev->read_data8(addr); InitPageUpdateLink(needs_reset,addr); return val; } Bitu readw(PhysPt addr) { Bitu needs_reset=InitPage(addr,false); - Bit16u val=mem_readw(addr); + Bit16u val=d_dev->read_data16(addr); InitPageUpdateLink(needs_reset,addr); return val; } Bitu readd(PhysPt addr) { Bitu needs_reset=InitPage(addr,false); - Bit32u val=mem_readd(addr); + Bit32u val=d_dev->read_data32(addr); InitPageUpdateLink(needs_reset,addr); return val; } void writeb(PhysPt addr,Bitu val) { Bitu needs_reset=InitPage(addr,true); - mem_writeb(addr,val); + d_dev->write_data8(addr, val); InitPageUpdateLink(needs_reset,addr); } void writew(PhysPt addr,Bitu val) { Bitu needs_reset=InitPage(addr,true); - mem_writew(addr,val); + d_dev->write_data16(addr, val); InitPageUpdateLink(needs_reset,addr); } void writed(PhysPt addr,Bitu val) { Bitu needs_reset=InitPage(addr,true); - mem_writed(addr,val); + d_dev->write_data32(addr, val); InitPageUpdateLink(needs_reset,addr); } bool readb_checked(PhysPt addr, Bit8u * val) { if (InitPageCheckOnly(addr,false)) { - *val=mem_readb(addr); + *val=d_dev->read_data8(addr); return false; } else return true; } bool readw_checked(PhysPt addr, Bit16u * val) { if (InitPageCheckOnly(addr,false)){ - *val=mem_readw(addr); + *val=d_dev->read_data16(addr); return false; } else return true; } bool readd_checked(PhysPt addr, Bit32u * val) { if (InitPageCheckOnly(addr,false)) { - *val=mem_readd(addr); + *val=d_dev->read_data32(addr); return false; } else return true; } bool writeb_checked(PhysPt addr,Bitu val) { if (InitPageCheckOnly(addr,true)) { - mem_writeb(addr,val); + d_dev->write_data8(addr, val); return false; } else return true; } bool writew_checked(PhysPt addr,Bitu val) { if (InitPageCheckOnly(addr,true)) { - mem_writew(addr,val); + d_dev->write_data16(addr, val); return false; } else return true; } bool writed_checked(PhysPt addr,Bitu val) { if (InitPageCheckOnly(addr,true)) { - mem_writed(addr,val); + d_dev->write_data32(addr, val); return false; } else return true; } @@ -473,20 +456,21 @@ public: class InitPageUserROHandler : public PageHandler { public: - InitPageUserROHandler() { + InitPageUserROHandler(DEVICE* parent) : PageHandler(parent) + { flags=PFLAG_INIT|PFLAG_NOCODE; } void writeb(PhysPt addr,Bitu val) { InitPage(addr,(Bit8u)(val&0xff)); - host_writeb(get_tlb_read(addr)+addr,(Bit8u)(val&0xff)); + d_dev->write_data8(get_tlb_read(addr)+addr,(Bit8u)(val&0xff)); } void writew(PhysPt addr,Bitu val) { InitPage(addr,(Bit16u)(val&0xffff)); - host_writew(get_tlb_read(addr)+addr,(Bit16u)(val&0xffff)); + d_dev->write_data16(get_tlb_read(addr)+addr,(Bit16u)(val&0xffff)); } void writed(PhysPt addr,Bitu val) { InitPage(addr,(Bit32u)val); - host_writed(get_tlb_read(addr)+addr,(Bit32u)val); + d_dev->write_data32(get_tlb_read(addr)+addr,(Bit32u)val); } bool writeb_checked(PhysPt addr,Bitu val) { Bitu writecode=InitPageCheckOnly(addr,(Bit8u)(val&0xff)); @@ -494,7 +478,7 @@ public: HostPt tlb_addr; if (writecode>1) tlb_addr=get_tlb_read(addr); else tlb_addr=get_tlb_write(addr); - host_writeb(tlb_addr+addr,(Bit8u)(val&0xff)); + d_dev->write_data8(tlb_addr+addr,(Bit8u)(val&0xff)); return false; } return true; @@ -505,7 +489,7 @@ public: HostPt tlb_addr; if (writecode>1) tlb_addr=get_tlb_read(addr); else tlb_addr=get_tlb_write(addr); - host_writew(tlb_addr+addr,(Bit16u)(val&0xffff)); + d_dev->write_data16(tlb_addr+addr,(Bit16u)(val&0xffff)); return false; } return true; @@ -516,7 +500,7 @@ public: HostPt tlb_addr; if (writecode>1) tlb_addr=get_tlb_read(addr); else tlb_addr=get_tlb_write(addr); - host_writed(tlb_addr+addr,(Bit32u)val); + d_dev->write_data32(tlb_addr+addr,(Bit32u)val); return false; } return true; @@ -644,6 +628,9 @@ bool PAGING_ForcePageInit(Bitu lin_addr) { } #if defined(USE_FULL_TLB) +INLINE void InitTLBInt(tlb_entry *bank) { +} + void PAGING_InitTLB(void) { for (Bitu i=0;i(parent); + + d_parent->paging.enabled=false; + d_parent->PAGING_InitTLB(); Bitu i; for (i=0;ipaging.firstmb[i]=i; } - pf_queue.used=0; + d_parent->pf_queue.used=0; + } ~PAGING(){} }; static PAGING* test; + void PAGING_Init(Section * sec) { - test = new PAGING(sec); + test = new PAGING(this, sec); } +}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/types_compat.h b/source/src/vm/libcpu_newdev/dosbox-i386/types_compat.h new file mode 100644 index 000000000..34fc55406 --- /dev/null +++ b/source/src/vm/libcpu_newdev/dosbox-i386/types_compat.h @@ -0,0 +1,575 @@ +/* + Skelton for retropc emulator + + Origin : MAME i386 core + Author : Kyuma.Ohta + Date : 2019.05.21- + + [ i386-i586 core compatible header from DOSBOX] +*/ + + +#if !defined(__CSP_I386_DOSBOX_TYPES_COMPAT_H__) +#define __CSP_I386_DOSBOX_TYPES_COMPAT_H__ + +#ifndef __OPCALL +#define __OPCALL +#endif + +#ifndef __OPCALL_INLINE +#define __OPCALL_INLINE __inline__ +#endif + +#ifndef INLINE +#define INLINE __inline__ +#endif + +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif + +#if C_ATTRIBUTE_ALWAYS_INLINE +#define INLINE inline __attribute__((always_inline)) +#else +#define INLINE inline +#endif + +#if C_ATTRIBUTE_FASTCALL +#define DB_FASTCALL __attribute__((fastcall)) +#else +#define DB_FASTCALL +#endif + +#if C_HAS_ATTRIBUTE +#define GCC_ATTRIBUTE(x) __attribute__ ((x)) +#else +#define GCC_ATTRIBUTE(x) /* attribute not supported */ +#endif + +#if C_HAS_BUILTIN_EXPECT +#define GCC_UNLIKELY(x) __builtin_expect((x),0) +#define GCC_LIKELY(x) __builtin_expect((x),1) +#else +#define GCC_UNLIKELY(x) (x) +#define GCC_LIKELY(x) (x) +#endif + +typedef uint8_t Bit8u; +typedef uint16_t Bit16u; +typedef uint33_t Bit32u; +typedef uint64_t Bit64u; + +typedef int8_t Bit8s; +typedef int16_t Bit16s; +typedef int33_t Bit32s; +typedef int64_t Bit64s; + +typedef int32_t Bits; +typedef uint32_t Bitu; + +typedef double Real64; + + +#include "device.h" + +// Sorry, needs C++11 or later. 20190521 K.Ohta +namespace I386_DOSBOX { +class MinimumSkelton { +protected: + DEVICE* d_device; + boot verbose_log; +public: + void MinimumSkelton(DEVICE* parent) + { + d_device = parent; + verbose_log = false; // OK? + } + virtual void ~MinimumSkelton() { } + void set_logging(bool onoff) + { + verbose_log = onoff; + } + template + void E_Exit(Args... args) { + if((verbose_log) && (d_device != NULL)) { + d_device->out_debug_log(args...); + } + } +}; +}; + +#include "./include/paging.h" +#include "./include/regs.h" +#include "./lazyflags.h" + +class TaskStateSegment { + I386_DOSBOX *d_cpu; +public: + TaskStateSegment(I386_DOSBOX *parent = NULL) { + d_cpu = parent; + valid=false; + } + void SetCpuDomain(I386_DOSBOX *p) { + d_cpu = p; + } + bool IsValid(void) { + return valid; + } + Bitu Get_back(void); + void SaveSelector(void); + void Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp); + bool SetSelector(Bitu new_sel); + TSS_Descriptor desc; + Bitu selector; + PhysPt base; + Bitu limit; + Bitu is386; + bool valid; +}; + +class I386_DOSBOX : public DEVICE +{ +protected: + struct LazyFlags { + GenReg32 var1,var2,res; + Bitu type; + Bitu prev_type; + Bitu oldcf; + } lflags; + + const Bit8u * lookupRMregb[]; + const Bit16u * lookupRMregw[]; + const Bit32u * lookupRMregd[256]; + + const Bit8u * lookupRMEAregb[256]; + const Bit16u * lookupRMEAregw[256]; + const Bit16u * lookupRMEAregd[256]; + + CPU_Regs cpu_regs; + CPUBlock cpu; + Segments Segs; + + Bit32s CPU_Cycles; + Bit32s CPU_CycleLeft; + Bit32s CPU_CycleMax; + Bit32s CPU_OldCycleMax; + Bit32s CPU_CyclePercUsed; + Bit32s CPU_CycleLimit; + Bit32s CPU_CycleUp; + Bit32s CPU_CycleDown; + Bit64s CPU_IODelayRemoved; + CPU_Decoder * cpudecoder; + bool CPU_CycleAutoAdjust; + bool CPU_SkipCycleAutoAdjust; + Bitu CPU_AutoDetermineMode; + Bitu CPU_ArchitectureType; + Bitu CPU_extflags_toggle; // ID and AC flags may be toggled depending on emulated CPU architecture + Bitu CPU_PrefetchQueueSize; + Bit32s ticksDone; + Bit32u ticksScheduled; + + bool verbose_log; + struct MemoryBlock { + Bitu pages; + PageHandler * * phandlers; + MemHandle * mhandles; + LinkBlock links; + struct { + Bitu start_page; + Bitu end_page; + Bitu pages; + PageHandler *handler; + PageHandler *mmiohandler; + } lfb; + struct { + bool enabled; + Bit8u controlport; + } a20; + } memory; + PagingBlock paging; + + TaskStateSegment cpu_tss; + + virtual void PAGING_Enable(bool enabled); + virtual bool PAGING_Enabled(void); + virtual Bitu PAGING_GetDirBase(void); + virtual void PAGING_SetDirBase(Bitu cr3); + virtual void PAGING_InitTLB(void); + virtual void PAGING_ClearTLB(void); + virtual void PAGING_InitTLBBank(tlb_entry **bank); + + virtual void PAGING_LinkPage(Bitu lin_page,Bitu phys_page); + virtual void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page); + virtual void PAGING_UnlinkPages(Bitu lin_page,Bitu pages); +/* This maps the page directly, only use when paging is disabled */ + virtual void PAGING_MapPage(Bitu lin_page,Bitu phys_page); + virtual bool PAGING_MakePhysPage(Bitu & page); + virtual bool PAGING_ForcePageInit(Bitu lin_addr); + + INLINE void InitTLBInt(tlb_entry *bank); + + virtual void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler); + virtual void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler); + virtual void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); + virtual PageHandler * MEM_GetPageHandler(Bitu phys_page); + + virtual INLINE HostPt get_tlb_read(PhysPt address); + virtual INLINE HostPt get_tlb_write(PhysPt address); + virtual INLINE PageHandler* get_tlb_readhandler(PhysPt address); + virtual INLINE PageHandler* get_tlb_writehandler(PhysPt address); + virtual INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage); + virtual INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr); + virtual INLINE tlb_entry *get_tlb_entry(PhysPt address); + virtual INLINE Bit8u mem_readb_inline(PhysPt address); + + + virtual void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler); + virtual void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler); + virtual void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); + + virtual Bit16u mem_unalignedreadw(PhysPt address); + virtual Bit32u mem_unalignedreadd(PhysPt address); + virtual void mem_unalignedwritew(PhysPt address,Bit16u val); + virtual void mem_unalignedwrited(PhysPt address,Bit32u val); + + virtual bool mem_unalignedreadw_checked(PhysPt address,Bit16u * val); + virtual bool mem_unalignedreadd_checked(PhysPt address,Bit32u * val); + virtual bool mem_unalignedwritew_checked(PhysPt address,Bit16u val); + virtual bool mem_unalignedwrited_checked(PhysPt address,Bit32u val); + + INLINE Bit8u mem_readb_inline(PhysPt address); + INLINE Bit16u mem_readw_inline(PhysPt address); + INLINE Bit32u mem_readd_inline(PhysPt address); + + INLINE void mem_writeb_inline(PhysPt address,Bit8u val); + INLINE void mem_writew_inline(PhysPt address,Bit16u val); + INLINE void mem_writed_inline(PhysPt address,Bit32u val); + + INLINE bool mem_readb_checked(PhysPt address, Bit8u * val); + INLINE bool mem_readw_checked(PhysPt address, Bit16u * val); + INLINE bool mem_readd_checked(PhysPt address, Bit32u * val); + + INLINE bool mem_writeb_checked(PhysPt address, Bit8u val); + INLINE bool mem_writew_checked(PhysPt address, Bit16u val); + INLINE bool mem_writed_checked(PhysPt address, Bit32u val); + void PAGING_Init(Section * sec); + + //Flag Handling + Bit32u get_CF(void); + Bit32u get_AF(void); + Bit32u get_ZF(void); + Bit32u get_SF(void); + Bit32u get_OF(void); + Bit32u get_PF(void); + + INLINE void CPU_SetFlagsd(Bitu word); + INLINE void CPU_SetFlagsw(Bitu word); + + Bitu FillFlags(void); + void FillFlagsNoCFOF(void); + void DestroyConditionFlags(void); + + void CPU_Core_Full_Init(void); + void CPU_Core_Normal_Init(void); + void CPU_Core_Simple_Init(void); +#if (C_DYNAMIC_X86) + void CPU_Core_Dyn_X86_Init(void); + void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); + void CPU_Core_Dyn_X86_Cache_Close(void); + void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu); +#elif (C_DYNREC) + void CPU_Core_Dynrec_Init(void); + void CPU_Core_Dynrec_Cache_Init(bool enable_cache); + void CPU_Core_Dynrec_Cache_Close(void); +#endif + + // Within CPU + bool inited; + void CPU_Push16(Bitu value); + void CPU_Push32(Bitu value); + Bitu CPU_Pop16(); + Bitu CPU_Pop32(); + PhysPt SelBase(Bitu sel); + void CPU_SetFlags(Bitu word,Bitu mask); + bool CPU_PrepareException(Bitu which,Bitu error); + bool CPU_CLI(void); + bool CPU_STI(void); + bool CPU_POPF(Bitu use32); + bool CPU_PUSHF(Bitu use32); + void CPU_CheckSegments(void); + + void CPU_Reset_AutoAdjust(void); + void CPU_Disable_SkipAutoAdjust(void); + +public: + I386_DOSBOX(VM_TEMPLATE *parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + { + CPU_Cycles = 0; + CPU_CycleLeft = 3000; + CPU_CycleMax = 3000; + CPU_OldCycleMax = 3000; + CPU_CyclePercUsed = 100; + CPU_CycleLimit = -1; + CPU_CycleUp = 0; + CPU_CycleDown = 0; + CPU_IODelayRemoved = 0; + CPU_CycleAutoAdjust = false; + CPU_SkipCycleAutoAdjust = false; + CPU_AutoDetermineMode = 0; + + CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; + CPU_extflags_toggle=0; // ID and AC flags may be toggled depending on emulated CPU architecture + + CPU_PrefetchQueueSize=0; + + //initialize static members + inited=false; + verbose_log = false; + + cpu_tss.SetCpuDomain(this); + set_device_name(_T("I386(DOSBOX Variant)")); + } + ~I386_DOSBOX() { } + void set_logging(bool onoff) + { + verbose_log = onoff; + } + template + void E_Exit(Args... args) { + if((verbose_log) && (d_device != NULL)) { + d_device->out_debug_log(args...); + } + } + +}; + +void I386_DOSBOX::initialize() +{ +// if(inited) { +// Change_Config(); +// return; // OK? +// } + inited = true; + reg_eax=0; + reg_ebx=0; + reg_ecx=0; + reg_edx=0; + reg_edi=0; + reg_esi=0; + reg_ebp=0; + reg_esp=0; + + SegSet16(cs,0); + SegSet16(ds,0); + SegSet16(es,0); + SegSet16(fs,0); + SegSet16(gs,0); + SegSet16(ss,0); + + CPU_SetFlags(FLAG_IF,FMASK_ALL); //Enable interrupts + cpu.cr0=0xffffffff; + CPU_SET_CRX(0,0); //Initialize + cpu.code.big=false; + cpu.stack.mask=0xffff; + cpu.stack.notmask=0xffff0000; + cpu.stack.big=false; + cpu.trap_skip=false; + cpu.idt.SetBase(0); + cpu.idt.SetLimit(1023); + + for (Bitu i=0; i<7; i++) { + cpu.drx[i]=0; + cpu.trx[i]=0; + } + if (CPU_ArchitectureType==CPU_ARCHTYPE_PENTIUMSLOW) { + cpu.drx[6]=0xffff0ff0; + } else { + cpu.drx[6]=0xffff1ff0; + } + cpu.drx[7]=0x00000400; + + /* Init the cpu cores */ + CPU_Core_Normal_Init(); + CPU_Core_Simple_Init(); + CPU_Core_Full_Init(); +#if (C_DYNAMIC_X86) + CPU_Core_Dyn_X86_Init(); +#elif (C_DYNREC) + CPU_Core_Dynrec_Init(); +#endif + //MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles"); + //MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles"); + //Change_Config(configuration); + CPU_JMP(false,0,0,0); //Setup the first cpu core +} + + +namespace I386_DOSBOX { + +#if defined(USE_FULL_TLB) + +INLINE HostPt get_tlb_read(PhysPt address) { + return paging.tlb.read[address>>12]; +} +INLINE HostPt get_tlb_write(PhysPt address) { + return paging.tlb.write[address>>12]; +} +INLINE PageHandler* get_tlb_readhandler(PhysPt address) { + return paging.tlb.readhandler[address>>12]; +} +INLINE PageHandler* get_tlb_writehandler(PhysPt address) { + return paging.tlb.writehandler[address>>12]; +} + +/* Use these helper functions to access linear addresses in readX/writeX functions */ +INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { + return (paging.tlb.phys_page[linePage>>12]<<12); +} + +INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { + return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); +} + +#else + + +INLINE tlb_entry *get_tlb_entry(PhysPt address) { + Bitu index=(address>>12); + if (TLB_BANKS && (index > TLB_SIZE)) { + Bitu bank=(address>>BANK_SHIFT) - 1; + if (!paging.tlbh_banks[bank]) + PAGING_InitTLBBank(&paging.tlbh_banks[bank]); + return &paging.tlbh_banks[bank][index & BANK_MASK]; + } + return &paging.tlbh[index]; +} + +INLINE HostPt get_tlb_read(PhysPt address) { + return get_tlb_entry(address)->read; +} +INLINE HostPt get_tlb_write(PhysPt address) { + return get_tlb_entry(address)->write; +} +INLINE PageHandler* get_tlb_readhandler(PhysPt address) { + return get_tlb_entry(address)->readhandler; +} +INLINE PageHandler* get_tlb_writehandler(PhysPt address) { + return get_tlb_entry(address)->writehandler; +} + +/* Use these helper functions to access linear addresses in readX/writeX functions */ +INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { + tlb_entry *entry = get_tlb_entry(linePage); + return (entry->phys_page<<12); +} + +INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { + tlb_entry *entry = get_tlb_entry(linAddr); + return (entry->phys_page<<12)|(linAddr&0xfff); +} +#endif + +/* Special inlined memory reading/writing */ +INLINE Bit8u mem_readb_inline(PhysPt address) { + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) return read_data8(tlb_addr+address); + else return (Bit8u)(get_tlb_readhandler(address))->readb(address); +} + +INLINE Bit16u mem_readw_inline(PhysPt address) { + if ((address & 0xfff)<0xfff) { + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) return read_data16(tlb_addr+address); + else return (Bit16u)(get_tlb_readhandler(address))->readw(address); + } else return mem_unalignedreadw(address); +} + +INLINE Bit32u mem_readd_inline(PhysPt address) { + if ((address & 0xfff)<0xffd) { + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) return read_data32(tlb_addr+address); + else return (get_tlb_readhandler(address))->readd(address); + } else return mem_unalignedreadd(address); +} + +INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) write_data8(tlb_addr + address, val); + else (get_tlb_writehandler(address))->writeb(address,val); +} + +INLINE void mem_writew_inline(PhysPt address,Bit16u val) { + if ((address & 0xfff)<0xfff) { + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) write_data16(tlb_addr+address,val); + else (get_tlb_writehandler(address))->writew(address,val); + } else mem_unalignedwritew(address,val); +} + +INLINE void mem_writed_inline(PhysPt address,Bit32u val) { + if ((address & 0xfff)<0xffd) { + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) write_data32(tlb_addr+address,val); + else (get_tlb_writehandler(address))->writed(address,val); + } else mem_unalignedwrited(address,val); +} + + +INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *val=read_data8(tlb_addr+address); + return false; + } else return (get_tlb_readhandler(address))->readb_checked(address, val); +} + +INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { + if ((address & 0xfff)<0xfff) { + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *val = read_data16(tlb_addr+address); + return false; + } else return (get_tlb_readhandler(address))->readw_checked(address, val); + } else return mem_unalignedreadw_checked(address, val); +} + +INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { + if ((address & 0xfff)<0xffd) { + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *val= read_data32(tlb_addr+address); + return false; + } else return (get_tlb_readhandler(address))->readd_checked(address, val); + } else return mem_unalignedreadd_checked(address, val); +} + +INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) { + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + write_data8(tlb_addr+address,val); + return false; + } else return (get_tlb_writehandler(address))->writeb_checked(address,val); +} + +INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { + if ((address & 0xfff)<0xfff) { + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + write_data16(tlb_addr+address,val); + return false; + } else return (get_tlb_writehandler(address))->writew_checked(address,val); + } else return mem_unalignedwritew_checked(address,val); +} + +INLINE bool mem_writed_checked(PhysPt address,Bit32u val) { + if ((address & 0xfff)<0xffd) { + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + write_data32(tlb_addr+address,val); + return false; + } else return (get_tlb_writehandler(address))->writed_checked(address,val); + } else return mem_unalignedwrited_checked(address,val); +} + +}; +#endif // __CSP_I386_DOSBOX_TYPES_COMPAT_H__ -- 2.11.0