v86m.c
来自「一个类似windows」· C语言 代码 · 共 812 行 · 第 1/2 页
C
812 行
}
Exit = TRUE;
break;
/* outsb */
case 0x6E:
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
ULONG Count;
PUCHAR Port;
PUCHAR Buffer;
ULONG Offset;
Count = 1;
if (RepPrefix)
{
Count = Tf->Ecx;
if (!BigAddressPrefix)
{
Count = Count & 0xFFFF;
}
}
Port = (PUCHAR)(Tf->Edx & 0xFFFF);
Offset = Tf->Edi;
if (!BigAddressPrefix)
{
Offset = Offset & 0xFFFF;
}
Buffer = (PUCHAR)((Tf->SegEs * 16) + Offset);
for (; Count > 0; Count--)
{
WRITE_PORT_UCHAR(Port, *Buffer);
if (Tf->EFlags & DIRECTION_FLAG)
{
Buffer++;
}
else
{
Buffer--;
}
}
Tf->Eip++;
return(0);
}
Exit = TRUE;
break;
/* insw/insd */
case 0x6F:
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
ULONG Count;
PUCHAR Port;
PUSHORT BufferS = NULL;
PULONG BufferL = NULL;
ULONG Offset;
Count = 1;
if (RepPrefix)
{
Count = Tf->Ecx;
if (!BigAddressPrefix)
{
Count = Count & 0xFFFF;
}
}
Port = (PUCHAR)(Tf->Edx & 0xFFFF);
Offset = Tf->Edi;
if (!BigAddressPrefix)
{
Offset = Offset & 0xFFFF;
}
if (BigDataPrefix)
{
BufferL = (PULONG)((Tf->SegEs * 16) + Offset);
}
else
{
BufferS = (PUSHORT)((Tf->SegEs * 16) + Offset);
}
for (; Count > 0; Count--)
{
if (BigDataPrefix)
{
WRITE_PORT_ULONG((PULONG)Port, *BufferL);
}
else
{
WRITE_PORT_USHORT((PUSHORT)Port, *BufferS);
}
if (Tf->EFlags & DIRECTION_FLAG)
{
if (BigDataPrefix)
{
BufferL++;
}
else
{
BufferS++;
}
}
else
{
if (BigDataPrefix)
{
BufferL--;
}
else
{
BufferS--;
}
}
}
Tf->Eip++;
return(0);
}
Exit = TRUE;
break;
/* insb */
case 0x6C:
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
ULONG Count;
PUCHAR Port;
PUCHAR Buffer;
ULONG Offset;
Count = 1;
if (RepPrefix)
{
Count = Tf->Ecx;
if (!BigAddressPrefix)
{
Count = Count & 0xFFFF;
}
}
Port = (PUCHAR)(Tf->Edx & 0xFFFF);
Offset = Tf->Edi;
if (!BigAddressPrefix)
{
Offset = Offset & 0xFFFF;
}
Buffer = (PUCHAR)((Tf->SegEs * 16) + Offset);
for (; Count > 0; Count--)
{
*Buffer = READ_PORT_UCHAR(Port);
if (Tf->EFlags & DIRECTION_FLAG)
{
Buffer++;
}
else
{
Buffer--;
}
}
Tf->Eip++;
return(0);
}
Exit = TRUE;
break;
/* insw/insd */
case 0x6D:
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
ULONG Count;
PUCHAR Port;
PUSHORT BufferS = NULL;
PULONG BufferL = NULL;
ULONG Offset;
Count = 1;
if (RepPrefix)
{
Count = Tf->Ecx;
if (!BigAddressPrefix)
{
Count = Count & 0xFFFF;
}
}
Port = (PUCHAR)(Tf->Edx & 0xFFFF);
Offset = Tf->Edi;
if (!BigAddressPrefix)
{
Offset = Offset & 0xFFFF;
}
if (BigDataPrefix)
{
BufferL = (PULONG)((Tf->SegEs * 16) + Offset);
}
else
{
BufferS = (PUSHORT)((Tf->SegEs * 16) + Offset);
}
for (; Count > 0; Count--)
{
if (BigDataPrefix)
{
*BufferL = READ_PORT_ULONG((PULONG)Port);
}
else
{
*BufferS = READ_PORT_USHORT((PUSHORT)Port);
}
if (Tf->EFlags & DIRECTION_FLAG)
{
if (BigDataPrefix)
{
BufferL++;
}
else
{
BufferS++;
}
}
else
{
if (BigDataPrefix)
{
BufferL--;
}
else
{
BufferS--;
}
}
}
Tf->Eip++;
return(0);
}
Exit = TRUE;
break;
/* Int nn */
case 0xCD:
{
unsigned int inum;
unsigned int entry;
inum = ip[1];
entry = ((unsigned int *)0)[inum];
Tf->HardwareEsp = Tf->HardwareEsp - 6;
sp = sp - 3;
sp[0] = (USHORT)((Tf->Eip & 0xFFFF) + 2);
sp[1] = (USHORT)(Tf->SegCs & 0xFFFF);
sp[2] = (USHORT)(Tf->EFlags & 0xFFFF);
if (VTf->regs->Vif == 1)
{
sp[2] = (USHORT)(sp[2] | INTERRUPT_FLAG);
}
DPRINT("sp[0] %x sp[1] %x sp[2] %x\n", sp[0], sp[1], sp[2]);
Tf->Eip = entry & 0xFFFF;
Tf->SegCs = entry >> 16;
Tf->EFlags = Tf->EFlags & (~TRAP_FLAG);
return(0);
}
}
/* FIXME: Also emulate ins and outs */
/* FIXME: Handle opcode prefixes */
/* FIXME: Don't allow the BIOS to write to sensitive I/O ports */
}
DPRINT1("V86GPF unhandled (was %x)\n", ip[i]);
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
ULONG
NTAPI
KeV86Exception(ULONG ExceptionNr, PKTRAP_FRAME Tf, ULONG address)
{
PUCHAR Ip;
PKV86M_TRAP_FRAME VTf;
ASSERT (ExceptionNr != 14);
VTf = (PKV86M_TRAP_FRAME)Tf;
/* FIXME: This should use ->VdmObjects */
if(KeGetCurrentProcess()->Unused)
{
VTf->regs->PStatus = (PNTSTATUS) ExceptionNr;
return 1;
}
/*
* Check if we have reached the recovery instruction
*/
Ip = (PUCHAR)((Tf->SegCs & 0xFFFF) * 16 + (Tf->Eip & 0xFFFF));
DPRINT("ExceptionNr %d Ip[0] %x Ip[1] %x Ip[2] %x Ip[3] %x Tf->SegCs %x "
"Tf->Eip %x\n", ExceptionNr, Ip[0], Ip[1], Ip[2], Ip[3], Tf->SegCs,
Tf->Eip);
DPRINT("VTf %x VTf->regs %x\n", VTf, VTf->regs);
if (ExceptionNr == 6 &&
memcmp(Ip, VTf->regs->RecoveryInstruction, 4) == 0 &&
(Tf->SegCs * 16 + Tf->Eip) == VTf->regs->RecoveryAddress)
{
*VTf->regs->PStatus = STATUS_SUCCESS;
return(1);
}
/*
* Handle the exceptions
*/
switch (ExceptionNr)
{
/* Divide error */
case 0:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Single step */
case 1:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* NMI */
case 2:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Breakpoint */
case 3:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Overflow */
case 4:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Array bounds check */
case 5:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Invalid opcode */
case 6:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Device not available */
case 7:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Double fault */
case 8:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Intel reserved */
case 9:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Invalid TSS */
case 10:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Segment not present */
case 11:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Stack fault */
case 12:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* General protection fault */
case 13:
return(KeV86GPF(VTf, Tf));
/* Intel reserved */
case 15:
case 16:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Alignment check */
case 17:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
default:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?