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

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. asciiops.c
  5. Abstract:
  6. This module implements the code to emulate the ASCII opcodes.
  7. Author:
  8. David N. Cutler (davec) 12-Nov-1994
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. --*/
  13. #include "nthal.h"
  14. #include "emulate.h"
  15. VOID
  16. XmAaaOp (
  17. IN PRXM_CONTEXT P
  18. )
  19. /*++
  20. Routine Description:
  21. This function emulates an aaa opcode.
  22. Arguments:
  23. P - Supplies a pointer to the emulation context structure.
  24. Return Value:
  25. None.
  26. --*/
  27. {
  28. ULONG Carry;
  29. //
  30. // If AL if greater than 9 or AF is set, then adjust ASCII result.
  31. //
  32. if (((P->Gpr[AX].Xl & 0xf) > 9) || (P->Eflags.EFLAG_AF != 0)) {
  33. Carry = (P->Gpr[AX].Xl > 0xf9);
  34. P->Gpr[AX].Xl = (P->Gpr[AX].Xl + 6) & 0xf;
  35. P->Gpr[AX].Xh += (UCHAR)(1 + Carry);
  36. P->Eflags.EFLAG_CF = 1;
  37. P->Eflags.EFLAG_AF = 1;
  38. } else {
  39. P->Gpr[AX].Xl &= 0xf;
  40. P->Eflags.EFLAG_CF = 0;
  41. P->Eflags.EFLAG_AF = 0;
  42. }
  43. return;
  44. }
  45. VOID
  46. XmAadOp (
  47. IN PRXM_CONTEXT P
  48. )
  49. /*++
  50. Routine Description:
  51. This function emulates an aad opcode.
  52. Arguments:
  53. P - Supplies a pointer to the emulation context structure.
  54. Return Value:
  55. None.
  56. --*/
  57. {
  58. //
  59. // Pack AH and AL into AX before division by scaling AH by 10 and
  60. // adding AL.
  61. //
  62. P->Gpr[AX].Xl = (P->Gpr[AX].Xh * P->SrcValue.Byte) + P->Gpr[AX].Xl;
  63. P->Gpr[AX].Xh = 0;
  64. P->Eflags.EFLAG_SF = (P->Gpr[AX].Xx >> 15) & 0x1;
  65. P->Eflags.EFLAG_ZF = (P->Gpr[AX].Xx == 0);
  66. P->Eflags.EFLAG_PF = XmComputeParity(P->Gpr[AX].Xx);
  67. return;
  68. }
  69. VOID
  70. XmAamOp (
  71. IN PRXM_CONTEXT P
  72. )
  73. /*++
  74. Routine Description:
  75. This function emulates an aam opcode.
  76. Arguments:
  77. P - Supplies a pointer to the emulation context structure.
  78. Return Value:
  79. None.
  80. --*/
  81. {
  82. //
  83. // Unpack AL into AL and AH after multiplication by dividing by 10
  84. // and storing the quotient in AH and the remainder in AL.
  85. //
  86. P->Gpr[AX].Xh = P->Gpr[AX].Xl / P->SrcValue.Byte;
  87. P->Gpr[AX].Xl = P->Gpr[AX].Xl % P->SrcValue.Byte;
  88. P->Eflags.EFLAG_SF = (P->Gpr[AX].Xx >> 15) & 0x1;
  89. P->Eflags.EFLAG_ZF = (P->Gpr[AX].Xx == 0);
  90. P->Eflags.EFLAG_PF = XmComputeParity(P->Gpr[AX].Xx);
  91. return;
  92. }
  93. VOID
  94. XmAasOp (
  95. IN PRXM_CONTEXT P
  96. )
  97. /*++
  98. Routine Description:
  99. This function emulates an aaa opcode.
  100. Arguments:
  101. P - Supplies a pointer to the emulation context structure.
  102. Return Value:
  103. None.
  104. --*/
  105. {
  106. ULONG Borrow;
  107. //
  108. // If AL if greater than 9 or AF is set, then adjust ASCII result.
  109. //
  110. if (((P->Gpr[AX].Xl & 0xf) > 9) || (P->Eflags.EFLAG_AF != 0)) {
  111. Borrow = (P->Gpr[AX].Xl < 0x6);
  112. P->Gpr[AX].Xl = (P->Gpr[AX].Xl - 6) & 0xf;
  113. P->Gpr[AX].Xh -= (UCHAR)(1 + Borrow);
  114. P->Eflags.EFLAG_CF = 1;
  115. P->Eflags.EFLAG_AF = 1;
  116. } else {
  117. P->Gpr[AX].Xl &= 0xf;
  118. P->Eflags.EFLAG_CF = 0;
  119. P->Eflags.EFLAG_AF = 0;
  120. }
  121. return;
  122. }
  123. VOID
  124. XmDaaOp (
  125. IN PRXM_CONTEXT P
  126. )
  127. /*++
  128. Routine Description:
  129. This function emulates a daa opcode.
  130. Arguments:
  131. P - Supplies a pointer to the emulation context structure.
  132. Return Value:
  133. None.
  134. --*/
  135. {
  136. //
  137. // If AL if greater than 9 or AF is set, then adjust ASCII result.
  138. //
  139. if (((P->Gpr[AX].Xl & 0xf) > 0x9) || (P->Eflags.EFLAG_AF != 0)) {
  140. P->Gpr[AX].Xl = P->Gpr[AX].Xl + 6;
  141. P->Eflags.EFLAG_AF = 1;
  142. } else {
  143. P->Eflags.EFLAG_AF = 0;
  144. }
  145. //
  146. // If AL is greater than 9 or CF is set, then adjust ASCII result.
  147. //
  148. if ((P->Gpr[AX].Xl > 9) || (P->Eflags.EFLAG_CF != 0)) {
  149. P->Gpr[AX].Xl = P->Gpr[AX].Xl + 0x60;
  150. P->Eflags.EFLAG_CF = 1;
  151. } else {
  152. P->Eflags.EFLAG_CF = 0;
  153. }
  154. return;
  155. }
  156. VOID
  157. XmDasOp (
  158. IN PRXM_CONTEXT P
  159. )
  160. /*++
  161. Routine Description:
  162. This function emulates a daa opcode.
  163. Arguments:
  164. P - Supplies a pointer to the emulation context structure.
  165. Return Value:
  166. None.
  167. --*/
  168. {
  169. //
  170. // If AL if greater than 9 or AF is set, then adjust ASCII result.
  171. //
  172. if (((P->Gpr[AX].Xl & 0xf) > 0x9) || (P->Eflags.EFLAG_AF != 0)) {
  173. P->Gpr[AX].Xl = P->Gpr[AX].Xl - 6;
  174. P->Eflags.EFLAG_AF = 1;
  175. } else {
  176. P->Eflags.EFLAG_AF = 0;
  177. }
  178. //
  179. // If AL is greater than 9 or CF is set, then adjust ASCII result.
  180. //
  181. if ((P->Gpr[AX].Xl > 9) || (P->Eflags.EFLAG_CF != 0)) {
  182. P->Gpr[AX].Xl = P->Gpr[AX].Xl - 0x60;
  183. P->Eflags.EFLAG_CF = 1;
  184. } else {
  185. P->Eflags.EFLAG_CF = 0;
  186. }
  187. return;
  188. }