1
0
Fork 0

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
This commit is contained in:
Sjoerd van der Berg 2003-11-18 22:15:51 +00:00
parent ab8c335230
commit 69374f45bc

View file

@ -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