📄 dpmi.c
字号:
/*****************************************************************************
* FILE: DPMI.C *
* *
* DESC: *
* - DPMI 0.9 functions for GNUC *
* *
* Copyright (C) 1993,1994 *
* Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld *
* email: rainer@mathematik.uni-bielefeld.de *
* *
*****************************************************************************/
#include "dpmi.h"
/*
** this file could also be used for a include file with
** #define INLINE extern inline
*/
#ifndef INLINE
#define INLINE
#endif
#define CHECKERR "jnc 1f\n\tmovl $-1, %0 \n\tjmp 2f \n\t1: \n\t"
#define CHECK_ERR_DPMI10 "jc 2f\n\t"
#define OKEAX0 "xorl %0, %0 \n\t2: \n\t"
INLINE int AllocLDT(UINT n_sel, UINT * first_sel)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movzwl %%ax, %%eax\n\t"
"movl %%eax, %2 \n\t"
OKEAX0
:"=a"(_v)
:"c"(n_sel), "m"(*first_sel), "0"(0x000)
:"ax", "cx"
);
return _v;
}
INLINE int FreeLDT(UINT sel)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"(sel), "0"(0x001)
:"ax", "bx"
);
return _v;
}
INLINE int SegToSel(UINT segm, UINT * sel)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movzwl %%ax, %%eax \n\t"
"movl %%ax, %2 \n\t"
OKEAX0
:"=a"(_v)
:"b"(segm), "m"(*sel), "0"(0x002)
:"ax", "bx"
);
return _v;
}
INLINE UINT SelInc(void)
{
register unsigned short _v;
__asm__ __volatile__(
"int $0x31 \n\t"
:"=a"((unsigned short) _v)
:"0"((short) 0x003)
:"ax"
);
return (unsigned int) _v;
}
INLINE int GetBaseAddress(UINT sel, ULONG * base)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movw %%dx, %2 \n\t"
"movw %%cx, %3 \n\t"
OKEAX0
:"=a"(_v)
:"b"(sel), "m"(*base), "m"(*((short *) base + 1)), "0"(0x006)
:"ax", "bx", "cx", "dx"
);
return _v;
}
INLINE int SetBaseAddress(UINT sel, DWORD base)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"(sel), "c"((short) (base >> 16)), "d"((short) base), "0"(0x007)
:"ax", "bx", "cx", "dx"
);
return _v;
}
INLINE int SetLimit(UINT sel, DWORD limit)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"(sel), "c"((short) (limit >> 16)), "d"((short) limit), "0"(0x008)
:"ax", "bx", "cx", "dx"
);
return _v;
}
INLINE int SetAccess(UINT sel, BYTE acc, BYTE acc_hi)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"(sel), "c"(((short) acc_hi << 8) | acc), "0"(0x009)
:"ax", "bx", "cx"
);
return _v;
}
INLINE int CreatAlias(UINT sel, UINT * alias)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movzwl %%ax, %%eax \n\t"
"movl %%eax, %2 \n\t"
OKEAX0
:"=a"(_v)
:"b"(sel), "m"(*alias), "0"(0xa)
:"ax", "bx"
);
return _v;
}
INLINE int GetDescriptor(UINT sel, NPDESCRIPTOR desc)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"(sel), "D"((long) desc), "0"(0x00B)
:"ax", "bx", "di"
);
return _v;
}
INLINE int SetDescriptor(UINT sel, NPDESCRIPTOR desc)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"(sel), "D"((long) desc), "0"(0x00C)
:"ax", "bx", "di"
);
return _v;
}
INLINE int AllocSpecialLDT(UINT sel)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"(sel), "0"(0x00D)
:"ax", "bx"
);
return _v;
}
/*
** on error : return value = DOS error
** segm = maximaler request
*/
INLINE int AllocDosMem(UINT paragr, UINT * segm, UINT * sel)
{
register short _v;
__asm__ __volatile__(
"int $0x31 \n\t"
"jnc 1f \n\t"
"movzwl %%bx, %%ebx \n\t"
"movl %%ebx, %2 \n\t"
"jmp 2f \n\t"
"1: \n\t"
"movzwl %%ax, %%eax \n\t"
"movl %%eax, %2 \n\t"
"movzwl %%dx, %%edx \n\t"
"movl %%edx, %3 \n\t"
"xorl %0, %0 \n\t"
"2: \n\t"
:"=a"((short) _v)
:"b"(paragr), "m"(*segm), "m"(*sel), "0"(0x100)
:"ax", "bx", "dx"
);
return (int) _v;
}
INLINE int FreeDosMem(UINT sel)
{
register char _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"((char) _v)
:"d"(sel), "0"(0x101)
:"ax", "dx"
);
return (int) _v;
}
INLINE int ResizeDosMem(UINT sel, UINT bytes, UINT * newsel)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
"jc 1f \n\t"
"movl $-1, %0 \n\t"
"jmp 2f \n\t"
"1: \n\t"
"movzwl %%dx, %%edx \n\t"
"movl %%edx, %3 \n\t"
"xorl %0, %0 \n\t"
"2: \n\t"
:"=a"(_v)
:"d"(sel), "b"(bytes), "m"(*newsel), "0"(0x102)
:"ax", "bx", "dx"
);
return _v;
}
INLINE int GetRealModeVector(BYTE inum, UINT * segm, UINT * offs)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movzwl %%cx, %%ecx \n\t"
"movl %%ecx, %2 \n\t"
"movzwl %%dx, %%edx \n\t"
"movl %%edx, %3 \n\t"
OKEAX0
:"=a"(_v)
:"b"((char) inum), "m"(*segm), "m"(*offs), "0"(0x200)
:"ax", "bx", "cx", "dx"
);
return _v;
}
INLINE int SetRealModeVector(BYTE inum, UINT segm, UINT offs)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((char) inum), "c"((short) segm), "d"((short) offs), "0"(0x201)
:"ax", "bx", "cx", "dx"
);
return _v;
}
INLINE int GetExceptionVector32(BYTE inum, UINT * sel, DWORD * offs)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movzwl %%cx, %%ecx \n\t"
"movl %%ecx, %2 \n\t"
"mov %%edx, %3 \n\t"
OKEAX0
:"=a"(_v)
:"b"((char) inum), "m"(*sel), "m"(*offs), "0"(0x202)
:"ax", "bx", "cx", "dx"
);
return _v;
}
INLINE int SetExceptionVector32(BYTE inum, UINT sel, DWORD offs)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((char) inum), "c"(sel), "d"(offs), "0"(0x203)
:"ax", "bx", "cx", "dx"
);
return _v;
}
INLINE int GetProtModeVector32(BYTE inum, UINT * sel, DWORD * offs)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movzwl %%cx, %%ecx \n\t"
"movl %%ecx, %2 \n\t"
"mov %%edx, %3 \n\t"
OKEAX0
:"=a"(_v)
:"b"((char) inum), "m"(*sel), "m"(*offs), "0"(0x204)
:"ax", "bx", "cx", "dx"
);
return _v;
}
INLINE int SetProtModeVector32(BYTE inum, UINT sel, DWORD offs)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((char) inum), "c"(sel), "d"(offs), "0"(0x205)
:"ax", "bx", "cx", "dx"
);
return _v;
}
INLINE int SimulateRMint(BYTE intno, BYTE r, UINT w, NPTRANSLATION rmcall,...)
{
register int _v;
__asm__ __volatile__(
"xorb %%bh, %%bh \n\t"
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((BYTE) intno), "c"(0), "D"((long) rmcall), "0"(0x300)
:"ax", "bx", "cx", "di"
);
return _v;
}
INLINE int CallRMprocFar(BYTE r, UINT w, NPTRANSLATION rmcall,...)
{
register int _v;
__asm__ __volatile__(
"xorb %%bh, %%bh \n\t"
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"c"(0), "D"((long) rmcall), "0"(0x301)
:"ax", "bx", "cx", "di"
);
return _v;
}
INLINE int CallRMprocIret(BYTE b, UINT w, NPTRANSLATION rmcall,...)
{
register int _v;
__asm__ __volatile__(
"xorb %%bh, %%bh \n\t"
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"c"(0), "D"((long) rmcall), "0"(0x302)
:"ax", "bx", "cx", "di"
);
return _v;
}
INLINE void GetDPMIVersion(DPMIVERSION * version)
{
__asm__ __volatile__(
"int $0x31 \n\t"
"movb %%ah, (%0) \n\t"
"movb %%al, 1(%0) \n\t"
"movw %%bx, 2(%0) \n\t"
"movb %%cl, 4(%0) \n\t"
"movb %%dh, 5(%0) \n\t"
"movb %%dl, 6(%0) \n\t"
:
:"D"((long) version), "a"(0x400)
: "ax","bx","cx","dx"
);
return ;
}
INLINE int GetFreeMemInfo(NPFREEMEMINFO info)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"D"((long) info), "0"(0x500)
:"ax", "di"
);
return _v;
}
INLINE int AllocMem(DWORD size, DWORD * handle, DWORD * base)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movl %3 , %%edx \n\t"
"movw %%si, 2(%%edx) \n\t"
"movw %%di, (%%edx) \n\t"
"movl %4 , %%edx \n\t"
"movw %%bx, 2(%%edx) \n\t"
"movw %%cx, (%%edx) \n\t"
OKEAX0
:"=a"(_v)
:"b"((short) (size >> 16)), "c"((short) size)
,"m"(handle), "m"(base)
,"0"(0x501)
:"ax", "bx", "cx", "dx", "di", "si"
);
return _v;
}
INLINE int FreeMem(DWORD handle)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"S"((short) (handle >> 16)), "D"((short) handle), "0"(0x502)
:"ax", "si", "di"
);
return _v;
}
INLINE int ResizeMem(DWORD size, DWORD handle, DWORD * newhandle, DWORD * newbase)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movl %5 , %%edx \n\t"
"movw %%si, 2(%%edx) \n\t"
"movw %%di, (%%edx) \n\t"
"movl %6 , %%edx \n\t"
"movw %%bx, 2(%%edx) \n\t"
"movw %%cx, (%%edx) \n\t"
OKEAX0
:"=a"(_v)
:"b"((short) (size >> 16)), "c"((short) size),
"S"((short) (handle >> 16)), "D"((short) handle),
"m"(newhandle), "m"(newbase), "0"(0x503)
:"ax", "bx", "cx", "dx", "di", "si"
);
return _v;
}
int LockLinRegion(DWORD size, DWORD address)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((short) (address >> 16)), "c"((short) address),
"S"((short) (size >> 16)), "D"((short) size),
"0"(0x600)
:"ax", "bx", "cx", "si", "di"
);
return _v;
}
int UnlockLinRegion(DWORD size, DWORD address)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((short) (address >> 16)), "c"((short) address),
"S"((short) (size >> 16)), "D"((short) size),
"0"(0x601)
:"ax", "bx", "cx", "si", "di"
);
return _v;
}
int MarkRealModePageable(DWORD size, DWORD address)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((short) (address >> 16)), "c"((short) address),
"S"((short) (size >> 16)), "D"((short) size),
"0"(0x602)
:"ax", "bx", "cx", "si", "di"
);
return _v;
}
int RelockRealModeRegion(DWORD size, DWORD address)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((short) (address >> 16)), "c"((short) address),
"S"((short) (size >> 16)), "D"((short) size),
"0"(0x602)
:"ax", "bx", "cx", "si", "di"
);
return _v;
}
INLINE int GetPageSize(DWORD * size)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movw %%cx, %1 \n\t"
"movw %%bx, %2 \n\t"
OKEAX0
:"=a"(_v)
:"m"(*size), "m"(*((char *) size + 2)), "0"(0x604)
:"ax", "bx", "cx"
);
return _v;
}
int MarkPageDemand(DWORD size, DWORD address)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((short) (address >> 16)), "c"((short) address),
"S"((short) (size >> 16)), "D"((short) size),
"0"(0x702)
:"ax", "bx", "cx", "si", "di"
);
return _v;
}
int SetDebugWatchpoint(DWORD address, WORD type, WORD *handle)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movw %%bx, %4 \n\t"
OKEAX0
:"=a"(_v)
:"b" ((short) (address >> 16)), "c" ((short) address),
"d" ((short) (type)), "m" (*(short *)handle),"0" (0xB00)
:"ax", "bx", "cx"
);
return _v;
}
int ClearDebugWatchpoint(WORD handle)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a" (_v)
:"b" ((short) (handle)),"0" (0xB01)
:"ax", "bx"
);
return _v;
}
int GetStateDebugWatchpoint(WORD handle, WORD *state)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
"movw %%ax, %2 \n\t"
OKEAX0
: "=a" (_v)
: "b" ((short) (handle)), "m" (*(short *)state),"0" (0xB02)
: "ax", "bx"
);
return _v;
}
int ResetDebugWatchpoint(WORD handle)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((short) (handle)), "0"(0xB03)
:"ax", "bx"
);
return _v;
}
INLINE void get_segment(int sel, void *from, void *to, int size)
{
__asm__("pushw %%fs \n\t"
"movw %%ax,%%fs \n\t"
"cld \n\t"
"testb $1,%%cl \n\t"
"je 1f \n\t"
"fs ; movsb \n\t"
"1: \n\t"
"testb $2,%%cl \n\t"
"je 2f \n\t"
"fs ; movsw \n\t"
"2: \n\t"
"shrl $2,%%ecx \n\t"
"rep ; fs ; movsl \n\t"
"popw %%fs \n\t"
::"a"(sel), "c"(size), "D"((long) to), "S"((long) from)
:"cx", "di", "si");
}
UINT unsigned GetCS()
{
register short _v;
__asm__("movw %%cs, %0 ":"=r"((short) _v));
return (UINT) _v;
}
UINT unsigned GetDS()
{
register short _v;
__asm__("movw %%ds, %0 ":"=r"((short) _v));
return (UINT) _v;
}
UINT GetES()
{
register unsigned short _v;
__asm__("movw %%es, %0 ":"=r"((short) _v));
return (UINT) _v;
}
void volatile _dos_exit(WORD exit)
{
__asm__ __volatile__(
"int $0x21"
: /* void */
:"a"((exit & 0xFF) | 0x4C00)
);
}
DWORD lsl32(UINT sel)
{
register unsigned _v;
__asm__ __volatile__(
"lsl %1,%0 "
:"=r"(_v)
:"r"(sel)
);
return _v;
}
int DpmiEnableFpu(WORD bits)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"((WORD)bits), "0"(0xE01)
:"ax", "bx"
);
return _v;
}
int DpmiDisableFpu(void)
{
register int _v;
__asm__ __volatile__(
"int $0x31 \n\t"
CHECKERR
OKEAX0
:"=a"(_v)
:"b"(0), "0"(0xE01)
:"ax", "bx"
);
return _v;
}
void dos_exit(WORD exit)
{
__asm__ __volatile__(
"movb $0x4C, %%ah \n\t"
"int $0x21 \n\t"
:
:"a"((unsigned char) exit)
);
}
void clearregs(void)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -