/* -*-C-*-
*******************************************************************************
*
* File:         dpmi.c
* RCS:          $Header: $
* Description:  Simple DPMI interface
* Author:       Darryl Okahata
* Created:      Sun Mar 07 00:16:32 1993
* Modified:     Tue Mar 30 23:21:04 1993 (darrylo@home) darrylo@dosmachine
* Language:     C
* Package:      N/A
* Status:       Experimental (Do Not Distribute)
*
* (C) Copyright 1993, Darryl Okahata, all rights reserved.
*
*******************************************************************************
*/


#include <stdio.h>
#include <string.h>
#include <dos.h>

#include "dpmi.h"

#ifdef DOS_EXTENDER

dpmi_allocate_block(size, block)
int		size;	/* in paragraphs */
DPMIBLOCK	*block;
{
    union REGS		regs;
    struct SREGS	sregs;

    block->segment = 0;
    block->selector = 0;
    memset(&sregs, 0, sizeof(sregs));
    regs.w.ax = 0x0100;
    regs.w.bx = (size >> 4) + 1;
    int386x(DPMI_INTERRUPT, &regs, &regs, &sregs);
    if (regs.w.cflag & 1) {	/* if carry flag is set */
	return (0);
    }
    block->segment = regs.w.ax;
    block->selector = regs.w.dx;
    return (1);
}


dpmi_free_block(block)
DPMIBLOCK	*block;
{
    union REGS		regs;
    struct SREGS	sregs;

    memset(&sregs, 0, sizeof(sregs));
    regs.w.ax = 0x0101;
    regs.w.dx = block->selector;
    int386x(DPMI_INTERRUPT, &regs, &regs, &sregs);
    block->segment = 0;
    block->selector = 0;
    if (regs.w.cflag & 1) {	/* if carry flag is set */
	return (0);
    }
    return (1);
}


dpmi_call_int(intnum, dregs)
int		intnum;
DPMIREGS	*dregs;
{
    union REGS		regs;
    struct SREGS	sregs;

    memset(&regs, 0, sizeof(regs));
    memset(&sregs, 0, sizeof(sregs));
    regs.w.ax = 0x0300;
    regs.h.bl = intnum;
    regs.h.bh = 0;
    regs.w.cx = 0;
    sregs.es = FP_SEG(dregs);
    regs.x.edi = FP_OFF(dregs);
    int386x(DPMI_INTERRUPT, &regs, &regs, &sregs);
    return (!(regs.w.cflag & 1) && !(dregs->flags & 1));
}


dpmi_call_dos(dregs)
DPMIREGS	*dregs;
{
    return (dpmi_call_int(0x21, dregs));
}


void dpmi_get_meminfo(info)
DPMI_MEMINFO		*info;
{
    DPMI_MEMINFO far	*ptr;
    union REGS		regs;
    struct SREGS	sregs;

    ptr = (DPMI_MEMINFO far *) info;
    memset(&regs, 0, sizeof(regs));
    memset(&sregs, 0, sizeof(sregs));
    regs.x.eax = 0x00000500;
    sregs.es = FP_SEG(ptr);
    regs.x.edi = FP_OFF(ptr);
    int386x(DPMI_INTERRUPT, &regs, &regs, &sregs);
}

#endif	/* DOS_EXTENDER */
