/*++ Copyright (c) 1995-1998 Microsoft Corporation Module Name: fraginit.c Abstract: Initialization, termination, and CPU interface functions Author: 25-Aug-1995 BarryBo Revision History: --*/ #include #include #include #include #include #define _WX86CPUAPI_ #include "wx86.h" #include "wx86nt.h" #include "wx86cpu.h" #include "cpuassrt.h" #ifdef MSCCPU #include "ccpu.h" #include "msccpup.h" #undef GET_BYTE #undef GET_SHORT #undef GET_LONG #else #include "threadst.h" #include "instr.h" #include "frag.h" ASSERTNAME; #endif #include "fragp.h" // // Table mapping a byte to a 0 or 1, corresponding to the parity bit for // that byte. // const BYTE ParityBit[] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 }; #if _ALPHA_ // // TRUE if the CPU should generate the new LDB/STB instructions for accessing // data less than one DWORD long or when accessing unaligned data. // DWORD fByteInstructionsOK; #endif int * _errno( ) /*++ Routine Description: Stub function so the CPU can pull in floating-point CRT support without the C startup code. Arguments: None. Return Value: Pointer to per-thread [actually per-fiber] errno value. --*/ { DECLARE_CPU; return &cpu->ErrnoVal; } BOOL FragLibInit( PCPUCONTEXT cpu, DWORD StackBase ) /*++ Routine Description: This routine initializes the fragment library. Arguments: cpu - per-thread CPU data StackBase - initial ESP value Return Value: True if successful. --*/ { // // Initialize the 487 emulator // FpuInit(cpu); // // Initialize all non-zero fields in the cpu // cpu->flag_df = 1; // direction flag is initially UP cpu->flag_if = 1; // enable interrupts ES = SS = DS = KGDT_R3_DATA+3; CS = KGDT_R3_CODE+3; FS = KGDT_R3_TEB+3; esp = StackBase; // set up the initial ESP value #if _ALPHA_ // // See if LDB/STB instructions are implemented. // fByteInstructionsOK = (DWORD)ProxyIsProcessorFeaturePresent( PF_ALPHA_BYTE_INSTRUCTIONS); #endif return TRUE; } DWORD GetEax(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return eax; } DWORD GetEbx(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return ebx; } DWORD GetEcx(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return ecx; } DWORD GetEdx(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return edx; } DWORD GetEsp(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return esp; } DWORD GetEbp(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return ebp; } DWORD GetEsi(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return esi; } DWORD GetEdi(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return edi; } DWORD GetEip(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return eip; } void SetEax(PVOID CpuContext, DWORD dw) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; eax = dw; } void SetEbx(PVOID CpuContext, DWORD dw) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; ebx = dw; } void SetEcx(PVOID CpuContext, DWORD dw) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; ecx = dw; } void SetEdx(PVOID CpuContext, DWORD dw) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; edx = dw; } void SetEsp(PVOID CpuContext, DWORD dw) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; esp = dw; } void SetEbp(PVOID CpuContext, DWORD dw) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; ebp = dw; } void SetEsi(PVOID CpuContext, DWORD dw) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; esi = dw; } void SetEdi(PVOID CpuContext, DWORD dw) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; edi = dw; } void SetEip(PVOID CpuContext, DWORD dw) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; eip = dw; } VOID SetCs(PVOID CpuContext, USHORT us) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; CS = us; } VOID SetSs(PVOID CpuContext, USHORT us) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; SS = us; } VOID SetDs(PVOID CpuContext, USHORT us) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; DS = us; } VOID SetEs(PVOID CpuContext, USHORT us) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; ES = us; } VOID SetFs(PVOID CpuContext, USHORT us) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; FS = us; } VOID SetGs(PVOID CpuContext, USHORT us) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; GS = us; } USHORT GetCs(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return CS; } USHORT GetSs(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return SS; } USHORT GetDs(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return DS; } USHORT GetEs(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return ES; } USHORT GetFs(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return FS; } USHORT GetGs(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; return GS; } ULONG GetEfl(PVOID CpuContext) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; DWORD dw; dw = ((GET_CFLAG) ? FLAG_CF : 0) | 2 | 3 << 12 // iopl | ((GET_AUXFLAG) ? FLAG_AUX : 0) | ((GET_PFLAG) ? FLAG_PF : 0) | ((cpu->flag_zf) ? 0 : FLAG_ZF) // zf has inverse logic | ((GET_SFLAG) ? FLAG_SF : 0) | ((cpu->flag_tf) ? FLAG_TF : 0) | ((cpu->flag_if) ? FLAG_IF : 0) | ((cpu->flag_df == -1) ? FLAG_DF : 0) | ((GET_OFLAG) ? FLAG_OF : 0) | cpu->flag_ac; return dw; } void SetEfl(PVOID CpuContext, ULONG RegValue) { PCPUCONTEXT cpu = (PCPUCONTEXT)CpuContext; // IOPL, IF, NT, RF, VM, AC ignored. SET_CFLAG_IND(RegValue & FLAG_CF); cpu->flag_pf = (RegValue & FLAG_PF) ? 0 : 1; // see ParityBit[] table cpu->flag_aux= (RegValue & FLAG_AUX) ? AUX_VAL : 0; cpu->flag_zf = (RegValue & FLAG_ZF) ? 0 : 1; // inverse logic SET_SFLAG_IND(RegValue & FLAG_SF); cpu->flag_tf = (RegValue & FLAG_TF) ? 1 : 0; cpu->flag_df = (RegValue & FLAG_DF) ? -1 : 1; SET_OFLAG_IND(RegValue & FLAG_OF); cpu->flag_ac = (RegValue & FLAG_AC); } #if DBG VOID DoAssert( PSZ exp, PSZ msg, PSZ mod, INT line ) { if (msg) { LOGPRINT((ERRORLOG, "CPU ASSERTION FAILED:\r\n %s\r\n%s\r\nFile: %s Line %d\r\n", msg, exp, mod, line)); } else { LOGPRINT((ERRORLOG, "CPU ASSERTION FAILED:\r\n %s\r\nFile: %s Line %d\r\n", exp, mod, line)); } DbgBreakPoint(); } #endif //DBG