359 lines
7.3 KiB
C
359 lines
7.3 KiB
C
|
/*++
|
||
|
|
||
|
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 <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
#include <windows.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#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
|