/**********************************************************************
  An example of new DosAllocMem flag usage

   OBJ_LOCSPECIFIC 0x1000

  allocate memory at requested addr.
***********************************************************************/

#define INCL_DOSMEMMGR   /* Include DOS Memory Management APIs */
#define INCL_DOSERRORS   /* DOS error values                   */
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>

#define OBJ_LOCSPECIFIC 0x1000

void *Allocate(ULONG WantedAddr)
{
    PVOID  MyObject    = (PVOID)WantedAddr; /* Pointer to memory object            */
    ULONG  ulObjSize   = 0;                 /* Size of memory object (in bytes)    */
    APIRET rc          = NO_ERROR;          /* Return code                         */

    ulObjSize = 30*1024*1024;               /* Will be rounded to a page boundary - 4096 */

    printf("Trying to allocate block at addr  : 0x%8.8X\n",MyObject);
    rc = DosAllocMem(&MyObject,     /* Pointer to memory object pointer     */
                     ulObjSize,     /* Size of object to be allocated       */
                     PAG_WRITE|OBJ_LOCSPECIFIC );   /* Allocate memory as read/writeable    */

    if (rc != NO_ERROR)
    {
        printf("DosAllocMem error:  return code = %u\n",rc);
        return 0;
    } else
    {
        printf("DosAllocMem() allocated block addr: 0x%8.8X\n",MyObject);
    }
    return MyObject;
}

void Free(void *Addr)
{
    APIRET rc = DosFreeMem(Addr);
    if (rc != NO_ERROR)
    {
        printf("DosFreeMem(0x%8.8x) error: return code = %u\n",Addr, rc);
    }
}

int main(int argc, char *argv[])
{
    void *p1 = Allocate(0x2200),
         *p2 = Allocate(0x220000),
         *p3 = Allocate(0x22000000),
         *p4 = Allocate(0x22000022);   // next page after p3, but it is busy, so call failed

    if (argc>1) _getch();              // make pause to call Theseus ;)

    if (p4) Free(p4);
    if (p3) Free(p3);
    if (p2) Free(p2);
    if (p1) Free(p1);
    return NO_ERROR;
}

