📄 dpmiserv.cpp
字号:
//#include "os.h"
//#ifdef OS_DOS
#include <i86.h>
#include <mem.h>
#include <stdlib.h>
#include <stdio.h>
#include "dpmiserv.h"
void FatalError(char *msg)
{
fprintf(stderr,"%s\n", msg);
exit(1);
}
/*------------------------- DPMI interface routines -----------------------*/
void DPMI_allocRealSeg(int size,int *sel,int *r_seg)
/****************************************************************************
* Function: DPMI_allocRealSeg
* Parameters: size - Size of memory block to allocate
* sel - Place to return protected mode selector
* r_seg - Place to return real mode segment
* Description: Allocates a block of real mode memory using DPMI services.
* This routine returns both a protected mode selector and
* real mode segment for accessing the memory block.
****************************************************************************/
{
union REGS r;
r.w.ax = 0x100; /* DPMI allocate DOS memory */
r.w.bx = (size + 0xF) >> 4; /* number of paragraphs */
int386(0x31, &r, &r);
if (r.w.cflag)
FatalError("DPMI_allocRealSeg failed!");
*sel = r.w.dx; /* Protected mode selector */
*r_seg = r.w.ax; /* Real mode segment */
}
void DPMI_freeRealSeg(unsigned sel)
/****************************************************************************
* Function: DPMI_allocRealSeg
* Parameters: sel - Protected mode selector of block to free
* Description: Frees a block of real mode memory.
****************************************************************************/
{
union REGS r;
r.w.ax = 0x101; /* DPMI free DOS memory */
r.w.dx = sel; /* DX := selector from 0x100 */
int386(0x31, &r, &r);
}
typedef struct {
long edi;
long esi;
long ebp;
long reserved;
long ebx;
long edx;
long ecx;
long eax;
short flags;
short es,ds,fs,gs,ip,cs,sp,ss;
} _RMREGS;
#define IN(reg) rmregs.e##reg = in->x.reg
#define OUT(reg) out->x.reg = rmregs.e##reg
int DPMI_int86(int intno, RMREGS *in, RMREGS *out)
/****************************************************************************
* Function: DPMI_int86
* Parameters: intno - Interrupt number to issue
* in - Pointer to structure for input registers
* out - Pointer to structure for output registers
* Returns: Value returned by interrupt in AX
* Description: Issues a real mode interrupt using DPMI services.
****************************************************************************/
{
_RMREGS rmregs;
union REGS r;
struct SREGS sr;
memset(&rmregs, 0, sizeof(rmregs));
IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
segread(&sr);
r.w.ax = 0x300; /* DPMI issue real interrupt */
r.h.bl = intno;
r.h.bh = 0;
r.w.cx = 0;
sr.es = sr.ds;
r.x.edi = (unsigned)&rmregs;
int386x(0x31, &r, &r, &sr); /* Issue the interrupt */
OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
out->x.cflag = rmregs.flags & 0x1;
return out->x.ax;
}
int DPMI_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs)
/****************************************************************************
* Function: DPMI_int86
* Parameters: intno - Interrupt number to issue
* in - Pointer to structure for input registers
* out - Pointer to structure for output registers
* sregs - Values to load into segment registers
* Returns: Value returned by interrupt in AX
* Description: Issues a real mode interrupt using DPMI services.
****************************************************************************/
{
_RMREGS rmregs;
union REGS r;
struct SREGS sr;
memset(&rmregs, 0, sizeof(rmregs));
IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
rmregs.es = sregs->es;
rmregs.ds = sregs->ds;
segread(&sr);
r.w.ax = 0x300; /* DPMI issue real interrupt */
r.h.bl = intno;
r.h.bh = 0;
r.w.cx = 0;
sr.es = sr.ds;
r.x.edi = (unsigned)&rmregs;
int386x(0x31, &r, &r, &sr); /* Issue the interrupt */
OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
sregs->es = rmregs.es;
sregs->cs = rmregs.cs;
sregs->ss = rmregs.ss;
sregs->ds = rmregs.ds;
out->x.cflag = rmregs.flags & 0x1;
return out->x.ax;
}
int DPMI_allocSelector(void)
/****************************************************************************
* Function: DPMI_allocSelector
* Returns: Newly allocated protected mode selector
* Description: Allocates a new protected mode selector using DPMI
* services. This selector has a base address and limit of 0.
****************************************************************************/
{
int sel;
union REGS r;
r.w.ax = 0; /* DPMI allocate selector */
r.w.cx = 1; /* Allocate a single selector */
int386(0x31, &r, &r);
if (r.x.cflag)
FatalError("DPMI_allocSelector() failed!");
sel = r.w.ax;
r.w.ax = 9; /* DPMI set access rights */
r.w.bx = sel;
r.w.cx = 0x8092; /* 32 bit page granular */
int386(0x31, &r, &r);
return sel;
}
long DPMI_mapPhysicalToLinear(long physAddr,long limit)
/****************************************************************************
* Function: DPMI_mapPhysicalToLinear
* Parameters: physAddr - Physical memory address to map
* limit - Length-1 of physical memory region to map
* Returns: Starting linear address for mapped memory
* Description: Maps a section of physical memory into the linear address
* space of a process using DPMI calls. Note that this linear
* address cannot be used directly, but must be used as the
* base address for a selector.
****************************************************************************/
{
union REGS r;
r.w.ax = 0x800; /* DPMI map physical to linear */
r.w.bx = physAddr >> 16;
r.w.cx = physAddr & 0xFFFF;
r.w.si = limit >> 16;
r.w.di = limit & 0xFFFF;
int386(0x31, &r, &r);
if (r.x.cflag)
FatalError("DPMI_mapPhysicalToLinear() failed!");
return ((long)r.w.bx << 16) + r.w.cx;
}
void DPMI_setSelectorBase(int sel,long linAddr)
/****************************************************************************
* Function: DPMI_setSelectorBase
* Parameters: sel - Selector to change base address for
* linAddr - Linear address used for new base address
* Description: Sets the base address for the specified selector.
****************************************************************************/
{
union REGS r;
r.w.ax = 7; /* DPMI set selector base address */
r.w.bx = sel;
r.w.cx = linAddr >> 16;
r.w.dx = linAddr & 0xFFFF;
int386(0x31, &r, &r);
if (r.x.cflag)
FatalError("DPMI_setSelectorBase() failed!");
}
void DPMI_setSelectorLimit(int sel,long limit)
/****************************************************************************
* Function: DPMI_setSelectorLimit
* Parameters: sel - Selector to change limit for
* limit - Limit-1 for the selector
* Description: Sets the memory limit for the specified selector.
****************************************************************************/
{
union REGS r;
r.w.ax = 8; /* DPMI set selector limit */
r.w.bx = sel;
r.w.cx = limit >> 16;
r.w.dx = limit & 0xFFFF;
int386(0x31, &r, &r);
if (r.x.cflag)
FatalError("DPMI_setSelectorLimit() failed!");
}
//#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -