home *** CD-ROM | disk | FTP | other *** search
- //=====================================================================
- //
- // dpmish.cpp
- //
- // dos protected mode interface manager class
- //
- // Copyright (c) 1994, Kevin Morgan, All rights reserved.
- //
- // Parts of this were loosely based on routines
- // from Al Williams book: "DOS and Windows Protected Mode"
- //
- //=====================================================================
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <dos.h>
- #include "dpmish.h"
-
-
- //=====================================================================
- //
- // DpmiApplication::fail
- //
- //=====================================================================
- void DpmiApplication::fail(const char *s, ...)
- {
- puts(s);
- dosExit(1);
- }
-
- //===================================================================
- //
- // DpmiApplication::dosExit
- //
- //===================================================================
- void DpmiApplication::dosExit(int retval)
- {
- asm {
- mov ah, 04ch
- mov al, byte ptr retval
- int 21h
- }
- }
-
-
- //===================================================================
- //
- // DpmiApplication::present(void)
- //
- // Call the DPMI Mode Detection function (INT 2fh AX=1686h) to see
- // if we are already running in protected mode under DPMI.
- //
- //===================================================================
- int DpmiApplication::present(void)
- {
- unsigned _ax;
- asm mov ax, 1686h
- asm int 2fh
- asm mov _ax, ax // returns zero if DPMI is present
- return (!_ax); // turn it around so WE return 0 if *not* present
- }
-
-
- //===================================================================
- // DpmiApplication::init(void)
- //
- // Call the DPMI function for Obtaining the Real to Protected Mode Switch
- // Entry Point (INT 2Fh AX=1687h), to determine if DPMI is available
- // and, if so, switch into protected mode by calling the Switch Entry Point.
- // See DPMI 0.9 spec.
- //
- //
- //===================================================================
- int DpmiApplication::init(void)
- {
- void (far *dpmi)();
- static unsigned hostdata_seg;
- unsigned hostdata_para, dpmi_flags;
- asm {
- push si
- push di
- mov ax, 1687h // test for DPMI presence
- int 2fh
- and ax,ax
- jz gotdpmi // AX==0 means DPMI is present
- jmp nodpmi
- }
- gotdpmi:
- asm {
- mov dpmi_flags, bx
- mov hostdata_para, si // save paras for DPMI host private data
- mov word ptr dpmi, di
- mov word ptr dpmi+2, es // save DPMI protected mode switch entry point
- pop di
- pop si
- }
- if (_dos_allocmem(hostdata_para, &hostdata_seg)!=0)
- fail("can't allocate memory");
-
- dpmi_flags &= ~1; // this is a 16-bit protected mode program
-
- // enter protected mode
- asm {
- mov ax, hostdata_seg
- mov es, ax
- mov ax, dpmi_flags
- }
- (*dpmi)();
- asm jc nodpmi // carry set if error
-
- // we should be in protected mode now.
- // Note that segment registers have changed.
-
- return present(); // double check
- nodpmi:
- return 0;
- }
-
-
- //===================================================================
- //
- // DpmiApplication::makeDescriptor
- //
- //===================================================================
- void _far *DpmiApplication::makeDescriptor(unsigned segaddr)
- {
- void _far *p;
- asm {
- mov ax, 0002h
- mov bx, segaddr
- int 31h
- jc dpmierr
- mov word ptr p+2, ax
- mov word ptr p, 0
- }
- return p;
- dpmierr:
- return 0;
- }
-
- //===================================================================
- //
- // DpmiApplication::getVersion
- //
- //===================================================================
- int DpmiApplication::getVersion(int& maj, int& min, int& flags)
- {
- char aMaj, aMin;
- int aFlags;
- asm {
- mov ax, 0400h
- int 31h
- jc nodpmi
- mov aMaj, ah
- mov aMin, al
- mov aFlags, bx
- }
- maj = aMaj;
- min = aMin;
- flags = aFlags;
- return 0;
- nodpmi:
- return 1;
- }
-
- //===================================================================
- //
- // DpmiApplication::getCapabilities
- //
- //===================================================================
- int DpmiApplication::getCapabilities(char _far *buf, int& aFlags)
- {
- int flags;
- asm {
- mov ax, 0401h
- mov di, word ptr buf
- mov ax, word ptr buf+2
- mov es, ax
- int 31h
- jc nodpmi
- mov flags, ax
- }
- aFlags = flags;
- return DPMI_OK;
- nodpmi:
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::allocateMemory
- //
- //===================================================================
- int DpmiApplication::allocateMemory(long sz, long& addr, long & handle)
- {
- long p;
- long hand;
- asm {
- mov ax, 0501h
- mov cx, word ptr sz
- mov bx, word ptr sz+2
- int 31h // call dpmi to allocate memory
- jc nomem
- mov word ptr p, cx
- mov word ptr p+2, bx
- mov word ptr hand, di
- mov word ptr hand+2, si
- }
- addr = p;
- handle = hand;
- return DPMI_OK;
- nomem:
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::allocateLdtDescriptors
- //
- //===================================================================
- int DpmiApplication::allocateLdtDescriptors(int nSelectors, unsigned& baseSelector)
- {
- asm {
- mov ax, 0000h
- mov cx, nSelectors
- int 31h // call dpmi to allocate descriptors
- jc failed
- }
- baseSelector = _AX;
- return DPMI_OK;
- failed:
- errcode = _AX;
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::createAlias(unsigned csIn, unsigned& dsOut)
- //
- //===================================================================
- int DpmiApplication::createAlias(unsigned csIn, unsigned& dsOut)
- {
- asm {
- mov ax, 000ah
- mov bx, csIn
- int 31h // call dpmi to allocate descriptors
- jc failed
- }
- dsOut = _AX;
- return DPMI_OK;
- failed:
- errcode = _AX;
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::freeSelector(unsigned selector)
- //
- //===================================================================
- int DpmiApplication::freeSelector(unsigned selector)
- {
- asm {
- mov ax, 0001h
- mov bx, selector
- int 31h // call dpmi to allocate descriptors
- jc failed
- }
- return DPMI_OK;
- failed:
- errcode = _AX;
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::getSelectorIncrementValue
- //
- //===================================================================
- int DpmiApplication::getSelectorIncrementValue(unsigned& incr)
- {
- asm {
- mov ax, 0003h
- int 31h // call dpmi to determine selector increment
- jc failed
- }
- incr = _AX;
- return DPMI_OK;
- failed:
- errcode = _AX;
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::setSelectorBase
- //
- //===================================================================
- int DpmiApplication::setSelectorBase(unsigned selector, long addr)
- {
- asm {
- mov ax, 0007h
- mov bx, selector
- mov dx, word ptr addr
- mov cx, word ptr addr+2
- int 31h // call dpmi to allocate memory
- jc failed
- }
- return DPMI_OK;
- failed:
- errcode = _AX;
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::setSelectorLimit
- //
- //===================================================================
- int DpmiApplication::setSelectorLimit(unsigned selector, long addr)
- {
- asm {
- mov ax, 0008h
- mov bx, selector
- mov dx, word ptr addr
- mov cx, word ptr addr+2
- int 31h // call dpmi to set selector base
- jc failed
- }
- return DPMI_OK;
- failed:
- errcode = _AX;
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::setAccessRights
- //
- //===================================================================
- int DpmiApplication::setAccessRights(unsigned selector, int rights)
- {
- asm {
- mov ax, 0009h
- mov bx, selector
- mov cx, rights
- int 31h // call dpmi to set selector base
- jc failed
- }
- return DPMI_OK;
- failed:
- errcode = _AX;
- printf("set access rights error: 0x%04x\n", errcode);
- return DPMI_ERR;
- }
-
-
- //===================================================================
- //
- // DpmiApplication::getExceptionHandler
- //
- //===================================================================
- DpmiInterruptVector DpmiApplication::getExceptionHandler(int intno)
- {
- DpmiInterruptVector func;
- asm {
- mov ax, 0202h
- mov bl, byte ptr intno
- int 31h
- mov word ptr func, dx
- mov word ptr func+2, cx
- }
- return func;
- }
-
- //===================================================================
- //
- // DpmiApplication::setExceptionHandler
- //
- //===================================================================
- void DpmiApplication::setExceptionHandler(int intno, DpmiInterruptVector func)
- {
- asm {
- mov ax, 0203h
- mov bl, byte ptr intno
- mov cx, word ptr func+2
- mov dx, word ptr func
- int 31h
- }
- }
-
- //===================================================================
- //
- // DpmiApplication::getProtVect
- //
- //===================================================================
- DpmiInterruptVector DpmiApplication::getProtVect(int intno)
- {
- DpmiInterruptVector func;
- asm {
- mov ax, 0204h
- mov bl, byte ptr intno
- int 31h
- mov word ptr func+2, cx
- mov word ptr func, dx
- }
- return func;
- }
-
- //===================================================================
- //
- // DpmiApplication::setProtVect
- //
- //===================================================================
- void DpmiApplication::setProtVect(int intno, DpmiInterruptVector func)
- {
- asm {
- mov ax, 0205h
- mov bl, byte ptr intno
- mov cx, word ptr func+2
- mov dx, word ptr func
- int 31h
- }
- }
-
- //===================================================================
- //
- // DpmiApplication::getRealVect
- //
- //===================================================================
- DpmiInterruptVector DpmiApplication::getRealVect(int intno)
- {
- DpmiInterruptVector func;
- asm {
- mov ax, 0200h
- mov bl, byte ptr intno
- int 31h
- mov word ptr func+2, cx
- mov word ptr func, dx
- }
- return func;
- }
-
- //===================================================================
- //
- // DpmiApplication::setRealVect
- //
- //===================================================================
- void DpmiApplication::setRealVect(int intno, DpmiInterruptVector func)
- {
- asm {
- mov ax, 0201h
- mov bl, byte ptr intno
- mov cx, word ptr func+2
- mov dx, word ptr func
- int 31h
- }
- }
-
- //===================================================================
- //
- // DpmiApplication::getMappedMemory
- //
- //===================================================================
- int DpmiApplication::getMappedMemory(long unsigned memSize, unsigned& selector, unsigned accessRights)
- {
- int res;
- long handle, linear;
-
- res = Dpmi.allocateLdtDescriptors(1, selector);
- if (res!=0) {
- return DPMI_ERR;
- }
-
- // now allocate and map memory
-
- res = Dpmi.allocateMemory(memSize, linear, handle);
- if (res!=DPMI_OK) return DPMI_ERR;
-
- if (accessRights==AccessRightsStack) {
- res = Dpmi.setSelectorBase(selector, linear+memSize);
- if (res!=DPMI_OK) return DPMI_ERR;
-
- res = Dpmi.setSelectorLimit(selector, 0x10000l-memSize);
- if (res!=DPMI_OK) return DPMI_ERR;
- }
- else {
- res = Dpmi.setSelectorBase(selector, linear);
- if (res!=DPMI_OK) return DPMI_ERR;
-
- res = Dpmi.setSelectorLimit(selector, memSize);
- if (res!=DPMI_OK) return DPMI_ERR;
- }
- res = Dpmi.setAccessRights(selector, accessRights);
- if (res!=DPMI_OK) return DPMI_ERR;
- return DPMI_OK;
- }
-
-
- //===================================================================
- //
- // DpmiApplication::simulateRealInterrupt
- //
- //===================================================================
- int DpmiApplication::simulateRealInterrupt(unsigned intno, DPMI_Regs *regs)
- {
- asm {
- mov ax, 0300h
- mov bl, byte ptr intno
- mov bh, 0 //
- mov cx, 0 // number of words to copy to real mode stack
- mov es, word ptr regs+2
- mov di, word ptr regs
- int 31h
- jc failed
- }
- return DPMI_OK;
- failed:
- errcode = _AX;
- printf("simulateRealInterrupt error: 0x%04x\n", errcode);
- return DPMI_ERR;
- }
-
-
- //===================================================================
- //
- // DpmiApplication::allocateDosMemory
- //
- //===================================================================
- int DpmiApplication::allocateDosMemory(unsigned nPara, unsigned& para, unsigned& selector)
- {
- asm {
- mov ax, 0100h
- mov bx, nPara
- int 31h
- jc failed
- }
- para = _AX;
- selector = _DX;
- return DPMI_OK;
- failed:
- errcode = _AX;
- printf("allocateDosMemory error: 0x%04x\n", errcode);
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::freeDosMemory
- //
- //===================================================================
- int DpmiApplication::freeDosMemory(unsigned selector)
- {
- asm {
- mov ax, 0101h
- mov dx, selector
- int 31h
- jc failed
- }
- return DPMI_OK;
- failed:
- errcode = _AX;
- printf("freeDosMemory error: 0x%04x\n", errcode);
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::mapDosMemory
- //
- //===================================================================
- int DpmiApplication::mapDosMemory(unsigned para, unsigned long sz, unsigned& selector)
- {
- int res = Dpmi.allocateLdtDescriptors(1, selector);
- if (res!=DPMI_OK) return DPMI_ERR;
-
- long linear = ((unsigned long) para) << 4;
-
- res = Dpmi.setSelectorBase(selector, linear);
- if (res!=DPMI_OK) return DPMI_ERR;
-
- res = Dpmi.setSelectorLimit(selector, sz);
- if (res!=DPMI_OK) return DPMI_ERR;
-
- res = Dpmi.setAccessRights(selector, AccessRightsData);
- if (res!=DPMI_OK) return DPMI_ERR;
- return DPMI_OK;
- }
-
- //===================================================================
- //
- // DpmiApplication::lockMemory
- //
- //===================================================================
- int DpmiApplication::lockMemory(long addr, long sz)
- {
- asm {
- mov bx, word ptr addr+2
- mov cx, word ptr addr
- mov si, word ptr sz+2
- mov di, word ptr sz
- mov ax, 0600h
- int 31h
- jc failed
- }
- return DPMI_OK;
- failed:
- errcode = _AX;
- return DPMI_ERR;
- }
-
- //===================================================================
- //
- // DpmiApplication::unlockMemory
- //
- //===================================================================
- int DpmiApplication::unlockMemory(long addr, long sz)
- {
- asm {
- mov bx, word ptr addr+2
- mov cx, word ptr addr
- mov si, word ptr sz+2
- mov di, word ptr sz
- mov ax, 0601h
- int 31h
- jc failed
- }
- return DPMI_OK;
- failed:
- errcode = _AX;
- return DPMI_ERR;
- }
-
-
-
- //===================================================================
- //
- // DpmiApplication::allocateRealCallback
- //
- //===================================================================
- int DpmiApplication::allocateRealCallback(
- DpmiInterruptVector protFunc,
- DPMI_Regs far *callBlock,
- DpmiInterruptVector& callBack)
- {
- DpmiInterruptVector res;
- asm {
- push ds
- mov ds, word ptr protFunc+2
- mov si, word ptr protFunc
- mov es, word ptr callBlock+2
- mov di, word ptr callBlock
- mov ax, 0303h
- int 31h
- pop ds
- jc failed
- mov word ptr res+2, cx
- mov word ptr res, dx
- }
- callBack = res;
- return DPMI_OK;
- failed:
- errcode = _AX;
- return DPMI_ERR;
- }
-
-