/* This file is DPMIUTIL.C
**
**	- utils for dpmi
**
** Copyright (c) Rainer Schnitker 91,92,93
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DPMI.H"

int FreeManyLDT(WORD sel, WORD n)
{
    WORD i, inc;

    inc = SelInc();
    for (i = 1; i <= n; i++) {
	if (FreeLDT(sel))
	    return -1;
	sel += inc;
    }
    return 0;
}

void PrintFreeMemInfo(NPFREEMEMINFO fm)
{
    printf("Largest available block           : %lu Bytes = %lu KB\n",
	   fm->LargestFree, fm->LargestFree >> 10);
    printf("Number free pages                 : %8lu = %8lu KB\n"
	   ,fm->MaxUnlockedPages, fm->MaxUnlockedPages * 4);
    printf("Number free pages to lock         : %8lu = %8lu KB\n"
	   ,fm->MaxLockedPages, fm->MaxLockedPages * 4);
    printf("Number pages of linear addr space : %8lu = %8lu KB\n"
	   ,fm->AddressSpacePages, fm->AddressSpacePages * 4);
    printf("Number pages not locked           : %8lu = %8lu KB\n"
	   ,fm->UnlockedPages, fm->UnlockedPages * 4);
    printf("Number pages not used             : %8lu = %8lu KB\n"
	   ,fm->UnusedPages, fm->UnusedPages * 4);
    printf("Number pages managed by the Dpmi  : %8lu = %8lu KB\n"
	   ,fm->PhysicalPages, fm->PhysicalPages * 4);
    printf("Number pages free addr space      : %8lu = %8lu KB\n"
	   ,fm->FreeAddressSpacePages, fm->FreeAddressSpacePages * 4);

    if (fm->PagingFilePages <= 0xFFFFFL)
	printf("Number pages in swapfile          : %8lu = %8lu KB\n"
	       ,fm->PagingFilePages, fm->PagingFilePages * 4);
    else
	printf("DPMI host paging partition        : %lu Bytes = %lu MB\n"
	       ,fm->PagingFilePages, fm->PagingFilePages >> 20);
}

void PrintDescriptor(LPDESCRIPTOR d)
{
    BYTE flag;

    if (!(d->access & PRESENT_BIT)) {
	printf("Not Present\n");
	return;
    }
    if (d->access & SEGMENT_BIT)/* code or data selector */
	printf("Base=%02X%02X%04X Limit=%01X%04X %s DPL=%u %s %s %s %s\n",
	       d->base_hi, d->base_mi, d->base_lo,
	       d->lim_hi & LIMIT_HI_MASK, d->lim_lo,
	       (d->lim_hi & GRANULAR_BIT) ? "Pages" : "Bytes",
	       (d->access & DPL_MASK) >> 5,
	       (d->lim_hi & DEFAULT_BIT) ? "32bit" : "16bit",
	       (d->access & CODE_BIT) ?
	       (d->access & CONFIRMING_BIT) ? "CONF" : "CODE" :
	       (d->access & EXPAND_BIT) ? "EXPD" : "DATA",
	       (d->access & WRITE_BIT) ?
	       (d->access & CODE_BIT) ? "R" : "W" : "-",
	       (d->access & ACCESS_BIT) ? "ACC" : " ");

    else {			/* system selector */
	flag = d->access & (BYTE) 7;
	switch (flag) {
	case 0:
	    break;
	case 1:
	    printf("TSS%s ", (d->access & 8) ? "386" : "286");
	    break;
	case 2:
	    printf("LDT ");
	    break;
	case 3:
	    printf("BUSYTSS%s ", (d->access & 8) ? "386" : "286");
	    break;
	case 4:
	    printf("CALLGATE%s ", (d->access & 8) ? "386" : "286");
	    break;
	case 5:
	    printf("TASKGATE ");
	    break;
	case 6:
	    printf("INT_GATE%s ", (d->access & 8) ? "386" : "286");
	    break;
	case 7:
	    printf("TRAPGATE%s ", (d->access & 8) ? "386" : "286");
	    break;
	}


	if (flag <= 3) {
	    printf("Base=%02X%02X%04X Limit=%01X%04X DPL=%u\n",
		   d->base_hi, d->base_mi, d->base_lo,
		   d->lim_hi & LIMIT_HI_MASK, d->lim_lo,
		   (d->access & DPL_MASK) >> 5);
	} else {
	    printf("Sel=%04X Offset=%02X%02X%04X DPL=%u\n",
		   d->base_lo,
		   d->base_hi, d->lim_hi, d->lim_lo,
		   (d->access & DPL_MASK) >> 5);
	}
    }				/* else system descriptor */
}
