1 /* This file implements rudimentary XMS memory handling.
\r
2 * Documentation on the XMS API was found on http://www.qzx.com/pc-gpe/xms30.txt
\r
5 #include "src\lib\xms.h"
\r
7 /* Set up the XMS driver, returns 0 on success and non-zero on failure */
\r
8 static int initxms(void)
\r
12 if ( XMSControl == 0 )
\r
15 ; Is an XMS driver installed?
\r
21 if ( XMSStatus == 0x80 )
\r
24 ; Get the address of the driver control function
\r
27 mov word ptr [XMSControl] ,bx
\r
28 mov word ptr [XMSControl+2],es
\r
33 return ( XMSControl == 0 );
\r
36 /* Allocate a slab of memory from XMS */
\r
37 void huge * xmsmalloc(long unsigned int size)
\r
40 unsigned int XMSStatus = 0;
\r
41 unsigned int XMSHandle = 0;
\r
42 void huge * XMSPointer = NULL;
\r
45 /* If we can not initialize XMS, the allocation fails */
\r
49 /* It is not possible to allocate more kilobytes than a 16-bit register can hold :-) */
\r
50 if ( size / 1024 > UINT_MAX )
\r
53 /* Get the next free entry in the handle <-> pointer mapping */
\r
54 for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )
\r
56 if ( allocMapXMS[n].XMSPointer == NULL )
\r
60 if ( n == MAX_XMS_ALLOCATIONS )
\r
63 kB = size / 1024 + (size % 1024 > 0);
\r
66 ; Allocate [kB] kilobytes of XMS memory
\r
74 /* Check if XMS allocation failed */
\r
75 if ( XMSStatus == 0)
\r
79 ; Convert XMS handle to normal pointer
\r
85 mov word ptr [XMSPointer], bx
\r
86 mov word ptr [XMSPointer+2],dx
\r
89 if ( XMSStatus == 0 )
\r
91 /* Lock failed, deallocate the handle */
\r
98 ; Return value is not really interesting
\r
99 ; mov [XMSStatus], ax
\r
104 /* Create an entry in the handle <-> pointer mapping */
\r
105 allocMapXMS[n].XMSHandle = XMSHandle;
\r
106 allocMapXMS[n].XMSPointer = XMSPointer;
\r
111 /* Free a pointer allocated with xmsalloc */
\r
112 void xmsfree(void huge * XMSPointer)
\r
116 if ( XMSPointer == NULL )
\r
122 for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )
\r
124 if ( allocMapXMS[n].XMSPointer == XMSPointer )
\r
126 int XMSHandle = allocMapXMS[n].XMSHandle;
\r
129 ; Unlock handle so we can free the memory block
\r
131 mov dx, [XMSHandle]
\r
136 mov dx, [XMSHandle]
\r
139 ; Return value ignored
\r
142 /* Clear handle <-> pointer map entry so it can be reused */
\r
143 allocMapXMS[n].XMSHandle = 0;
\r
144 allocMapXMS[n].XMSPointer = NULL;
\r
151 /* Write a memory report for debugging purposes */
\r
152 void xmsreport(void/*FILE * stream*/)
\r
154 int XMSVersionNumber = 0;
\r
155 unsigned int XMSLargestBlock = 0;
\r
156 unsigned int XMSTotal = 0;
\r
160 puts("Could not initialize XMS Driver!");
\r
165 ; Get the driver version number
\r
167 call [XMSControl] ; Get XMS Version Number
\r
168 mov [XMSVersionNumber], ax
\r
170 ; Get the amount of free XMS memory
\r
173 mov [XMSLargestBlock], ax
\r
177 //fprintf(stream, "XMS Version number: %d\n", XMSVersionNumber);
\r
178 //fprintf(stream, "Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);
\r
179 printf("XMS Version number: %d\n", XMSVersionNumber);
\r
180 printf("Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);
\r
185 xmsreport(fopen("xms.log", "w"));
\r