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;
|
||
}
|