* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <stdio.h>
+#include "device.h"
+#include "./types_compat.h"
+//#include <stdio.h>
-#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)
* 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,
reg_ecx|=(count & add_mask);
}
}
+
+};
* 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))
if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \
else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \
}
+};
#include "helpers.h"
#include "table_ea.h"
* 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) {
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,
eaa=BaseDS+Fetchw(); \
} \
-
+};
#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);
#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.
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
};
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) {
}
-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;
}
~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;
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.
}
#endif
+};
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);
}
#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;
#define MEM_PAGESIZE 4096
+namespace DOSBOX_I386 {
+
extern HostPt MemBase;
HostPt GetMemBase(void);
#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) {
static INLINE RealPt RealGetVec(Bit8u vec) {
return mem_readd(vec<<2);
}
+};
#endif
#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)
//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<I386_DOSBOX *>(parent);
+ }
+ virtual ~PageHandler() { }
virtual Bitu readb(PhysPt addr);
virtual Bitu readw(PhysPt addr);
virtual Bitu readd(PhysPt addr);
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
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
* 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; \
#define BSWAPD(op1) \
op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000);
+
+};
#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]
#define lf_resd lflags.res.dword[DW_INDEX]
-extern LazyFlags lflags;
-
#define SETFLAGSb(FLAGB) \
{ \
SETFLAGBIT(OF,get_OF()); \
t_LASTFLAG
};
+};
#endif
#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,
®_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,
®_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,
};
-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,
®_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,
®_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,
#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;
}
-
-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;
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));
// 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)) {
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;
}
}
-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;
}
// 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:
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;
}
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));
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;
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;
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;
}
#if defined(USE_FULL_TLB)
+INLINE void InitTLBInt(tlb_entry *bank) {
+}
+
void PAGING_InitTLB(void) {
for (Bitu i=0;i<TLB_SIZE;i++) {
paging.tlb.read[i]=0;
#else
-static INLINE void InitTLBInt(tlb_entry *bank) {
+INLINE void InitTLBInt(tlb_entry *bank) {
for (Bitu i=0;i<TLB_SIZE;i++) {
bank[i].read=0;
bank[i].write=0;
return paging.enabled;
}
-class PAGING:public Module_base{
+class PAGING:public MinimumSkelton{
+ I386_DOSBOX *d_parent;
public:
- PAGING(Section* configuration):Module_base(configuration){
+ PAGING(DEVICE* parent): MinimumSkelton(parent){
/* Setup default Page Directory, force it to update */
- paging.enabled=false;
- PAGING_InitTLB();
+ d_parent = static_cast<I386_DOSBOX *>(parent);
+
+ d_parent->paging.enabled=false;
+ d_parent->PAGING_InitTLB();
Bitu i;
for (i=0;i<LINK_START;i++) {
- paging.firstmb[i]=i;
+ d_parent->paging.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);
}
+};
--- /dev/null
+/*
+ Skelton for retropc emulator
+
+ Origin : MAME i386 core
+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
+ 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 <class... Args>
+ 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 <class... Args>
+ 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__