From 69374f45bcb8c0faf36374175aefc8fbe0b35f81 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 18 Nov 2003 22:15:51 +0000 Subject: [PATCH] changed some functions to allow exceptions. Changed the task segment stuff Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1444 --- include/cpu.h | 170 +++++++++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 93 deletions(-) diff --git a/include/cpu.h b/include/cpu.h index 90ae88ef..2de0a508 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -65,44 +65,30 @@ void CPU_JMP(bool use32,Bitu selector,Bitu offset); void CPU_CALL(bool use32,Bitu selector,Bitu offset); void CPU_RET(bool use32,Bitu bytes); -#define CPU_INT_HARDWARE 0x1 +#define CPU_INT_SOFTWARE 0x1 #define CPU_INT_HAS_ERROR 0x2 void CPU_Interrupt(Bitu num,Bitu error_code,Bitu type); INLINE void CPU_HW_Interrupt(Bitu num) { - CPU_Interrupt(num,0,CPU_INT_HARDWARE); -} -INLINE void CPU_SW_Interrupt(Bitu num) { CPU_Interrupt(num,0,0); } -void CPU_Exception(Bitu num,Bitu error_code=0); - -INLINE void Interrupt(Bitu num) { - CPU_SW_Interrupt(num); +INLINE void CPU_SW_Interrupt(Bitu num,Bitu oplen) { + CPU_Interrupt(num,oplen,CPU_INT_SOFTWARE); } +void CPU_Exception(Bitu num,Bitu error_code=0); void CPU_IRET(bool use32); void CPU_SetSegGeneral(SegNames seg,Bitu value); void CPU_CPUID(void); -void CPU_HLT(void); +void CPU_HLT(Bitu oplen); Bitu CPU_Pop16(void); Bitu CPU_Pop32(void); void CPU_Push16(Bitu value); void CPU_Push32(Bitu value); -void CPU_SetFlags(Bitu word); - -INLINE void CPU_SetFlagsd(Bit32u word) { - CPU_SetFlags(word); -}; - -INLINE void CPU_SetFlagsw(Bit16u word) { - CPU_SetFlags((cpu_regs.flags&0xffff0000)|word); -}; - - +void CPU_SetFlags(Bitu word,Bitu mask); // ********************************************************************* // Descriptor @@ -151,32 +137,6 @@ INLINE void CPU_SetFlagsw(Bit16u word) { #define DESC_CODE_R_C_A 0x1e #define DESC_CODE_R_C_NA 0x1f -#pragma pack(1) -/* TSS Struct from Bochs - http://bochs.sf.net */ -struct TSS_386 { - Bit16u back, RESERVED0; /* Backlink */ - Bit32u esp0; /* The CK stack pointer */ - Bit16u ss0, RESERVED1; /* The CK stack selector */ - Bit32u esp1; /* The parent KL stack pointer */ - Bit16u ss1, RESERVED2; /* The parent KL stack selector */ - Bit32u esp2; /* Unused */ - Bit16u ss2, RESERVED3; /* Unused */ - Bit32u cr3; /* The page directory pointer */ - Bit32u eip; /* The instruction pointer */ - Bit32u eflags; /* The flags */ - Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ - Bit32u esp, ebp, esi, edi; /* The special purpose registers */ - Bit16u es, RESERVED4; /* The extra selector */ - Bit16u cs, RESERVED5; /* The code selector */ - Bit16u ss, RESERVED6; /* The application stack selector */ - Bit16u ds, RESERVED7; /* The data selector */ - Bit16u fs, RESERVED8; /* And another extra selector */ - Bit16u gs, RESERVED9; /* ... and another one */ - Bit16u ldt, RESERVED10; /* The local descriptor table */ - Bit16u trap; /* The trap flag (for debugging) */ - Bit16u io; /* The I/O Map base address */ -} GCC_ATTRIBUTE(packed); - struct S_Descriptor { #ifdef WORDS_BIGENDIAN Bit32u base_0_15 :16; @@ -229,55 +189,49 @@ struct G_Descriptor { #endif } GCC_ATTRIBUTE(packed); -#pragma pack() - - -struct TaskSegment_32 { - Bit32u esp0; /* The CK stack pointer */ - Bit32u esp1; /* The parent KL stack pointer */ - Bit32u esp2; /* Unused */ - Bit32u cr3; /* The page directory pointer */ - Bit32u eip; /* The instruction pointer */ - Bit32u eflags; /* The flags */ - Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ - Bit32u esp, ebp, esi, edi; /* The special purpose registers */ - Bit16u back; /* Backlink */ +struct TSS_16 { + Bit16u back; /* Back link to other task */ + Bit16u sp0; /* The CK stack pointer */ Bit16u ss0; /* The CK stack selector */ + Bit16u sp1; /* The parent KL stack pointer */ Bit16u ss1; /* The parent KL stack selector */ + Bit16u sp2; /* Unused */ Bit16u ss2; /* Unused */ + Bit16u ip; /* The instruction pointer */ + Bit16u flags; /* The flags */ + Bit16u ax, cx, dx, bx; /* The general purpose registers */ + Bit16u sp, bp, si, di; /* The special purpose registers */ Bit16u es; /* The extra selector */ Bit16u cs; /* The code selector */ Bit16u ss; /* The application stack selector */ Bit16u ds; /* The data selector */ - Bit16u fs; /* And another extra selector */ - Bit16u gs; /* ... and another one */ Bit16u ldt; /* The local descriptor table */ - Bit16u trap; /* The trap flag (for debugging) */ - Bit16u io; /* The I/O Map base address */ -}; +} GCC_ATTRIBUTE(packed); -void CPU_ReadTaskSeg32(PhysPt base,TaskSegment_32 * seg); +struct TSS_32 { + Bit32u back; /* Back link to other task */ + Bit32u esp0; /* The CK stack pointer */ + Bit32u ss0; /* The CK stack selector */ + Bit32u esp1; /* The parent KL stack pointer */ + Bit32u ss1; /* The parent KL stack selector */ + Bit32u esp2; /* Unused */ + Bit32u ss2; /* Unused */ + Bit32u cr3; /* The page directory pointer */ + Bit32u eip; /* The instruction pointer */ + Bit32u eflags; /* The flags */ + Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ + Bit32u esp, ebp, esi, edi; /* The special purpose registers */ + Bit32u es; /* The extra selector */ + Bit32u cs; /* The code selector */ + Bit32u ss; /* The application stack selector */ + Bit32u ds; /* The data selector */ + Bit32u fs; /* And another extra selector */ + Bit32u gs; /* ... and another one */ + Bit32u ldt; /* The local descriptor table */ +} GCC_ATTRIBUTE(packed); + +#pragma pack() -class TaskStateSegment -{ -public: - bool Get_ss_esp(Bitu which,Bitu & _ss,Bitu & _esp) { - PhysPt reader=seg_base+offsetof(TSS_386,esp0)+which*8; - _esp=mem_readd(reader); - _ss=mem_readw(reader+4); - return true; - } - bool Get_cr3(Bitu which,Bitu & _cr3) { - _cr3=mem_readd(seg_base+offsetof(TSS_386,cr3));; - return true; - } - -private: - PhysPt seg_base; - Bitu seg_limit; - Bitu seg_value; -}; - class Descriptor { public: @@ -347,7 +301,7 @@ protected: class GDTDescriptorTable : public DescriptorTable { public: - bool GetDescriptor (Bitu selector, Descriptor& desc) { + bool GetDescriptor(Bitu selector, Descriptor& desc) { Bitu address=selector & ~7; if (selector & 4) { if (address>=ldt_limit) return false; @@ -359,7 +313,18 @@ public: return true; } } - + bool SetDescriptor(Bitu selector, Descriptor& desc) { + Bitu address=selector & ~7; + if (selector & 4) { + if (address>=ldt_limit) return false; + desc.Save(ldt_base+address); + return true; + } else { + if (address>=table_limit) return false; + desc.Save(table_base+address); + return true; + } + } Bitu SLDT(void) { return ldt_value; } @@ -378,18 +343,27 @@ private: Bitu ldt_value; }; +class TSS_Descriptor : public Descriptor { +public: + Bitu IsBusy(void) { + return saved.seg.type & 2; + } + Bitu Is386(void) { + return saved.seg.type & 8; + } + void SetBusy(bool busy) { + if (busy) saved.seg.type|=2; + else saved.seg.type&=~2; + } +}; + + struct CPUBlock { Bitu cpl; /* Current Privilege */ Bitu cr0; - bool v86; /* Are we in a v86 task */ bool pmode; /* Is Protected mode enabled */ GDTDescriptorTable gdt; DescriptorTable idt; - struct { - Bit16u val; - PhysPt base; - Bitu type; - } tr; struct { Bitu mask; bool big; @@ -405,5 +379,15 @@ struct CPUBlock { extern CPUBlock cpu; +INLINE void CPU_SetFlagsd(Bitu word) { + Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL; + CPU_SetFlags(word,mask); +}; + +INLINE void CPU_SetFlagsw(Bitu word) { + Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff; + CPU_SetFlags(word,mask); +}; + #endif