home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Panoráma
/
computer_panorama_1997-12-hibas.iso
/
SHARE
/
GRAPH
/
PTC051.ZIP
/
SRC
/
DPMI.H
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-09
|
9KB
|
469 lines
////////////////////
// DPMI interface //
////////////////////
#ifndef __DPMI_H
#define __DPMI_H
#include "lang.h"
#include "misc.h"
#include "config.h"
#ifdef __DPMI__
#include <dos.h>
#include "far.h"
#include <string.h>
#ifdef __DJGPP__
#include <dpmi.h>
#endif
// DPMI registers
#pragma pack(1)
struct DPMIREGS
{
uint edi PACKED;
uint esi PACKED;
uint ebp PACKED;
uint reserved PACKED;
uint ebx PACKED;
uint edx PACKED;
uint ecx PACKED;
uint eax PACKED;
ushort flags PACKED;
ushort es PACKED;
ushort ds PACKED;
ushort fs PACKED;
ushort gs PACKED;
ushort ip PACKED;
ushort cs PACKED;
ushort sp PACKED;
ushort ss PACKED;
};
#pragma pack()
class DPMI
{
public:
// DPMI info
#pragma pack(1)
struct INFO
{
uchar major PACKED;
uchar minor PACKED;
ushort flags PACKED;
uchar processor PACKED;
uchar masterPIC PACKED;
uchar slavePIC PACKED;
};
#pragma pack()
// setup
inline DPMI();
inline ~DPMI();
// high level dpmi interface
inline int GetDosMemory(ushort *segment,ushort *selector,int bytes=4096);
// low level dpmi interface
inline static int GetVersion(INFO *version);
inline static int AllocateSelector(ushort *selector);
inline static int FreeSelector(ushort selector);
inline static int SegmentToSelector(ushort segment,ushort *selector);
inline static int GetSelectorBase(ushort selector,uint *base);
inline static int SetSelectorBase(ushort selector,uint base);
inline static int SetSelectorLimit(ushort selector,uint limit);
inline static int SetSelectorRights(ushort selector,ushort rights);
inline static int AllocateDosMemory(ushort *segment,ushort *selector,uint bytes);
inline static int FreeDosMemory(ushort selector);
inline static int ResizeDosMemory(ushort selector,uint bytes);
inline static int MapPhysicalAddress(uint physical,uint size,uint *linear);
inline static int FreePhysicalMapping(uint linear);
inline static int int86(uchar interrupt_no,DPMIREGS *in,DPMIREGS *out);
// status
inline int ok();
private:
// static dos memory
static int InitDosMemory(int bytes);
static void CloseDosMemory();
static int DosMemoryCount;
static ushort DosMemorySegment;
static ushort DosMemorySelector;
static uint DosMemorySize;
// status
int Status;
};
// WHAT TO DO WITH THIS? -- ????
// map a realmode pointer into flat address space
#define DPMI_MapRealPointer(p) (void*)((((uint)(p)>>12)&0xFFFF0)+((p)&0xFFFF))
inline DPMI::DPMI()
{
// initialize dos memory
if (!InitDosMemory(4096)) Status=0;
else Status=1;
}
inline DPMI::~DPMI()
{
// close dos memory
CloseDosMemory();
}
inline int DPMI::GetDosMemory(ushort *segment,ushort *selector,int size)
{
if (size>DosMemorySize)
{
// resize static block?
return 0;
}
// return static dos memory block
*segment=DosMemorySegment;
*selector=DosMemorySelector;
return 1;
}
inline int DPMI::GetVersion(DPMI::INFO *version)
{
#ifdef __DJGPP__
if (__dpmi_get_version((__dpmi_version_ret*)version)!=-1) return 1;
else return 0;
#else
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=0x400;
::int386(0x31,®s,®s);
version->major=regs.h.ah;
version->minor=regs.h.al;
version->flags=regs.w.bx;
version->processor=regs.h.cl;
version->masterPIC=regs.h.dh;
version->slavePIC=regs.h.dl;
return !regs.w.cflag;
#endif
}
inline int DPMI::AllocateSelector(ushort *selector)
{
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=0;
regs.w.cx=1;
::int386(0x31,®s,®s);
*selector=regs.w.ax;
return !regs.w.cflag;
}
inline int DPMI::FreeSelector(ushort selector)
{
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=1;
regs.w.bx=selector;
::int386(0x31,®s,®s);
return !regs.w.cflag;
}
inline int DPMI::SegmentToSelector(ushort segment,ushort *selector)
{
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=2;
regs.w.bx=segment;
::int386(0x31,®s,®s);
*selector=regs.w.ax;
return !regs.w.cflag;
}
inline int DPMI::GetSelectorBase(ushort selector,uint *base)
{
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=6;
regs.w.bx=selector;
::int386(0x31,®s,®s);
*base=((uint)regs.w.cx<<16)+regs.w.dx;
return !regs.w.cflag;
}
inline int DPMI::SetSelectorBase(ushort selector,uint base)
{
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=7;
regs.w.bx=selector;
regs.w.cx=base >> 16;
regs.w.dx=base & 0xffff;
::int386(0x31,®s,®s);
return !regs.w.cflag;
}
inline int DPMI::SetSelectorLimit(ushort selector,uint limit)
{
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=8;
regs.w.bx=selector;
regs.w.cx=limit >> 16;
regs.w.dx=limit & 0xffff;
::int386(0x31,®s,®s);
return !regs.w.cflag;
}
inline int DPMI::SetSelectorRights(ushort selector,ushort rights)
{
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=9;
regs.w.bx=selector;
regs.w.cx=rights;
::int386(0x31,®s,®s);
return !regs.w.cflag;
}
inline int DPMI::AllocateDosMemory(ushort *segment,ushort *selector,uint bytes)
{
/*
#ifdef __DJGPP__
int sel;
if (__dpmi_allocate_dos_memory((bytes+16)>>4,&sel)!=-1)
{
*selector=sel;
segment=
return 1;
}
else return 0;
#else
*/
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=0x100;
regs.w.bx=(bytes+16)>>4;
::int386(0x31,®s,®s);
if (regs.w.cflag==0)
{
*segment=regs.w.ax;
*selector=regs.w.dx;
return 1;
}
else return 0;
//#endif
}
inline int DPMI::FreeDosMemory(ushort selector)
{
#ifdef __DJGPP__
if (__dpmi_free_dos_memory(selector)!=-1) return 1;
else return 0;
#else
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=0x101;
regs.w.dx=selector;
::int386(0x31,®s,®s);
return !regs.w.cflag;
#endif
}
inline int DPMI::ResizeDosMemory(ushort selector,uint bytes)
{
#ifdef __DJGPP__
if (__dpmi_resize_dos_memory(selector,(bytes+16)>>4,NULL)!=-1) return 1;
else return 0;
#else
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=0x102;
regs.w.bx=selector;
regs.w.dx=(bytes+16)>>4;
::int386(0x31,®s,®s);
return !regs.w.cflag;
#endif
}
inline int DPMI::MapPhysicalAddress(uint physical,uint size,uint *linear)
{
#ifdef __DJGPP__
__dpmi_meminfo info;
info.size=size;
info.address=physical;
if (__dpmi_physical_address_mapping(&info)!=-1)
{
*linear=info.address;
return 1;
}
else
{
*linear=NULL;
return 0;
}
#else
REGS regs;
memset(®s,0,sizeof(regs));
regs.w.ax=0x800;
regs.w.bx=physical >> 16;
regs.w.cx=physical & 0xffff;
regs.w.si=size >> 16;
regs.w.di=size & 0xffff;
::int386(0x31,®s,®s);
if (regs.w.cflag==0)
{
*linear=((uint)regs.w.bx<<16) + regs.w.cx;
return 1;
}
else
{
*linear=NULL;
return 0;
}
#endif
}
inline int DPMI::FreePhysicalMapping(uint linear)
{
#ifdef __DJGPP__
__dpmi_meminfo info;
info.size=0;
info.address=linear;
if (__dpmi_free_physical_address_mapping(&i