Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

288 lines
4.5 KiB

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
asciiops.c
Abstract:
This module implements the code to emulate the ASCII opcodes.
Author:
David N. Cutler (davec) 12-Nov-1994
Environment:
Kernel mode only.
Revision History:
--*/
#include "nthal.h"
#include "emulate.h"
VOID
XmAaaOp (
IN PRXM_CONTEXT P
)
/*++
Routine Description:
This function emulates an aaa opcode.
Arguments:
P - Supplies a pointer to the emulation context structure.
Return Value:
None.
--*/
{
ULONG Carry;
//
// If AL if greater than 9 or AF is set, then adjust ASCII result.
//
if (((P->Gpr[AX].Xl & 0xf) > 9) || (P->Eflags.EFLAG_AF != 0)) {
Carry = (P->Gpr[AX].Xl > 0xf9);
P->Gpr[AX].Xl = (P->Gpr[AX].Xl + 6) & 0xf;
P->Gpr[AX].Xh += (UCHAR)(1 + Carry);
P->Eflags.EFLAG_CF = 1;
P->Eflags.EFLAG_AF = 1;
} else {
P->Gpr[AX].Xl &= 0xf;
P->Eflags.EFLAG_CF = 0;
P->Eflags.EFLAG_AF = 0;
}
return;
}
VOID
XmAadOp (
IN PRXM_CONTEXT P
)
/*++
Routine Description:
This function emulates an aad opcode.
Arguments:
P - Supplies a pointer to the emulation context structure.
Return Value:
None.
--*/
{
//
// Pack AH and AL into AX before division by scaling AH by 10 and
// adding AL.
//
P->Gpr[AX].Xl = (P->Gpr[AX].Xh * P->SrcValue.Byte) + P->Gpr[AX].Xl;
P->Gpr[AX].Xh = 0;
P->Eflags.EFLAG_SF = (P->Gpr[AX].Xx >> 15) & 0x1;
P->Eflags.EFLAG_ZF = (P->Gpr[AX].Xx == 0);
P->Eflags.EFLAG_PF = XmComputeParity(P->Gpr[AX].Xx);
return;
}
VOID
XmAamOp (
IN PRXM_CONTEXT P
)
/*++
Routine Description:
This function emulates an aam opcode.
Arguments:
P - Supplies a pointer to the emulation context structure.
Return Value:
None.
--*/
{
//
// Unpack AL into AL and AH after multiplication by dividing by 10
// and storing the quotient in AH and the remainder in AL.
//
P->Gpr[AX].Xh = P->Gpr[AX].Xl / P->SrcValue.Byte;
P->Gpr[AX].Xl = P->Gpr[AX].Xl % P->SrcValue.Byte;
P->Eflags.EFLAG_SF = (P->Gpr[AX].Xx >> 15) & 0x1;
P->Eflags.EFLAG_ZF = (P->Gpr[AX].Xx == 0);
P->Eflags.EFLAG_PF = XmComputeParity(P->Gpr[AX].Xx);
return;
}
VOID
XmAasOp (
IN PRXM_CONTEXT P
)
/*++
Routine Description:
This function emulates an aaa opcode.
Arguments:
P - Supplies a pointer to the emulation context structure.
Return Value:
None.
--*/
{
ULONG Borrow;
//
// If AL if greater than 9 or AF is set, then adjust ASCII result.
//
if (((P->Gpr[AX].Xl & 0xf) > 9) || (P->Eflags.EFLAG_AF != 0)) {
Borrow = (P->Gpr[AX].Xl < 0x6);
P->Gpr[AX].Xl = (P->Gpr[AX].Xl - 6) & 0xf;
P->Gpr[AX].Xh -= (UCHAR)(1 + Borrow);
P->Eflags.EFLAG_CF = 1;
P->Eflags.EFLAG_AF = 1;
} else {
P->Gpr[AX].Xl &= 0xf;
P->Eflags.EFLAG_CF = 0;
P->Eflags.EFLAG_AF = 0;
}
return;
}
VOID
XmDaaOp (
IN PRXM_CONTEXT P
)
/*++
Routine Description:
This function emulates a daa opcode.
Arguments:
P - Supplies a pointer to the emulation context structure.
Return Value:
None.
--*/
{
//
// If AL if greater than 9 or AF is set, then adjust ASCII result.
//
if (((P->Gpr[AX].Xl & 0xf) > 0x9) || (P->Eflags.EFLAG_AF != 0)) {
P->Gpr[AX].Xl = P->Gpr[AX].Xl + 6;
P->Eflags.EFLAG_AF = 1;
} else {
P->Eflags.EFLAG_AF = 0;
}
//
// If AL is greater than 9 or CF is set, then adjust ASCII result.
//
if ((P->Gpr[AX].Xl > 9) || (P->Eflags.EFLAG_CF != 0)) {
P->Gpr[AX].Xl = P->Gpr[AX].Xl + 0x60;
P->Eflags.EFLAG_CF = 1;
} else {
P->Eflags.EFLAG_CF = 0;
}
return;
}
VOID
XmDasOp (
IN PRXM_CONTEXT P
)
/*++
Routine Description:
This function emulates a daa opcode.
Arguments:
P - Supplies a pointer to the emulation context structure.
Return Value:
None.
--*/
{
//
// If AL if greater than 9 or AF is set, then adjust ASCII result.
//
if (((P->Gpr[AX].Xl & 0xf) > 0x9) || (P->Eflags.EFLAG_AF != 0)) {
P->Gpr[AX].Xl = P->Gpr[AX].Xl - 6;
P->Eflags.EFLAG_AF = 1;
} else {
P->Eflags.EFLAG_AF = 0;
}
//
// If AL is greater than 9 or CF is set, then adjust ASCII result.
//
if ((P->Gpr[AX].Xl > 9) || (P->Eflags.EFLAG_CF != 0)) {
P->Gpr[AX].Xl = P->Gpr[AX].Xl - 0x60;
P->Eflags.EFLAG_CF = 1;
} else {
P->Eflags.EFLAG_CF = 0;
}
return;
}