-/* This file implements rudimentary XMS memory handling.
- * Documentation on the XMS API was found on http://www.qzx.com/pc-gpe/xms30.txt
- */
-
-#include "src\lib\xms.h"
-
-/* Set up the XMS driver, returns 0 on success and non-zero on failure */
-static int initxms(void)
-{
- char XMSStatus = 0;
-
- if ( XMSControl == 0 )
- {
- __asm {
- ; Is an XMS driver installed?
- mov ax,4300h
- int 2Fh
- mov [XMSStatus], al
- }
-
- if ( XMSStatus == 0x80 )
- {
- __asm {
- ; Get the address of the driver control function
- mov ax,4310h
- int 2Fh
- mov word ptr [XMSControl] ,bx
- mov word ptr [XMSControl+2],es
- }
- }
- }
-
- return ( XMSControl == 0 );
-}
-
-/* Allocate a slab of memory from XMS */
-void huge * xmsmalloc(long unsigned int size)
-{
- unsigned int kB;
- unsigned int XMSStatus = 0;
- unsigned int XMSHandle = 0;
- void huge * XMSPointer = NULL;
- int n;
-
- /* If we can not initialize XMS, the allocation fails */
- if ( initxms() )
- return NULL;
-
- /* It is not possible to allocate more kilobytes than a 16-bit register can hold :-) */
- if ( size / 1024 > UINT_MAX )
- return NULL;
-
- /* Get the next free entry in the handle <-> pointer mapping */
- for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )
- {
- if ( allocMapXMS[n].XMSPointer == NULL )
- break;
- }
-
- if ( n == MAX_XMS_ALLOCATIONS )
- return NULL;
-
- kB = size / 1024 + (size % 1024 > 0);
-
- __asm {
- ; Allocate [kB] kilobytes of XMS memory
- mov ah, 09h
- mov dx, [kB]
- call [XMSControl]
- mov [XMSStatus], ax
- mov [XMSHandle], dx
- }
-
- /* Check if XMS allocation failed */
- if ( XMSStatus == 0)
- return NULL;
-
- __asm {
- ; Convert XMS handle to normal pointer
- mov ah, 0Ch
- mov dx, [XMSHandle]
- call [XMSControl]
- mov [XMSStatus], ax
-
- mov word ptr [XMSPointer], bx
- mov word ptr [XMSPointer+2],dx
- }
-
- if ( XMSStatus == 0 )
- {
- /* Lock failed, deallocate the handle */
- __asm {
- ; Free XMS handle
- mov ah, 0Ah
- mov dx, [XMSHandle]
- call [XMSControl]
-
- ; Return value is not really interesting
- ; mov [XMSStatus], ax
- }
- return NULL;
- }
-
- /* Create an entry in the handle <-> pointer mapping */
- allocMapXMS[n].XMSHandle = XMSHandle;
- allocMapXMS[n].XMSPointer = XMSPointer;
-
- return XMSPointer;
-}
-
-/* Free a pointer allocated with xmsalloc */
-void xmsfree(void huge * XMSPointer)
-{
- int n;
-
- if ( XMSPointer == NULL )
- return;
-
- if ( initxms() )
- return;
-
- for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )
- {
- if ( allocMapXMS[n].XMSPointer == XMSPointer )
- {
- int XMSHandle = allocMapXMS[n].XMSHandle;
-
- __asm {
- ; Unlock handle so we can free the memory block
- mov ah, 0Dh
- mov dx, [XMSHandle]
- call [XMSControl]
-
- ; Free XMS memory
- mov ah, 0Ah
- mov dx, [XMSHandle]
- call [XMSControl]
-
- ; Return value ignored
- }
-
- /* Clear handle <-> pointer map entry so it can be reused */
- allocMapXMS[n].XMSHandle = 0;
- allocMapXMS[n].XMSPointer = NULL;
-
- return;
- }
- }
-}
-
-/* Write a memory report for debugging purposes */
-void xmsreport(void/*FILE * stream*/)
-{
- int XMSVersionNumber = 0;
- unsigned int XMSLargestBlock = 0;
- unsigned int XMSTotal = 0;
-
- if ( initxms() )
- {
- puts("Could not initialize XMS Driver!");
- return;
- }
-
- __asm {
- ; Get the driver version number
- mov ah,00h
- call [XMSControl] ; Get XMS Version Number
- mov [XMSVersionNumber], ax
-
- ; Get the amount of free XMS memory
- mov ah, 08h
- call [XMSControl]
- mov [XMSLargestBlock], ax
- mov [XMSTotal], dx
- }
-
- //fprintf(stream, "XMS Version number: %d\n", XMSVersionNumber);
- //fprintf(stream, "Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);
- printf("XMS Version number: %d\n", XMSVersionNumber);
- printf("Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);
-}
-
-/*int main()
-{
- xmsreport(fopen("xms.log", "w"));
- return 0;
-}*/
+/* This file implements rudimentary XMS memory handling.\r
+ * Documentation on the XMS API was found on http://www.qzx.com/pc-gpe/xms30.txt\r
+ */\r
+\r
+#include "src\lib\xms.h"\r
+\r
+/* Set up the XMS driver, returns 0 on success and non-zero on failure */\r
+static int initxms(void)\r
+{\r
+ char XMSStatus = 0;\r
+\r
+ if ( XMSControl == 0 )\r
+ {\r
+ __asm {\r
+ ; Is an XMS driver installed?\r
+ mov ax,4300h\r
+ int 2Fh\r
+ mov [XMSStatus], al\r
+ }\r
+\r
+ if ( XMSStatus == 0x80 )\r
+ {\r
+ __asm {\r
+ ; Get the address of the driver control function\r
+ mov ax,4310h\r
+ int 2Fh\r
+ mov word ptr [XMSControl] ,bx\r
+ mov word ptr [XMSControl+2],es\r
+ }\r
+ }\r
+ }\r
+\r
+ return ( XMSControl == 0 );\r
+}\r
+\r
+/* Allocate a slab of memory from XMS */\r
+void huge * xmsmalloc(long unsigned int size)\r
+{\r
+ unsigned int kB;\r
+ unsigned int XMSStatus = 0;\r
+ unsigned int XMSHandle = 0;\r
+ void huge * XMSPointer = NULL;\r
+ int n;\r
+\r
+ /* If we can not initialize XMS, the allocation fails */\r
+ if ( initxms() )\r
+ return NULL;\r
+\r
+ /* It is not possible to allocate more kilobytes than a 16-bit register can hold :-) */\r
+ if ( size / 1024 > UINT_MAX )\r
+ return NULL;\r
+\r
+ /* Get the next free entry in the handle <-> pointer mapping */\r
+ for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )\r
+ {\r
+ if ( allocMapXMS[n].XMSPointer == NULL )\r
+ break;\r
+ }\r
+\r
+ if ( n == MAX_XMS_ALLOCATIONS )\r
+ return NULL;\r
+\r
+ kB = size / 1024 + (size % 1024 > 0);\r
+\r
+ __asm {\r
+ ; Allocate [kB] kilobytes of XMS memory\r
+ mov ah, 09h\r
+ mov dx, [kB]\r
+ call [XMSControl]\r
+ mov [XMSStatus], ax\r
+ mov [XMSHandle], dx\r
+ }\r
+\r
+ /* Check if XMS allocation failed */\r
+ if ( XMSStatus == 0)\r
+ return NULL;\r
+\r
+ __asm {\r
+ ; Convert XMS handle to normal pointer\r
+ mov ah, 0Ch\r
+ mov dx, [XMSHandle]\r
+ call [XMSControl]\r
+ mov [XMSStatus], ax\r
+\r
+ mov word ptr [XMSPointer], bx\r
+ mov word ptr [XMSPointer+2],dx\r
+ }\r
+\r
+ if ( XMSStatus == 0 )\r
+ {\r
+ /* Lock failed, deallocate the handle */\r
+ __asm {\r
+ ; Free XMS handle\r
+ mov ah, 0Ah\r
+ mov dx, [XMSHandle]\r
+ call [XMSControl]\r
+\r
+ ; Return value is not really interesting \r
+ ; mov [XMSStatus], ax\r
+ }\r
+ return NULL;\r
+ }\r
+\r
+ /* Create an entry in the handle <-> pointer mapping */\r
+ allocMapXMS[n].XMSHandle = XMSHandle;\r
+ allocMapXMS[n].XMSPointer = XMSPointer;\r
+\r
+ return XMSPointer;\r
+}\r
+\r
+/* Free a pointer allocated with xmsalloc */\r
+void xmsfree(void huge * XMSPointer)\r
+{\r
+ int n;\r
+\r
+ if ( XMSPointer == NULL )\r
+ return;\r
+\r
+ if ( initxms() )\r
+ return;\r
+\r
+ for ( n = 0; n < MAX_XMS_ALLOCATIONS; n++ )\r
+ {\r
+ if ( allocMapXMS[n].XMSPointer == XMSPointer )\r
+ {\r
+ int XMSHandle = allocMapXMS[n].XMSHandle;\r
+\r
+ __asm {\r
+ ; Unlock handle so we can free the memory block\r
+ mov ah, 0Dh\r
+ mov dx, [XMSHandle]\r
+ call [XMSControl]\r
+\r
+ ; Free XMS memory\r
+ mov ah, 0Ah\r
+ mov dx, [XMSHandle]\r
+ call [XMSControl]\r
+\r
+ ; Return value ignored\r
+ }\r
+\r
+ /* Clear handle <-> pointer map entry so it can be reused */\r
+ allocMapXMS[n].XMSHandle = 0;\r
+ allocMapXMS[n].XMSPointer = NULL;\r
+\r
+ return;\r
+ }\r
+ }\r
+}\r
+\r
+/* Write a memory report for debugging purposes */\r
+void xmsreport(void/*FILE * stream*/)\r
+{\r
+ int XMSVersionNumber = 0;\r
+ unsigned int XMSLargestBlock = 0;\r
+ unsigned int XMSTotal = 0;\r
+\r
+ if ( initxms() )\r
+ {\r
+ puts("Could not initialize XMS Driver!");\r
+ return;\r
+ }\r
+\r
+ __asm {\r
+ ; Get the driver version number\r
+ mov ah,00h\r
+ call [XMSControl] ; Get XMS Version Number\r
+ mov [XMSVersionNumber], ax\r
+\r
+ ; Get the amount of free XMS memory\r
+ mov ah, 08h\r
+ call [XMSControl]\r
+ mov [XMSLargestBlock], ax\r
+ mov [XMSTotal], dx\r
+ }\r
+\r
+ //fprintf(stream, "XMS Version number: %d\n", XMSVersionNumber);\r
+ //fprintf(stream, "Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);\r
+ printf("XMS Version number: %d\n", XMSVersionNumber);\r
+ printf("Largest available block: %d kB (%d kB total)\n", XMSLargestBlock, XMSTotal);\r
+}\r
+\r
+/*int main()\r
+{\r
+ xmsreport(fopen("xms.log", "w"));\r
+ return 0;\r
+}*/\r