#include <i86.h>
#include  "dpmi.h"
#include "complex.h"
#include "screen.h"

//+-------------------------------------------------------------------+
//| dpmi_map_physical                                                 |
//| (map physical address to far pointer)                             |
//+-------------------------------------------------------------------+
int dpmi_map_physical( unsigned long physical_address, unsigned long limit, unsigned long *mapp_address)
{
 union REGS pregs;

 eprintf(GRAY_,"adr req = %x (%x)",physical_address,limit);

 pregs.w.cx = physical_address;
 pregs.w.bx = physical_address>>16;
 pregs.w.di = limit;
 pregs.w.si = limit>>16;
 pregs.x.eax = DPMI_MAP_FIZ;
 int386( DPMI_INT, &pregs, &pregs);
 if(pregs.x.cflag) return(-1);
 *(unsigned short *)mapp_address=pregs.w.bx; *mapp_address = *mapp_address<<16;
 *(unsigned short *)mapp_address=pregs.w.cx;
 eprintf(GRAY_,"adr map = %x",*mapp_address);
 return(0);
}

//+-------------------------------------------------------------------+
//| dpmi_free_map_physical                                            |
//| (Free map physical address to far pointer)                        |
//+-------------------------------------------------------------------+
int dpmi_free_map_physical(unsigned long physical_address)
{
 union REGS pregs;

 pregs.x.ecx = 0xFFFF&physical_address;
 pregs.x.ebx = 0xFFFF&(physical_address>>16);
 pregs.x.eax = DPMI_FREE_MAP;
 int386( DPMI_INT, &pregs, &pregs);
 if(pregs.x.cflag) return(-1);
 return(0);
}

//+-------------------------------------------------------------------+
//| dpmi_setvect                                                      |
//| (SET PROTECTED MODE INTERRUPT VECTOR)                             |
//+-------------------------------------------------------------------+
int dpmi_setvect(char irq,_dpmi_paddr *addr)
{
 union REGS pregs;

 pregs.w.ax=DPMI_SET_VECT;
 pregs.h.bl=irq;
 pregs.w.cx=addr->selector;
 pregs.x.edx=addr->offset32;
 int386( DPMI_INT, &pregs, &pregs);
 if(pregs.x.cflag) return(-1);
 return(0);
}

//+-------------------------------------------------------------------+
//| dpmi_getvect                                                      |
//| (GET PROTECTED MODE INTERRUPT VECTOR)                             |
//+-------------------------------------------------------------------+
int dpmi_getvect(char irq,_dpmi_paddr *addr)
{
 union REGS pregs;

 pregs.x.eax=DPMI_GET_VECT;
 pregs.x.ebx=irq;
 int386( DPMI_INT, &pregs, &pregs);
 if(pregs.x.cflag) return(-1);
 addr->selector=pregs.x.ecx;
 addr->offset32=pregs.x.edx;
 return(0);
}

//+-------------------------------------------------------------------+
//| dpmi_dos_allc                                                     |
//| (ALLOCATE DOS MEMORY BLOCK)                                       |
//+-------------------------------------------------------------------+
int dpmi_dos_allc(unsigned short bufsize,unsigned short *selector, unsigned short *real_segm)
{
 union REGS pregs;

 pregs.x.eax=DPMI_ALLOC_DOS_MEM;
 pregs.w.bx=bufsize;
 int386( DPMI_INT, &pregs, &pregs);
 if(pregs.x.cflag) return(-1);
 *real_segm = pregs.w.ax;
 *selector  = pregs.w.dx;
 return(0);
}

//+-------------------------------------------------------------------+
//| dpmi_dos_free                                                     |
//| (FREE DOS MEMORY BLOCK)                                           |
//+-------------------------------------------------------------------+
int dpmi_dos_free(unsigned short selector)
{
 union REGS pregs;

 pregs.x.eax=DPMI_FREE_DOS_MEM;
 pregs.w.dx=selector;
 int386( DPMI_INT, &pregs, &pregs);
 if(pregs.x.cflag) return(-1);
 return(0);
}

//+-------------------------------------------------------------------+
//| dpmi_RM_proc_retf                                                 |
//| (CALL REAL MODE PROCEDURE WITH FAR RETURN FRAME)                  |
//+-------------------------------------------------------------------+
int dpmi_RM_proc_retf(__dpmi_regs *_regs)
{
 union REGS pregs;

 pregs.x.eax=DPMI_RM_PROC_RETF;
 pregs.x.edi=_regs;
 pregs.x.ecx=pregs.x.ebx=0;
 int386( DPMI_INT, &pregs, &pregs);
 if(pregs.x.cflag) return(-1);
 return(0);
}