⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dpmiserv.cpp

📁 在DOS利用Watcom c++的保护模式4G内存
💻 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 + -