summaryrefslogtreecommitdiffstats
path: root/private/mvdm/xms.486
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/mvdm/xms.486/alpha/sources1
-rw-r--r--private/mvdm/xms.486/i386/sources3
-rw-r--r--private/mvdm/xms.486/i386/xmsmem86.c155
-rw-r--r--private/mvdm/xms.486/makefile9
-rw-r--r--private/mvdm/xms.486/mips/sources1
-rw-r--r--private/mvdm/xms.486/ppc/sources1
-rw-r--r--private/mvdm/xms.486/sources58
-rw-r--r--private/mvdm/xms.486/xms.c103
-rw-r--r--private/mvdm/xms.486/xms.h156
-rw-r--r--private/mvdm/xms.486/xmsa20.c106
-rw-r--r--private/mvdm/xms.486/xmsblock.c247
-rw-r--r--private/mvdm/xms.486/xmsdisp.c59
-rw-r--r--private/mvdm/xms.486/xmsmemr.c167
-rw-r--r--private/mvdm/xms.486/xmsmisc.c84
-rw-r--r--private/mvdm/xms.486/xmsumb.c242
15 files changed, 1392 insertions, 0 deletions
diff --git a/private/mvdm/xms.486/alpha/sources b/private/mvdm/xms.486/alpha/sources
new file mode 100644
index 000000000..3d33411fb
--- /dev/null
+++ b/private/mvdm/xms.486/alpha/sources
@@ -0,0 +1 @@
+ALPHA_SOURCES=..\xmsmemr.c
diff --git a/private/mvdm/xms.486/i386/sources b/private/mvdm/xms.486/i386/sources
new file mode 100644
index 000000000..324c67cb3
--- /dev/null
+++ b/private/mvdm/xms.486/i386/sources
@@ -0,0 +1,3 @@
+
+i386_SOURCES=i386\xmsmem86.c
+
diff --git a/private/mvdm/xms.486/i386/xmsmem86.c b/private/mvdm/xms.486/i386/xmsmem86.c
new file mode 100644
index 000000000..b3f82e122
--- /dev/null
+++ b/private/mvdm/xms.486/i386/xmsmem86.c
@@ -0,0 +1,155 @@
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ xmscmt86.c
+
+Abstract:
+
+ This module conains the memory commit/decommit routines
+ for x86.
+
+Author:
+
+ Dave Hastings (daveh) creation-date 25-Jan-1994
+
+Revision History:
+
+
+--*/
+#include <xms.h>
+#include <suballoc.h>
+
+NTSTATUS
+xmsCommitBlock(
+ ULONG BaseAddress,
+ ULONG Size
+ )
+/*++
+
+Routine Description:
+
+ This routine commits a block of memory using NtAllocateVirtualMemory.
+
+Arguments:
+
+ BaseAddress -- Supplies the base address to commit memory at
+ Size -- Supplies the size of the block to commit
+
+Return Value:
+
+ Same as NtAllocateVirtualMemory.
+
+--*/
+{
+ PVOID Address;
+ ULONG s;
+ NTSTATUS Status;
+
+ //
+ // Copy the parameters locally, so that MM doesn't
+ // change them for us
+ //
+ Address = (PVOID)BaseAddress;
+ s = Size;
+
+ //
+ // Perform the allocation
+ //
+ Status = NtAllocateVirtualMemory(
+ NtCurrentProcess(),
+ &Address,
+ 0L,
+ &s,
+ MEM_COMMIT,
+ PAGE_READWRITE
+ );
+
+ return Status;
+}
+
+NTSTATUS
+xmsDecommitBlock(
+ ULONG BaseAddress,
+ ULONG Size
+ )
+/*++
+
+Routine Description:
+
+ This routine commits a block of memory using NtAllocateVirtualMemory.
+
+Arguments:
+
+ BaseAddress -- Supplies the base address to decommit memory at
+ Size -- Supplies the size of the block to decommit
+
+Return Value:
+
+ Same as NtFreeVirtualMemory.
+
+--*/
+{
+ PVOID Address;
+ ULONG s;
+ NTSTATUS Status;
+
+ //
+ // Copy the parameters locally, so that MM doesn't
+ // change them for us
+ //
+ Address = (PVOID)BaseAddress;
+ s = Size;
+
+ //
+ // Perform the allocation
+ //
+ Status = NtFreeVirtualMemory( NtCurrentProcess(),
+ &Address,
+ &s,
+ MEM_DECOMMIT
+ );
+
+ return Status;
+}
+
+VOID
+xmsMoveMemory(
+ ULONG Destination,
+ ULONG Source,
+ ULONG Count
+ )
+/*++
+
+Routine Description:
+
+ This routine moves a block of memory, and notifies the emulator.
+ It correctly handles overlapping source and destination
+
+Arguments:
+
+ Destination -- Supplies a pointer to the destination Linear
+ Address
+ Source -- Supplies a pointer to the source Linear Address
+ Count -- Supplies the number of bytes to move
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ //
+ // Move the memory
+ //
+ RtlMoveMemory(
+ (PVOID)Destination,
+ (PVOID)Source,
+ Count
+ );
+
+}
+
diff --git a/private/mvdm/xms.486/makefile b/private/mvdm/xms.486/makefile
new file mode 100644
index 000000000..445b289cb
--- /dev/null
+++ b/private/mvdm/xms.486/makefile
@@ -0,0 +1,9 @@
+# XMS makefile
+# 15-May-1991 Sudeep Bharati Created
+#
+
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/mvdm/xms.486/mips/sources b/private/mvdm/xms.486/mips/sources
new file mode 100644
index 000000000..c0ccd5e5a
--- /dev/null
+++ b/private/mvdm/xms.486/mips/sources
@@ -0,0 +1 @@
+MIPS_SOURCES=..\xmsmemr.c
diff --git a/private/mvdm/xms.486/ppc/sources b/private/mvdm/xms.486/ppc/sources
new file mode 100644
index 000000000..4dae141e4
--- /dev/null
+++ b/private/mvdm/xms.486/ppc/sources
@@ -0,0 +1 @@
+PPC_SOURCES=..\xmsmemr.c
diff --git a/private/mvdm/xms.486/sources b/private/mvdm/xms.486/sources
new file mode 100644
index 000000000..39181db06
--- /dev/null
+++ b/private/mvdm/xms.486/sources
@@ -0,0 +1,58 @@
+!IF 0
+
+Copyright (c) 1989-1991 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+History:
+ Created 15-May-1991 by Sudeep Bharati (sudeepb)
+ from template created 12-Apr-1990 by Steve Wood (stevewo)
+
+
+NOTE: Commented description of this file is in \nt\public\oak\bin\sources.tpl
+
+!ENDIF
+
+MAJORCOMP=mvdm
+MINORCOMP=xms
+
+TARGETNAME=xms486
+TARGETPATH=\nt\public\sdk\lib
+TARGETTYPE=LIBRARY
+TARGETLIBS=
+
+SOFTPC_TREE=$(BASEDIR)\private\mvdm\softpc.new
+
+INCLUDES=..\inc;$(SOFTPC_TREE)\base\inc
+
+!IF $(ALPHA) || $(MIPS)
+GPSIZE=0
+!ELSE
+GPSIZE=32
+!ENDIF
+
+
+NTPROFILEINPUT=YES
+
+SOURCES=xms.c \
+ xmsa20.c \
+ xmsblock.c \
+ xmsdisp.c \
+ xmsmisc.c \
+ xmsumb.c
+
+C_DEFINES=-DWIN_32
+
+UMTYPE=console
+UMTEST=
+UMLIBS=
diff --git a/private/mvdm/xms.486/xms.c b/private/mvdm/xms.486/xms.c
new file mode 100644
index 000000000..841513b42
--- /dev/null
+++ b/private/mvdm/xms.486/xms.c
@@ -0,0 +1,103 @@
+/*
+ * xms.c - Main Module of XMS DLL.
+ *
+ * Sudeepb 15-May-1991 Craeted
+ * williamh 25-Sept-1992 added UMB support
+ * williamh 10-10-1992 added A20 line support
+ */
+
+#include <xms.h>
+#include <suballoc.h>
+#include "umb.h"
+#include "memapi.h"
+
+/* XMSInit - XMS Initialiazation routine. (This name may change when XMS is
+ * converted to DLL).
+ *
+ * Entry
+ * None
+ *
+ * Exit
+ * None
+ */
+
+ULONG xmsMemorySize = (ULONG)0; // Total XMS meory in K
+
+extern BOOL VDMForWOW;
+
+PVOID ExtMemSA;
+
+BOOL XMSInit (int argc, char *argv[])
+{
+ DWORD Size;
+ PVOID Address;
+ ULONG VdmAddress, XmsSize;
+ NTSTATUS Status;
+
+ if (!xmsMemorySize)
+ return FALSE;
+
+ Size = 0;
+ Address = NULL;
+ // commit all free UMBs.
+ ReserveUMB(UMB_OWNER_RAM, &Address, &Size);
+
+ XmsSize = xmsMemorySize * 1024 - (64*1024);
+
+#ifndef i386
+ Status = VdmAllocateVirtualMemory(&VdmAddress,
+ XmsSize,
+ FALSE);
+
+ if (Status == STATUS_NOT_IMPLEMENTED) {
+
+ // Old emulator, just assume base address
+#endif ; //i386
+ //
+ // Initialize the sub allocator
+ //
+ ExtMemSA = SAInitialize(
+ 1024 * 1024 + 64*1024,
+ XmsSize,
+ xmsCommitBlock,
+ xmsDecommitBlock,
+ xmsMoveMemory
+ );
+
+#ifndef i386
+ } else {
+
+ //
+ // New emulator. Make sure the reserve worked
+ //
+
+ if (!NT_SUCCESS(Status)) {
+ ASSERT(FALSE);
+ return FALSE;
+ }
+
+ //
+ // We only work correctly if emulator returned this value
+ //
+ if (VdmAddress != (1024 * 1024 + 64*1024)) {
+ ASSERT(FALSE);
+ return FALSE;
+ }
+
+ ExtMemSA = SAInitialize(
+ VdmAddress,
+ XmsSize,
+ VdmCommitVirtualMemory,
+ VdmDeCommitVirtualMemory,
+ xmsMoveMemory
+ );
+
+ }
+#endif // i386
+
+ if (ExtMemSA == NULL) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/private/mvdm/xms.486/xms.h b/private/mvdm/xms.486/xms.h
new file mode 100644
index 000000000..dc9280271
--- /dev/null
+++ b/private/mvdm/xms.486/xms.h
@@ -0,0 +1,156 @@
+/* xms.h - main include file for dem
+ *
+ * Modification History
+ *
+ * Sudeepb 31-Mar-1991 Created
+ *
+ * williamh 25-Sept-1992 Added UMB support
+ */
+
+/*
+#define WIN
+#define FLAT_32
+#include <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#define _WINDOWS
+#include <windows.h>
+
+*/
+
+#ifdef DOS
+#define SIGNALS
+#endif
+
+#ifdef OS2_16
+#define OS2
+#define SIGNALS
+#endif
+
+#ifdef OS2_32
+#define OS2
+#define FLAT_32
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <process.h>
+
+#ifdef WIN_16
+#define WIN
+#define API16
+#endif
+
+#ifdef WIN_32
+#define WIN
+#define FLAT_32
+#define TRUE_IF_WIN32 1
+#include <nt.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+#else
+#define TRUE_IF_WIN32 0
+#endif
+
+#ifdef FLAT_32
+#ifndef i386
+#define ALIGN_32
+#else
+#define NOALIGN_32
+#endif
+#endif
+
+#ifdef WIN
+#define _WINDOWS
+#include <windows.h>
+#endif
+
+#ifdef SIGNALS
+#include <conio.h>
+#include <signal.h>
+#endif
+
+#ifdef OS2_32
+#include <excpt.h>
+#define XCPT_SIGNAL 0xC0010003
+#endif
+#include <xmsexp.h>
+#include <suballoc.h>
+
+#define SIZE_PARAGRAPH 16
+#define XMSUMB_THRESHOLD 3 * SIZE_PARAGRAPH
+
+/** Basic Typedefs of XMS **/
+
+typedef VOID (*PFNSVC)(VOID);
+
+typedef struct _ExtMemMove {
+ ULONG mm_len; // Move Length
+ USHORT mm_hSource; // Source Handle
+ ULONG mm_SourceOffset; // Source Offset
+ USHORT mm_hDest; // Dest Handle
+ ULONG mm_DestOffset; // Dest. offset
+} EXTMEMMOVE, *PEXTMEMMOVE;
+
+
+typedef struct _XMSUMB_ {
+ WORD Segment;
+ WORD Size;
+ WORD Owner;
+ struct _XMSUMB_ *Next;
+} XMSUMB, *PXMSUMB;
+
+/** Function Prototypes */
+
+VOID xmsA20 (VOID);
+VOID xmsAllocBlock (VOID);
+VOID xmsFreeBlock (VOID);
+VOID xmsReallocBlock (VOID);
+VOID xmsMoveBlock (VOID);
+VOID xmsSysPageSize (VOID);
+VOID xmsQueryExtMem (VOID);
+VOID xmsQueryFreeExtMem (VOID);
+ULONG xmsGetMemorySize (BOOL);
+ULONG xmsGetDefaultVDMSize (VOID);
+VOID xmsInitUMB (VOID);
+VOID xmsRequestUMB (VOID);
+VOID xmsReleaseUMB (VOID);
+VOID xmsReleaseUMBNotify (PVOID, ULONG);
+VOID xmsInsertUMB (PVOID, ULONG);
+VOID xmsNotifyHookI15 (VOID);
+
+VOID xmsDisableA20Wrapping (VOID);
+VOID xmsEnableA20Wrapping (VOID);
+
+NTSTATUS
+xmsCommitBlock(
+ ULONG BaseAddress,
+ ULONG Size
+ );
+
+NTSTATUS
+xmsDecommitBlock(
+ ULONG BaseAddress,
+ ULONG Size
+ );
+
+VOID
+xmsMoveMemory(
+ ULONG Source,
+ ULONG Destination,
+ ULONG Count
+ );
+
+
+#ifndef i386
+BOOL sas_manage_xms (VOID * start_addr, ULONG cb, INT a_or_f);
+#endif
+
+/** External Data */
+
+extern ULONG xmsMemorySize;
+extern BYTE * pHimemA20State;
diff --git a/private/mvdm/xms.486/xmsa20.c b/private/mvdm/xms.486/xmsa20.c
new file mode 100644
index 000000000..d52aa1d48
--- /dev/null
+++ b/private/mvdm/xms.486/xmsa20.c
@@ -0,0 +1,106 @@
+/* xmsa20.c - A20 related XMS routines
+ *
+ * XMSA20
+ *
+ * Modification History:
+ *
+ * Sudeepb 15-May-1991 Created
+ */
+
+#include "xms.h"
+
+#include <xmssvc.h>
+#include <softpc.h>
+
+void sas_enable_20_bit_wrapping(void);
+void sas_disable_20_bit_wrapping(void);
+BOOL sas_twenty_bit_wrapping_enabled(void);
+
+BYTE * pHimemA20State = NULL;
+
+
+/* xmsA20 - Handle A20 requests
+ *
+ *
+ * Entry - Client (AX) 0 - Disable A20
+ * 1 - Enable A20
+ * 2 - Query
+ *
+ * Exit
+ * SUCCESS
+ * Client (AX) = 1
+ * if on entry AX=2 Then
+ * Cleint (AX) =1 means was enabled
+ * Cleint (AX) =0 means was disabled
+ *
+ * FAILURE
+ * Client (AX) = 0
+ */
+
+VOID xmsA20 (VOID)
+{
+ int reason;
+
+ reason = getAX();
+
+ setAX(1);
+
+ if (reason == 0)
+ xmsEnableA20Wrapping();
+ else if (reason == 1)
+ xmsDisableA20Wrapping();
+ else if (reason == 2) {
+ if (sas_twenty_bit_wrapping_enabled())
+ setAX(0);
+ setBL(0);
+ }
+ else
+ setAX(0);
+}
+// function to enable 1MB wrapping (turn off A20 line)
+VOID xmsEnableA20Wrapping(VOID)
+{
+ sas_enable_20_bit_wrapping();
+ if (pHimemA20State != NULL)
+ *pHimemA20State = 0;
+
+#if 0 // this is not necessay because the intel space(pointed by
+ // HimemA20State) doesn't contain instruction
+ // doesn't contain instruction
+#ifdef MIPS
+ Sim32FlushVDMPointer
+ (
+ (((ULONG)pHimemA20State >> 4) << 16) | ((ULONG)pHimemA20State & 0xF),
+ 1,
+ pHimemA20State,
+ FALSE
+ );
+
+#endif
+#endif
+
+}
+
+// function to disable 1MB wrapping(turn on A20 line)
+VOID xmsDisableA20Wrapping(VOID)
+{
+
+ sas_disable_20_bit_wrapping();
+ if (pHimemA20State != NULL)
+ *pHimemA20State = 1;
+#if 0 // this is not necessay because the intel space(pointed by
+ // HimemA20State) doesn't contain instruction
+ // doesn't contain instruction
+#ifdef MIPS
+ Sim32FlushVDMPointer
+ (
+ (((ULONG)pHimemA20State >> 4) << 16) | ((ULONG)pHimemA20State & 0xF),
+ 1,
+ pHimemA20State,
+ FALSE
+ );
+
+#endif
+#endif
+
+}
diff --git a/private/mvdm/xms.486/xmsblock.c b/private/mvdm/xms.486/xmsblock.c
new file mode 100644
index 000000000..8eb2818c9
--- /dev/null
+++ b/private/mvdm/xms.486/xmsblock.c
@@ -0,0 +1,247 @@
+/* xmsblock.c - XMS Extended block related routines
+ *
+ * xmsAllocBlock
+ * xmsFreeBlock
+ * xmsReallocBlock
+ * xmsMoveBlock
+ * xmsQueryExtMem
+ *
+ * Modification History:
+ *
+ * Sudeepb 15-May-1991 Created
+ */
+
+#include "xms.h"
+#include <memory.h>
+#include <string.h>
+#include <xmssvc.h>
+#include <softpc.h>
+#include <mvdm.h>
+
+
+/* xmsAllocBlock - Commit Memory for an EMB.
+ *
+ *
+ * Entry - DX - Size in K to allocate
+ *
+ * Exit
+ * SUCCESS
+ * Client (AX) - Start address of the EMB (in K)
+ *
+ * FAILURE
+ * Client (AX) = 0
+ */
+
+VOID xmsAllocBlock (VOID)
+{
+BOOL Success;
+ULONG BaseAddress;
+ULONG size;
+
+ size = getDX() * 1024;
+ if(size) {
+
+ //
+ // Ask for a chunk of memory
+ //
+ Success = SAAllocate(
+ ExtMemSA,
+ size,
+ &BaseAddress
+ );
+
+ if (!Success) {
+ DbgPrint("xmsAllocBlock:SAAlloc failed !!!!\n");
+ setAX(0);
+ return;
+ }
+ }
+
+ ASSERT((USHORT)(BaseAddress / 1024) < 65535);
+ setAX((USHORT)(BaseAddress / 1024));
+ return;
+}
+
+/* xmsFreeBlock - Free Memory for an EMB.
+ *
+ *
+ * Entry - AX - Start address of the EMB (in K)
+ * DX - Size in K to free
+ *
+ * Exit
+ * SUCCESS
+ * Client (AX) = 1
+ *
+ * FAILURE
+ * Client (AX) = 0
+ */
+
+VOID xmsFreeBlock (VOID)
+{
+BOOL Success;
+ULONG BaseAddress;
+ULONG size;
+
+ BaseAddress = (getAX() * 1024);
+ size = getDX() * 1024;
+
+ Success = SAFree(
+ ExtMemSA,
+ size,
+ BaseAddress
+ );
+
+ if (!Success) {
+ DbgPrint("xmsFreeBlock:SAFree failed !!!!");
+ setAX(0);
+ return;
+ }
+
+ setAX(1);
+ return;
+}
+
+/* xmsReallocBlock - Change the size of an EMB.
+ *
+ *
+ * Entry - AX - Start address of the EMB (in K)
+ * DX - Original Size in K
+ * BX - New size in K
+ *
+ * Exit
+ * SUCCESS
+ * Client (CX) = New base of block
+ *
+ * FAILURE
+ * Client (AX) = 0
+ */
+
+VOID xmsReallocBlock (VOID)
+{
+BOOL Success;
+ULONG BaseAddress;
+ULONG NewAddress;
+ULONG size;
+ULONG NewSize;
+
+ size = getDX() * 1024;
+ NewSize = getBX() * 1024;
+ BaseAddress = getAX() * 1024;
+ if(size != NewSize) {
+
+ //
+ // Realloc the chunk of memory
+ //
+ Success = SAReallocate(
+ ExtMemSA,
+ size,
+ BaseAddress,
+ NewSize,
+ &NewAddress
+ );
+
+ if (!Success) {
+ DbgPrint("xmsReallocBlock:SARealloc failed !!!!\n");
+ setCX(0);
+ return;
+ }
+ }
+
+ ASSERT((NewAddress / 1024) < 65535);
+ setCX((USHORT)(NewAddress / 1024));
+ return;
+}
+
+/* xmsMoveBlock - Process Move Block Functions
+ *
+ *
+ * Entry - Client (SS:BP) Pointer to Ext. Memory Move Structure
+ * SS:BP-4 = DWORD Transfer Count in words (guaranteed even)
+ * SS:BP-8 = DWORD Src Linear Address
+ * SS:BP-12 = DWORD Dst Linear Address
+ *
+ * Exit
+ * SUCCESS
+ * Client (AX) = 1
+ *
+ * FAILURE
+ * Client (AX) = 0
+ * Client (BL) = error code
+ *
+ * NOTE: For Overlapping regions XMS spec says "If the Source and
+ * Destination blocks overlap, only forward moves (i.e. where
+ * the destination base is less than the source base) are
+ * guaranteed to work properly"
+ */
+
+VOID xmsMoveBlock (VOID)
+{
+PBYTE pExtMoveInfo,pSrc,pDst;
+ULONG cbTransfer,SoftpcBase, DstSegOff;
+
+ pExtMoveInfo = (PBYTE) GetVDMAddr(getSS(),getBP());
+ (ULONG)pExtMoveInfo = (ULONG)pExtMoveInfo -4;
+ cbTransfer = (FETCHDWORD(*(PULONG)pExtMoveInfo));
+ cbTransfer *= 2; // Get in bytes
+ (ULONG)pExtMoveInfo = (ULONG)pExtMoveInfo -4;
+ (DWORD)pSrc = FETCHDWORD(*(PULONG)pExtMoveInfo);
+ (ULONG)pExtMoveInfo = (ULONG)pExtMoveInfo -4;
+ (DWORD)pDst = FETCHDWORD(*(PULONG)pExtMoveInfo);
+
+ // Yes, we could use memmov for handling the overlapping regions
+ // but XMS spec wants memcpy behaviour.
+
+#ifdef i386
+ RtlCopyMemory (pDst,pSrc,cbTransfer);
+#else
+ SoftpcBase = (ULONG) GetVDMAddr (0,0);
+ RtlCopyMemory((PVOID)((ULONG)pDst + SoftpcBase),
+ (PVOID)((ULONG)pSrc + SoftpcBase),
+ cbTransfer);
+ // if we touched the intel memory, tell the emulator to flush its cache
+ // WARNING!!!! Donot use Sim32FlushVDMPoiner unless you know the exact segment
+ // address. In this case, we have no idea what the segment value is, all we
+ // know is its "linear address".
+ // BUGBUG verify whether we can ignore the case with pDst > 0x110000
+ sas_overwrite_memory(pDst, cbTransfer);
+
+#endif
+ setAX(1);
+ return;
+}
+
+/* xmsQueryExtMem - Process query extended memory
+ *
+ *
+ * Entry - None
+ *
+ * Exit
+ * SUCCESS
+ * Client (AX) = Largest Free Block in K
+ * Client (DX) = Free Memory in K
+ *
+ * FAILURE
+ * Client (AX) = 0
+ * Client (DX) = 0
+ *
+ */
+VOID xmsQueryFreeExtMem(VOID)
+{
+ ULONG LargestFree = 0;
+ ULONG TotalFree = 0;
+
+ //
+ // Find out how much memory remains
+ //
+ SAQueryFree(
+ ExtMemSA,
+ &TotalFree,
+ &LargestFree
+ );
+
+ ASSERT((TotalFree / 1024) < 65534);
+ setAX((USHORT)(TotalFree / 1024));
+ ASSERT((LargestFree / 1024) < 65534);
+ setDX((USHORT)(LargestFree / 1024));
+
+}
diff --git a/private/mvdm/xms.486/xmsdisp.c b/private/mvdm/xms.486/xmsdisp.c
new file mode 100644
index 000000000..c044159ad
--- /dev/null
+++ b/private/mvdm/xms.486/xmsdisp.c
@@ -0,0 +1,59 @@
+/*
+ * xmsdisp.c - SVC dispatch module for XMS
+ *
+ * Modification History:
+ *
+ * Sudeepb 15-May-1991 Created
+ *
+ * williamh 25-Sept-1992 Added UMB support
+ */
+
+#include <xms.h>
+#include <xmsexp.h>
+#include <stdio.h>
+#include <softpc.h>
+#include <xmssvc.h>
+
+PFNSVC apfnXMSSvc [] = {
+ xmsA20, // XMS_A20
+ xmsMoveBlock, // XMS_MOVEBLOCK
+ xmsAllocBlock, // XMS_ALLOCBLOCK
+ xmsFreeBlock, // XMS_FREEBLOCK
+ xmsSysPageSize, // XMS_SYSTEMPAGESIZE
+ xmsQueryExtMem, // XMS_EXTMEM
+ xmsInitUMB, // XMS_INITUMB
+ xmsRequestUMB, // XMS_REQUESTUMB
+ xmsReleaseUMB, // XMS_RELEASEUMB
+ xmsNotifyHookI15, // XMS_NOTIFYHOOKI15
+ xmsQueryFreeExtMem, // XMS_QUERYEXTMEM
+ xmsReallocBlock // XMS_REALLOCBLOCK
+};
+
+/* XMSDispatch - Dispatch SVC call to right handler.
+ *
+ * Entry - iSvc (SVC byte following SVCop)
+ *
+ * Exit - None
+ *
+ * Note - Some mechanism has to be worked out to let the emulator know
+ * about DOSKRNL code segment and size. Using these it will figure
+ * out whether SVCop (hlt for the moment) has to be passed to
+ * DEM or to be handled as normal invalid opcode.
+ */
+
+BOOL XMSDispatch (ULONG iSvc)
+{
+
+#if DBG
+
+ if (iSvc >= XMS_LASTSVC){
+ printf("XMS:Unimplemented SVC index %x\n",iSvc);
+ setCF(1);
+ return FALSE;
+ }
+
+#endif
+
+ (apfnXMSSvc [iSvc])();
+ return TRUE;
+}
diff --git a/private/mvdm/xms.486/xmsmemr.c b/private/mvdm/xms.486/xmsmemr.c
new file mode 100644
index 000000000..9a495d671
--- /dev/null
+++ b/private/mvdm/xms.486/xmsmemr.c
@@ -0,0 +1,167 @@
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ xmscmt86.c
+
+Abstract:
+
+ This module conains the memory commit/decommit/move routines
+ for risc.
+
+Author:
+
+ Dave Hastings (daveh) creation-date 25-Jan-1994
+
+Revision History:
+
+
+--*/
+#include <xms.h>
+#include <suballoc.h>
+#include <softpc.h>
+
+NTSTATUS
+xmsCommitBlock(
+ ULONG BaseAddress,
+ ULONG Size
+ )
+/*++
+
+Routine Description:
+
+ This routine commits a block of memory using sas_manage_xms.
+
+Arguments:
+
+ BaseAddress -- Supplies the base address to commit memory at
+ Size -- Supplies the size of the block to commit
+
+Return Value:
+
+ 0 if successfull
+
+--*/
+{
+ BOOL Status;
+
+ //
+ // Perform the allocation
+ //
+ Status = sas_manage_xms(
+ (PVOID)BaseAddress,
+ Size,
+ 1
+ );
+
+ //
+ // We elected to have 0 indicate success, because that allows
+ // us to directly pass back NTSTATUS codes. On x86 we use
+ // NT memory management to do the commit for us, and the returned
+ // status code contains more information than just success or failure
+ //
+
+ if (Status) {
+ return STATUS_SUCCESS;
+ } else {
+ return -1;
+ }
+}
+
+NTSTATUS
+xmsDecommitBlock(
+ ULONG BaseAddress,
+ ULONG Size
+ )
+/*++
+
+Routine Description:
+
+ This routine commits a block of memory using sas_manage_xms.
+
+Arguments:
+
+ BaseAddress -- Supplies the base address to decommit memory at
+ Size -- Supplies the size of the block to decommit
+
+Return Value:
+
+ 0 if successful
+
+--*/
+{
+ BOOL Status;
+
+ //
+ // Perform the allocation
+ //
+ Status = sas_manage_xms(
+ (PVOID)BaseAddress,
+ Size,
+ 2
+ );
+
+ //
+ // We elected to have 0 indicate success, because that allows
+ // us to directly pass back NTSTATUS codes. On x86 we use
+ // NT memory management to do the commit for us, and the returned
+ // status code contains more information than just success or failure
+ //
+ if (Status) {
+ return STATUS_SUCCESS;
+ } else {
+ return -1;
+ }
+}
+
+VOID
+xmsMoveMemory(
+ ULONG Destination,
+ ULONG Source,
+ ULONG Count
+ )
+/*++
+
+Routine Description:
+
+ This routine moves a block of memory, and notifies the emulator.
+ It correctly handles overlapping source and destination
+
+Arguments:
+
+ Destination -- Supplies a pointer to the destination Intel (NOT Linear)
+ Address
+ Source -- Supplies a pointer to the source Intel Address
+ Count -- Supplies the number of bytes to move
+
+Return Value:
+
+ None.
+
+--*/
+{
+ ULONG SoftpcBase;
+
+ //
+ // Get the linear address of the beginning of Intel memory
+ //
+ SoftpcBase = (ULONG) GetVDMAddr(0,0);
+
+ //
+ // Move the memory
+ //
+ RtlMoveMemory(
+ (PVOID)((ULONG)Destination + SoftpcBase),
+ (PVOID)((ULONG)Source + SoftpcBase),
+ Count
+ );
+
+ // WARNING!!!! Donot use Sim32FlushVDMPoiner unless you know the exact segment
+ // address. In this case, we have no idea what the segment value is, all we
+ // know is its "linear address".
+
+ sas_overwrite_memory((PBYTE)Destination, Count);
+
+}
diff --git a/private/mvdm/xms.486/xmsmisc.c b/private/mvdm/xms.486/xmsmisc.c
new file mode 100644
index 000000000..9f15120ec
--- /dev/null
+++ b/private/mvdm/xms.486/xmsmisc.c
@@ -0,0 +1,84 @@
+/* xmsmisc.c - Misc. Support Functions for himem.
+ *
+ * xmsSysPageSize
+ * xmsQueryExtMem
+ *
+ * Modification History:
+ *
+ * Sudeepb 15-May-1991 Created
+ */
+
+#include "xms.h"
+
+#include <xmssvc.h>
+#include <softpc.h>
+
+extern void UpdateKbdInt15(WORD Seg,WORD Off);
+
+/* xmsSysPageSize - Get the System Page size.
+ *
+ *
+ * Entry - None
+ *
+ * Exit
+ * SUCCESS
+ * Client (AX) = Page Size in bytes
+ *
+ * FAILURE
+ * Not Valid
+ */
+
+VOID xmsSysPageSize (VOID)
+{
+SYSTEM_INFO SysInfo;
+
+ GetSystemInfo(&SysInfo);
+
+ setAX((USHORT)SysInfo.dwPageSize);
+
+ return;
+}
+
+
+
+/* xmsQueryExtMem - Get the extended memory for the vdm
+ *
+ *
+ * Entry - None
+ *
+ * Exit
+ * SUCCESS
+ * Client (AX) = Extended Memory in K
+ *
+ * FAILURE
+ * Not Valid
+ */
+
+VOID xmsQueryExtMem (VOID)
+{
+ setAX((USHORT)(xmsMemorySize));
+ return;
+}
+
+
+/* xmsNotifyHookI15 - Informs softpc that someone is hooking I15
+ * - also returns the extended memory for the vdm
+ *
+ *
+ * Entry - Client (CS:AX) seg:off of new I15 vector
+ *
+ * Exit
+ * SUCCESS
+ * Client (CX) = Extended Memory in K
+ *
+ * FAILURE
+ * Not Valid
+ */
+
+VOID xmsNotifyHookI15 (VOID)
+{
+ UpdateKbdInt15(getCS(), getAX());
+
+ setCX((USHORT)(xmsMemorySize));
+ return;
+}
diff --git a/private/mvdm/xms.486/xmsumb.c b/private/mvdm/xms.486/xmsumb.c
new file mode 100644
index 000000000..934650e6f
--- /dev/null
+++ b/private/mvdm/xms.486/xmsumb.c
@@ -0,0 +1,242 @@
+
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ XNSUMB.C
+
+Abstract:
+
+ Routines to service XMS Request UMB and Release UMB functions.
+ Also includes UMB initialization routine
+
+Author:
+
+ William Hsieh (williamh) Created 23-Sept-1992
+
+[Environment:]
+
+ User mode, running in the MVDM context (bop from 16bits)
+
+[Notes:]
+
+
+
+Revision History:
+
+--*/
+#include <xms.h>
+#include "umb.h"
+#include "softpc.h"
+
+
+
+// This global variable points to the first node(lowest address) UMB list
+static PXMSUMB xmsUMBHead;
+static BOOL xmsIsON = FALSE;
+// ------------------------------------------------------------------
+// Initialization for UMB support. It create a single direction linked
+// list and allocate all available UMBs.
+// Input: client (AX:BX) = segment:offset of himem.sys A20State variable
+//
+// Output: list header, xmsUMBHead set.
+//-------------------------------------------------------------------
+VOID xmsInitUMB(VOID)
+{
+ PVOID Address;
+ ULONG Size;
+ PXMSUMB xmsUMB, xmsUMBNew;
+ xmsUMBHead = NULL;
+ while (ReserveUMB(UMB_OWNER_XMS, &Address, &Size) &&
+ (xmsUMBNew = (PXMSUMB) malloc(sizeof(XMSUMB))) != NULL) {
+ // convert size in bytes to paragraphs
+ xmsUMBNew->Size = (WORD) (Size >> 4);
+ // convert linear address to paragraphs segment
+ xmsUMBNew->Segment = (WORD)((DWORD)Address >> 4);
+ xmsUMBNew->Owner = 0;
+ if (xmsUMBHead == NULL) {
+ xmsUMBHead = xmsUMBNew;
+ xmsUMBHead->Next = NULL;
+ }
+ else {
+ xmsUMBNew->Next = xmsUMB->Next;
+ xmsUMB->Next = xmsUMBNew;
+ }
+ xmsUMB = xmsUMBNew;
+ }
+ xmsIsON = TRUE;
+ pHimemA20State = (PBYTE) GetVDMAddr(getAX(), getBX());
+ xmsEnableA20Wrapping();
+
+
+
+}
+
+// This function receives control whenever there has been an UMB released
+// Input: PVOID Address = the block address
+// ULONG Size = the block size
+VOID xmsReleaseUMBNotify(
+PVOID Address,
+DWORD Size
+)
+{
+ // If the block is good and xms driver is ON,
+ // grab the block and insert it into our xms UMB list
+ if (Address != NULL && Size > 0 && xmsIsON &&
+ ReserveUMB(UMB_OWNER_XMS, &Address, &Size)){
+ xmsInsertUMB(Address, Size);
+ }
+
+}
+// ------------------------------------------------------------------
+// Insert a given UMB into the list
+// Input: PVOID Address = linear address of the block to be inserted
+// ULONG Size = size in byte of the block
+// Output: TRUE if the block was inserted to the list successfully
+// FALSE if the block wasn't inserted
+//-------------------------------------------------------------------
+
+VOID xmsInsertUMB(
+PVOID Address,
+ULONG Size
+)
+{
+ PXMSUMB xmsUMB, xmsUMBNew;
+ WORD Segment;
+
+ Segment = (WORD) ((DWORD)Address >> 4);
+ Size >>= 4;
+
+ xmsUMB = xmsUMBNew = xmsUMBHead;
+ while (xmsUMBNew != NULL && xmsUMBNew->Segment < Segment) {
+ xmsUMB = xmsUMBNew;
+ xmsUMBNew = xmsUMBNew->Next;
+ }
+ // merge it with previous block if possible
+ if (xmsUMB != NULL &&
+ xmsUMB->Owner == 0 &&
+ Segment == xmsUMB->Segment + xmsUMB->Size) {
+
+ xmsUMB->Size += (WORD) Size;
+ return;
+ }
+ // merge it with the after block if possible
+ if (xmsUMBNew != NULL &&
+ xmsUMBNew->Owner == 0 &&
+ xmsUMBNew->Segment == Segment + Size) {
+
+ xmsUMBNew->Size += (WORD) Size;
+ xmsUMBNew->Segment = Segment;
+ return;
+ }
+ // create a new node for the block
+ if ((xmsUMBNew = (PXMSUMB)malloc(sizeof(XMSUMB))) != NULL) {
+ xmsUMBNew->Size = (WORD) Size;
+ xmsUMBNew->Segment = Segment;
+ xmsUMBNew->Owner = 0;
+ if (xmsUMBHead == NULL) {
+ xmsUMBHead = xmsUMBNew;
+ xmsUMBNew->Next = NULL;
+ }
+ else {
+ xmsUMBNew->Next = xmsUMB->Next;
+ xmsUMB->Next = xmsUMBNew;
+ }
+ }
+}
+// ------------------------------------------------------------------
+// XMS function 16, Request UMB.
+// Input: (DX) = requested size in paragraphs
+// Output: (AX) = 1 if succeed and
+// (BX) has segment address(number) of the block
+// (DX) has actual allocated size in paragraphs
+// (AX) = 0 if failed and
+// (BL) = 0xB0, (DX) = largest size available
+// or
+// (BL) = 0xB1 if no UMBs are available
+//-------------------------------------------------------------------
+VOID xmsRequestUMB(VOID)
+{
+ PXMSUMB xmsUMB, xmsUMBNew;
+ WORD SizeRequested, SizeLargest;
+
+ xmsUMB = xmsUMBHead;
+ SizeRequested = getDX();
+ SizeLargest = 0;
+ while (xmsUMB != NULL) {
+ if (xmsUMB->Owner == 0) {
+ if (xmsUMB->Size >= SizeRequested) {
+ if((xmsUMB->Size - SizeRequested) >= XMSUMB_THRESHOLD &&
+ (xmsUMBNew = (PXMSUMB) malloc(sizeof(XMSUMB))) != NULL) {
+
+ xmsUMBNew->Segment = xmsUMB->Segment + SizeRequested;
+ xmsUMBNew->Size = xmsUMB->Size - SizeRequested;
+ xmsUMBNew->Next = xmsUMB->Next;
+ xmsUMB->Next = xmsUMBNew;
+ xmsUMBNew->Owner = 0;
+ xmsUMB->Size -= xmsUMBNew->Size;
+ }
+ xmsUMB->Owner = 0xFFFF;
+ setAX(1);
+ setBX(xmsUMB->Segment);
+ setDX(xmsUMB->Size);
+ return;
+ }
+ else {
+ if (xmsUMB->Size > SizeLargest)
+ SizeLargest = xmsUMB->Size;
+ }
+ }
+ xmsUMB = xmsUMB->Next;
+ }
+ setAX(0);
+ setDX(SizeLargest);
+ if (SizeLargest > 0)
+ setBL(0xB0);
+ else
+ setBL(0xB1);
+}
+
+
+//------------------------------------------------------------------
+// XMS function 17, Release UMB.
+// Input : (DX) = segment to be released
+// Output: (AX) = 1 if succeed
+// (AX) = 0 if failed and
+// (BL) = 0xB2 if segment not found in the list
+//------------------------------------------------------------------
+VOID xmsReleaseUMB(VOID)
+{
+ PXMSUMB xmsUMB, xmsUMBNext;
+ WORD Segment;
+
+ xmsUMB = xmsUMBHead;
+ Segment = getDX();
+ while (xmsUMB != NULL && xmsUMB->Segment != Segment) {
+ xmsUMB = xmsUMB->Next;
+ }
+ if (xmsUMB != NULL && xmsUMB->Owner != 0) {
+ xmsUMB->Owner = 0;
+ // no walk through the entire list to combine consecutive
+ // blocks together
+ xmsUMB = xmsUMBHead;
+ while (xmsUMB != NULL) {
+ while (xmsUMB->Owner == 0 &&
+ (xmsUMBNext = xmsUMB->Next) != NULL &&
+ xmsUMBNext->Owner == 0 &&
+ (WORD)(xmsUMB->Segment + xmsUMB->Size) == xmsUMBNext->Segment){
+ xmsUMB->Size += xmsUMBNext->Size;
+ xmsUMB->Next = xmsUMBNext->Next;
+ free(xmsUMBNext);
+ }
+ xmsUMB = xmsUMB->Next;
+ }
+ setAX(1);
+ }
+ else {
+ setBL(0xB2);
+ setAX(0);
+ }
+}