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.8 KiB
288 lines
4.8 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;
|
|
}
|