289 lines
4.5 KiB
C
289 lines
4.5 KiB
C
|
/*++
|
|||
|
|
|||
|
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;
|
|||
|
}
|