------------------------------------------------- Copyright Rainer Schnitker '91 '92 ------------------------------------------------- THE DPMI INTERFACE : This is a short documentation for the interface functions. For details, read the DPMI-specification 0.9 . DOS Extenders and DPMI is described in some special books like: Ray Duncan "Extended Dos". Most DPMI-functions return 0 if successful, -1 on error (later error code of DPMI 1.0). ****** LDT Descriptor management services DPMI 0.9 ****** Constants in dpmi.h for LDT management: - set access rights for descriptors ACCESS_BIT, READ_BIT, WRITE_BIT, CONFIRMING_BIT, EXPAND_BIT, CODE_BIT, SEGMENT_BIT, PRESENT_BIT AVL_BIT, DEFAULT_BIT, GRANULAR_BIT - mask out special fields in descriptor DPL_MASK, TYPE_MASK, LIMIT_HI_MASK - normal access type for dpl3 programs APP_CODE_SEL, APP_DATA_SEL - types of gates TYPE_CODE, TYPE_CONFIRM_CODE, TYPE_DATA, TYPE_EXPAND_DATA, TYPE_286TSS, TYPE_LDT, TYPE_BUSY286TSS, TYPE_286CALLGATE TYPE_TASKGATE, TYPE_286INTGATE, TYPE_286TRAPGATE, TYPE_386TSS, TYPE_BUSY386TSS, TYPE_386CALLGATE TYPE_386INTGATE, TYPE_386TRAPGATE int AllocLDT(WORD n,WORD *firstselector); - this allocates n descriptors from the Local Descriptor Table - add the value returned from function SelInc() to get the next selector - the descriptors will be set to present data type, base=0, limit=0 int FreeLDT(WORD selector); - this function is used to free descriptors that were allocated by the function AllocLDT() int SegtoSel(WORD realsegment,WORD *selector); - this converts real mode segments into descriptors - selector has limit 64 KB WORD SelInc(void); - return the increment value to get the next selector (typical 8). - function can't fail int LockSel(WORD selector); - undocumented function - this locks the address area of the selector int UnlockSel(WORD selector); - undocumented function - this function is used to unlock the memory area int GetBaseAddress(WORD selector,DWORD *address); - gives the 32bit-linear address of the selector int SetBaseAddress(WORD selector ,DWORD 32bitaddress); - set the base address of the specified selector int SetLimit(WORD sel,DWORD limit); - set the limit for the selector (note: limit = blocksize - 1) - if limit > 1 MB, low 12 bits must be set (then the granular bit will be set) - to get the limit use the function lsl32() or lsl16() int SetAccess(WORD,BYTE accessbyte,BYTE 386extendedbyte); - set access rights for the selector - SEGMENT-bit must be set. You can't create a system descriptor. - to get the access right use the function lar32() or lar16() int CreatAlias(WORD codeselector,WORD *alias_selector); - this creates a data descriptor with the same address and limit as the code descriptor int GetDescriptor(WORD selector,NPDESCRIPTOR buffer); - this copies the 8 bytes descriptor table into the buffer int SetDescriptor(WORD selector,NPDESCRIPTOR buffer); - this function is used to set a descriptor int AllocSpecialLDT(WORD selector); - this allocates a specific LDT descriptor ****** DOS Memory Services DPMI 0.9 ****** int AllocDosMem(WORD paragraphs,WORD *segment,WORD *selector); - multiple contiguous selectors are allocated for blocks of more than 64K - if the caller is a 16-bit program never modify or deallocate returned descriptors - return 0 if successful, else DOS errors: 07h memory control blocks damaged 08h insufficient memory available int FreeDosMem(WORD selector); - all descriptors allocated for the block are automatically freed int ResizeDosMem(WORD newparagraphs,WORD oldselector,WORD *newselector); - increasing the size of a block past a 64K boundary will fail if the next descriptor in the LDT is already in use - shrinking a block past a 64K boundary will cause some selectors to be freed ****** Interrupt Services DPMI 0.9 ****** int GetRealModeVector(BYTE intnumber,WORD segment*,WORD *offset); - get real mode interrupt vector int SetRealModeVector(BYTE intnumber,WORD segment,WORD offset); - set real mode interrupt vector - hardware interrupt handler memory must be locked int GetExceptionVektor(BYTE intnumber,WORD *selector,WORD *offset); - give the current protected mode exception handler int SetExceptionVektor(BYTE intnumber,WORD selector,WORD offset); - set new protected mode exception handler - read DPMI-specification 0.9 for some details - use higher C-level functions, described later SetExcep13 etc. int GetProtModeVector(BYTE,WORD *selector,WORD *offset); - get the current protected mode interrupt handler int SetProtModeVektor(BYTE,WORD selector,WORD offset); - set new protected mode interrupt handler ****** Translation services DPMI 0.9 ****** int SimulateRMint(BYTE intnr,BYTE flags,WORD stackwords,NPTRANSLATION call,...) - CS:IP in the real mode call structure is ignored for this call, instead, the indicated interrupt vector is used for the address - the flags in the call structure are pushed on the real mode stack to form an interrupt stack frame, and the trace and interrupt flags are clear on entry to the handler - DPMI will provide a small (30 words) real mode stack if SS:SP is zero the real mode handler must return with the stack in the same state as it was on being called int CallRMprocFar(BYTE flags,WORD stackwords,NPTRANSLATION call,...) - the real mode procedure must exit with a FAR return - DPMI will provide a small (30 words) real mode stack if SS:SP is zero - the real mode handler must return with the stack in the same state as it was on being called int CallRMprocIret(BYTE flags,WORD stackwords,NPTRANSLATION call,...) - the real mode procedure must exit with an IRET int AllocRMcallAddress(WORD sel,WORD off,NPTRANSLATION call, WORD *rmseg,WORD *rmoff) - the real mode call structure is static, causing reentrancy problems - the called procedure must modify the real mode CS:IP before returning - values are returned to real mode by modifying the real mode call struct int FreeRMcallAddress(WORD rmseg,WORD rmoff) - frees real mode callback address ****** Get Version DPMI 0.9 ****** void GetDPMIVersion(DPMIVERSION *) DPMIVERSION struct contains: - flags: bit 0: running under an 80386 (32-bit) implementation bit 1: processor returns to real mode for reflected interrupts instead of V86 mode bit 2: virtual memory supported bit 3: reserved (undefined) others reserved (zero) - cpu : processor type (02h=80286, 03h=80386, 04h=80486) - pic curr value of virtual master interrupt controller base interrupt curr value of virtual slave interrupt controller base interrupt ****** Memory management services DPMI 0.9 ****** void GetFreeMemInfo(NPFREEMEMINFO freemempointer); - get struct contains free mem info - struct FREEMEMINFO: DWORD largest available block in bytes DWORD maximum unlocked page allocation DWORD maximum locked page allocation DWORD total linear address space in pages DWORD total unlocked pages DWORD free pages DWORD total physical pages DWORD free linear address space in pages DWORD size of paging file/partition in pages DWORD reserved DWORD reserved DWORD reserved int GlobalAlloc(DWORD bytes,DWORD *handle,DWORD *memaddress); - allocate memory block , size = bytes - in Windows you get memory page granular. This means that allocation of 534 bytes allocate 4096 = 4 KB. - handle is used to free memory blocks int GlobalFree(DWORD handle); - frees a memory block that was allocate though GlobalAlloc() int GlobalResize(DWORD size,DWORD oldhandle,DWORD *handle,DWORD *newmemaddress); - reallocate memory block , size = bytes - old handle is unvalid ****** Page locking services DPMI 0.9 ****** int LockLinRegion(DWORD size,DWORD linaddress); - locks linear address range , size = region to lock int UnlockLinRegion(DWORD size,DWORD linaddress); - unlock linear address range int MarkRealModePageable(DWORD size,DWORD address); - mark real mode region pageable - relock region before terminating program - use only programs own memory - be sure dpmi-host-memory not pageable int RelockRealModeRegion(DWORD size,DWORD address); - relocks real mode region int GetPageSize(DWORD *size); - get pagesize in bytes ****** Damand page performance tuning services DPMI 0.9 ****** int MarkPageDemand(DWORD address,DWORD n) - mark n pages as demand paging candidate - return 0 : successful -1 : not successful int DiscardPage(DWORD address_of_page,DWORD size) - discard contents of page - return 0 : successful -1 : not successful ****** Physical Address Mapping DPMI 0.9 ****** int PhysicalMap(DWORD address,DWORD size,DWORD *physical) - implementations may refuse this call because it can circumvent protects - the caller must build an appropriate selector for the memory - do not use for memory mapped in the first megabyte ****** Virtuel interrupt state functions DPMI 0.9 ****** BYTE DisableVirtuelInterruptState(void) returns 0 if previously disabled 1 if previously enabled - disable interrupts - a CLI instruction may be used if the previous state is unimportant, but should be assumed to be very slow due to trapping by the host BYTE EnableVirtuelInterruptState(void) returns 0 if previously disabled 1 if previously enabled - enable interrupts - a STI instruction may be used if the previous state is unimportant, but should be assumed to be very slow due to trapping by the host BYTE GetVirtuelInterruptState(void) returns 0 if previously disabled 1 if previously enabled - should be used rather than PUSHF ****** Get Vendor Specific Api Entry Point ****** int GetVendorEntry(NPBYTE APIname,WORD *selector,WORD *offset) - APIname = case-sensitive ASCIZ vendor name or identifier - gives entry point for extended function ****** Debug Register support DPMI 0.9 ****** Constants in dpmi.h for breakpoints BREAK_CODE, BREAK_DATA_W1, BREAK_DATA_RW1, BREAK_DATA_W2 BREAK_DATA_RW2, BREAK_DATA_W4, BREAK_DATA_RW4 int SetDebugWatchpoint(DWORD linear_address,WORD break_type,WORD *handle) - set breakpoint on linear address - types defined in dpmi.h data breakpoint : 1/2/4 byte read/write int ClearDebugWatchpoint(WORD handle) - clear breakpoint int GetStateDebugWatchpoint(WORD handle, WORD *execute_flag) - get state of breakpoint - execute_flag=1, if watchpoint has been executed int ResetDebugWatchpoint(WORD handle) - reset state of breakpoint ****** CPU switching for DPMI 0.9 ****** int hangin_extender(void); - installs a DOS-Extender - return 0 , if successful ****** CPU switching for DPMI 0.9 ****** void real_to_protected(WORD type); - type=0 16 bit program , type=1 32 bit program - call this function switch the cpu in protected mode - other funtions are not execute if this function fails - cs,ds,es were set by the dpmi host void protected_to_real(WORD errorcode); - switch cpu back to real mode - terminates the program ( like real mode int21,function 4c) - errorcode = errorleved to msdos ******* c-functions using DPMI ********** int FreeManyLDT(WORD sel,WORD n) - this frees n continius selectors void PrintFreeMemInfo(NPFREEMEMINFO freemem); - this prints a free memory info void PrintDescriptor(NPDESCRIPTOR descriptor); - print the descriptor address,limit,access type etc. void far * IncFP(void far *); - increment selector to the next void far * DecFP(void far *); - decrement selector to the next ****** high level memory functions in the DPMI-Enviroment ******* void set_memory_type(WORD type) - set memory allocating strategy for extmalloc - types 0, XMSLIMIT, LOCKMEM - XMSLIMIT allocates only memory <= XMS-POOL useful to limit memory for PIF's in Windows 3.0 - LOCKMEM allocates locked memory only void far *extmalloc(DWORD nbytes); - allocates n bytes - if n is greater than 64 KB then continues descriptors will be allocated. To access the next descriptor add the value return by function IncSel() to the base selector - return base selector , NULL if insufficient memory available void extfree(void far *filepointer); - frees memory that was allocated by extmalloc() ******** extended c-functions ********* void farcopy(void far *dest,void far *source,DWORD bytes) - copy memory block from far pointer to far pointer - bytes must min(limit-dest,limit-source) , ( -> GP-fault) - useful to copy pointers given by extmalloc(more then 64KB) int extmovedata(void far *source,void far *dest,DWORD bytes) - same as movedata for size_t bytes - useful to copy pointers given by extmalloc(more then 64KB) - offsets should be the same ******** others ************* int IsWindowsEnhanced(void); - return 1 , if Windows Enhanced mode is running - else 0 int IsPM(void); - return 1 if cpu is in protected mode, 0 not void Yield(void); - call int 2F function 1680h - useful in a program loop in a multitasking environment like Windows ( like GetMassage ) ******* The Protected Mode Interface ******* DWORD lsl32(WORD selector); - load selector limit - uses 32-bit commands , only for >386 - 286 must use lsl16() WORD lsl16(WORD selector); - load selector limit DWORD lar32(WORD selector); - load selector access rights and extended access rights - uses 32-bit commands , only for >386 WORD lar16(WORD selector); - load selector access rights - 286 must use lar16() WORD verr(WORD selector); - verify if read flags is set - return 1 : read 0 : not WORD verw(WORD selector); - verify if write flag is set - return 1 : write 0 : not void sgdt(GDTR *gdtregister); - save GDT base address and limit void sidt(GDTR *idtregister); - save IDT base address and limit WORD sldt(void); - save LDT selector - return LDTselector WORD str(void); - save task register - return TASKselector