/* 
DPMITELL.C

C:\WINDOC\EXAMPLES>dpmitell
DPMI version number........................0.90
DOS mode...................................Virtual 8086
Virtual memory.............................Yes
Master PIC base interrupt..................08
Slave PIC base interrupt...................70
Processor..................................80386
Size of the linear address space...........11772K bytes
Amount of free linear address space........6916K bytes
Size of largest free linear block..........6616K bytes
Size of the virtual memory swap file.......11772K bytes
Total amount of physical memory............3884K bytes
Amount of free physical memory.............1788K bytes
*/ 
 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h>
#include <dos.h> 
#include <pharlap.h>
#include <pldos32.h>	// prototypes for _dos_ routines in DOS32.LIB

#ifdef __WATCOMC__
#define _REGS REGS
#define _int86 int386
// Names of regs in _REGS union are nonstandard
#define ax              eax 
#define bx              ebx 
#define di              edi 
#endif
 
#define CLEAR(x)    memset(&x, 0, sizeof(x)) 
 
typedef struct 
{ 
    unsigned dpmi_largest;      /* Largest available free block */ 
    unsigned dpmi_unlock_max;   /* Max. unlock page count */ 
    unsigned dpmi_lock_max;     /* Max. lock page count */ 
    unsigned dpmi_lin_size;     /* Size in bytes of linear address space */ 
    unsigned dpmi_unlock_count; /* Number of unlocked pages */ 
    unsigned dpmi_fpage_count;  /* Number of free pages */ 
    unsigned dpmi_ppage_count;  /* Number of physical pages */ 
    unsigned dpmi_lin_free;     /* Free linear address page count */ 
    unsigned dpmi_swapf_size;   /* Size of swap file in pages */ 
    unsigned dpmi_rsrv[3]; 
} DPMI_FREEMEM;  
 
int dpmi_present(void) 
{ 
    CONFIG_INF config; 
    UCHAR vmmname[256]; 
    _dx_config_inf(&config, vmmname); 
    return config.c_dpmif; 
} 
 
void dpmi_version(unsigned *pmaj, unsigned *pmin,  
                  unsigned *pflags, unsigned *pproc,  
                  unsigned *ppicm, unsigned *ppics) 
{ 
    union _REGS r; 
    CLEAR(r); 
    r.x.ax = 0x0400; 
    _int86(0x31, &r, &r); 
    *pmaj = (unsigned) r.h.ah; 
    *pmin = (unsigned) r.h.al; 
    *pflags = (unsigned) r.x.bx; 
    *pproc = (unsigned) r.h.cl; 
    *ppicm = (unsigned) r.h.dh; 
    *ppics = (unsigned) r.h.dl; 
} 
 
void dpmi_getmeminfo(DPMI_FREEMEM *pinfo) 
{ 
    union _REGS r; 
    CLEAR(r); 
    r.x.di = (unsigned) pinfo; 
    r.x.ax = 0x0500; 
    _int86(0x31, &r, &r); 
} 
 
void dpmi_info(void) 
{ 
    DPMI_FREEMEM info; 
    unsigned major, minor, mpic, spic, proc, flags; 
 
    dpmi_version(&major, &minor, &flags, &proc, &mpic, &spic); 
    printf("DPMI version number........................<<%d.%d>>\n", 
           major, minor); 
    printf("DOS mode...................................<<%s>>\n", 
           (flags & 0x2) ? "Real" : "Virtual 8086"); 
    printf("Virtual memory.............................<<%s>>\n", 
           (flags & 0x4) ? "Yes" : "No"); 
    printf("Master PIC base interrupt..................<<%02X>>\n", 
           mpic); 
    printf("Slave PIC base interrupt...................<<%02X>>\n", 
           spic); 
    printf("Processor..................................<<80%d86>>\n", 
           proc); 
 
    dpmi_getmeminfo(&info); 
    printf("Size of the linear address space...........<<%ldK>> bytes\n", 
           (info.dpmi_lin_size * 4096) / 1024); 
    printf("Amount of free linear address space........<<%ldK>> bytes\n", 
           (info.dpmi_lin_free * 4096) / 1024); 
    printf("Size of largest free linear block..........<<%ldK>> bytes\n", 
           info.dpmi_largest / 1024); 
    printf("Size of the virtual memory swap file.......<<%ldK>> bytes\n", 
           (info.dpmi_swapf_size * 4096) / 1024); 
    printf("Total amount of physical memory............<<%ldK>> bytes\n", 
           (info.dpmi_ppage_count * 4096) / 1024); 
    printf("Amount of free physical memory.............<<%ldK>> bytes\n", 
           (info.dpmi_fpage_count * 4096) / 1024); 
} 
 
main() 
{ 
    if (dpmi_present()) 
        dpmi_info(); 
    else 
        puts("This program requires DPMI"); 
    return 0; 
} 
