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.

253 lines
5.2 KiB

  1. /* xmsblock.c - XMS Extended block related routines
  2. *
  3. * xmsAllocBlock
  4. * xmsFreeBlock
  5. * xmsReallocBlock
  6. * xmsMoveBlock
  7. * xmsQueryExtMem
  8. *
  9. * Modification History:
  10. *
  11. * Sudeepb 15-May-1991 Created
  12. */
  13. #include "xms.h"
  14. #include <memory.h>
  15. #include <string.h>
  16. #include <xmssvc.h>
  17. #include <softpc.h>
  18. #include <mvdm.h>
  19. /* xmsAllocBlock - Commit Memory for an EMB.
  20. *
  21. *
  22. * Entry - DX - Size in K to allocate
  23. *
  24. * Exit
  25. * SUCCESS
  26. * Client (AX) - Start address of the EMB (in K)
  27. *
  28. * FAILURE
  29. * Client (AX) = 0
  30. */
  31. VOID xmsAllocBlock (VOID)
  32. {
  33. BOOL Success;
  34. ULONG BaseAddress;
  35. ULONG size;
  36. size = getDX() * 1024;
  37. if(size) {
  38. //
  39. // Ask for a chunk of memory
  40. //
  41. Success = SAAllocate(
  42. ExtMemSA,
  43. size,
  44. &BaseAddress
  45. );
  46. if (!Success) {
  47. DbgPrint("xmsAllocBlock:SAAlloc failed !!!!\n");
  48. setAX(0);
  49. return;
  50. }
  51. }
  52. else
  53. BaseAddress = 0;
  54. ASSERT((USHORT)(BaseAddress / 1024) < 65535);
  55. setAX((USHORT)(BaseAddress / 1024));
  56. return;
  57. }
  58. /* xmsFreeBlock - Free Memory for an EMB.
  59. *
  60. *
  61. * Entry - AX - Start address of the EMB (in K)
  62. * DX - Size in K to free
  63. *
  64. * Exit
  65. * SUCCESS
  66. * Client (AX) = 1
  67. *
  68. * FAILURE
  69. * Client (AX) = 0
  70. */
  71. VOID xmsFreeBlock (VOID)
  72. {
  73. BOOL Success;
  74. ULONG BaseAddress;
  75. ULONG size;
  76. BaseAddress = (getAX() * 1024);
  77. size = getDX() * 1024;
  78. Success = SAFree(
  79. ExtMemSA,
  80. size,
  81. BaseAddress
  82. );
  83. if (!Success) {
  84. DbgPrint("xmsFreeBlock:SAFree failed !!!!");
  85. setAX(0);
  86. return;
  87. }
  88. setAX(1);
  89. return;
  90. }
  91. /* xmsReallocBlock - Change the size of an EMB.
  92. *
  93. *
  94. * Entry - AX - Start address of the EMB (in K)
  95. * DX - Original Size in K
  96. * BX - New size in K
  97. *
  98. * Exit
  99. * SUCCESS
  100. * Client (CX) = New base of block
  101. *
  102. * FAILURE
  103. * Client (AX) = 0
  104. */
  105. VOID xmsReallocBlock (VOID)
  106. {
  107. BOOL Success;
  108. ULONG BaseAddress;
  109. ULONG NewAddress;
  110. ULONG size;
  111. ULONG NewSize;
  112. size = getDX() * 1024;
  113. NewSize = getBX() * 1024;
  114. BaseAddress = getAX() * 1024;
  115. if(size != NewSize) {
  116. //
  117. // Realloc the chunk of memory
  118. //
  119. Success = SAReallocate(
  120. ExtMemSA,
  121. size,
  122. BaseAddress,
  123. NewSize,
  124. &NewAddress
  125. );
  126. if (!Success) {
  127. DbgPrint("xmsReallocBlock:SARealloc failed !!!!\n");
  128. setCX(0);
  129. return;
  130. }
  131. }
  132. else
  133. {
  134. NewAddress = BaseAddress;
  135. }
  136. ASSERT((NewAddress / 1024) < 65535);
  137. setCX((USHORT)(NewAddress / 1024));
  138. return;
  139. }
  140. /* xmsMoveBlock - Process Move Block Functions
  141. *
  142. *
  143. * Entry - Client (SS:BP) Pointer to Ext. Memory Move Structure
  144. * SS:BP-4 = DWORD Transfer Count in words (guaranteed even)
  145. * SS:BP-8 = DWORD Src Linear Address
  146. * SS:BP-12 = DWORD Dst Linear Address
  147. *
  148. * Exit
  149. * SUCCESS
  150. * Client (AX) = 1
  151. *
  152. * FAILURE
  153. * Client (AX) = 0
  154. * Client (BL) = error code
  155. *
  156. * NOTE: For Overlapping regions XMS spec says "If the Source and
  157. * Destination blocks overlap, only forward moves (i.e. where
  158. * the destination base is less than the source base) are
  159. * guaranteed to work properly"
  160. */
  161. VOID xmsMoveBlock (VOID)
  162. {
  163. PBYTE pExtMoveInfo,pSrc,pDst;
  164. ULONG cbTransfer,SoftpcBase, DstSegOff;
  165. pExtMoveInfo = (PBYTE) GetVDMAddr(getSS(),getBP());
  166. (ULONG)pExtMoveInfo = (ULONG)pExtMoveInfo -4;
  167. cbTransfer = (FETCHDWORD(*(PULONG)pExtMoveInfo));
  168. cbTransfer *= 2; // Get in bytes
  169. (ULONG)pExtMoveInfo = (ULONG)pExtMoveInfo -4;
  170. (DWORD)pSrc = FETCHDWORD(*(PULONG)pExtMoveInfo);
  171. (ULONG)pExtMoveInfo = (ULONG)pExtMoveInfo -4;
  172. (DWORD)pDst = FETCHDWORD(*(PULONG)pExtMoveInfo);
  173. // Yes, we could use memmov for handling the overlapping regions
  174. // but XMS spec wants memcpy behaviour.
  175. #ifdef i386
  176. RtlCopyMemory (pDst,pSrc,cbTransfer);
  177. #else
  178. SoftpcBase = (ULONG) GetVDMAddr (0,0);
  179. RtlCopyMemory((PVOID)((ULONG)pDst + SoftpcBase),
  180. (PVOID)((ULONG)pSrc + SoftpcBase),
  181. cbTransfer);
  182. // if we touched the intel memory, tell the emulator to flush its cache
  183. // WARNING!!!! Donot use Sim32FlushVDMPoiner unless you know the exact segment
  184. // address. In this case, we have no idea what the segment value is, all we
  185. // know is its "linear address".
  186. // BUGBUG verify whether we can ignore the case with pDst > 0x110000
  187. sas_overwrite_memory(pDst, cbTransfer);
  188. #endif
  189. setAX(1);
  190. return;
  191. }
  192. /* xmsQueryExtMem - Process query extended memory
  193. *
  194. *
  195. * Entry - None
  196. *
  197. * Exit
  198. * SUCCESS
  199. * Client (AX) = Largest Free Block in K
  200. * Client (DX) = Free Memory in K
  201. *
  202. * FAILURE
  203. * Client (AX) = 0
  204. * Client (DX) = 0
  205. *
  206. */
  207. VOID xmsQueryFreeExtMem(VOID)
  208. {
  209. ULONG LargestFree = 0;
  210. ULONG TotalFree = 0;
  211. //
  212. // Find out how much memory remains
  213. //
  214. SAQueryFree(
  215. ExtMemSA,
  216. &TotalFree,
  217. &LargestFree
  218. );
  219. ASSERT((TotalFree / 1024) < 65534);
  220. setAX((USHORT)(TotalFree / 1024));
  221. ASSERT((LargestFree / 1024) < 65534);
  222. setDX((USHORT)(LargestFree / 1024));
  223. }