;
; DPMI16.ASM (c) Rainer Schnitker 91,92,93
;

;
; 16bit library for DPMI 0.9 calls
;
; define 'HAVE386' to use 32bit DPMI mode
;

	.286
	.model SMALL, C

; macro to call dpmi in ax
;
DPMI MACRO function
	mov ax,function
	int 31h
	ENDM

; error check for dpmi-functions
; return -1 for dpmi 0.9
; for dpmi 1.0 replace with "jc @@end" , error code = ax
;
CHECKERR MACRO
	jnc	short @@ok
	mov	ax, -1
	jmp	short @@end
	ENDM

getdword MACRO high,low,address
	mov low,word ptr address
	mov high,word ptr address.2
	ENDM

setdword MACRO address,high,low
	mov word ptr address,low
	mov word ptr address.2,high
	ENDM


	.data

	.code


   ;
   ;	int AllocLDT(WORD anzahl,WORD *sel)
   ;
	public	C AllocLDT
AllocLDT PROC C \
	anzahl	:WORD, \
	sel	:PTR

	mov	cx, anzahl
	DPMI 0000h
	CHECKERR
@@ok:
	mov	bx, sel
	mov	word ptr [bx], ax
	xor	ax, ax
@@end:
	ret
AllocLDT	endp

   ;
   ;	int FreeLDT(WORD sel)
   ;
	public	C FreeLDT
FreeLDT PROC C \
	sel	:WORD

	mov	bx, sel
	DPMI 0001h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
FreeLDT 	endp

   ;
   ;	int SegToSel(WORD seg,WORD *sel)
   ;
	public	C SegToSel
SegToSel PROC C \
	paragr	: WORD , \
	sel	: PTR

	mov	bx,paragr
	DPMI 0002h
	CHECKERR
@@ok:
	mov	bx, sel
	mov	word ptr [bx], ax
	xor	ax, ax
@@end:
	ret
SegToSel       endp

   ;
   ;	WORD SelInc(void)
   ;
	public	C SelInc
SelInc PROC C
	DPMI 0003h
	ret
SelInc		endp

   ;
   ;	int LockSel(WORD sel)  undocumented in dpmi 0.9/1.0
   ;
	public	C LockSel
LockSel PROC C \
	sel	:WORD

	mov	bx, sel
	DPMI 0004h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
LockSel        endp

   ;
   ;	int UnlockSel(WORD sel)  undocumented in dpmi 0.9/1.0
   ;
	public	C UnlockSel
UnlockSel PROC C \
	sel	:WORD

	mov	bx,sel
	DPMI 0005h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
UnlockSel      endp

   ;
   ;	int GetBaseAddress(WORD sel,DWORD *address)
   ;
	public	C GetBaseAddress
GetBaseAddress PROC C \
	sel	:WORD , \
	address :PTR

	mov	bx, sel
	DPMI 0006h
	CHECKERR
@@ok:
	mov	bx, address
	setdword [bx],cx,dx
	xor	ax, ax
@@end:
	ret
GetBaseAddress endp

   ;
   ;	int SetBaseAddress(WORD sel,DWORD address)
   ;
	public	C SetBaseAddress
SetBaseAddress PROC C \
	sel	:WORD , \
	base	:DWORD

	getdword cx,dx,base
	mov	bx, sel
	DPMI 0007h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
SetBaseAddress endp

   ;
   ;	int SetLimit(WORD sel,DWORD limit)
   ;
	public	C SetLimit
SetLimit PROC C \
	sel	:WORD , \
	limit	:DWORD

	mov	bx,sel
	getdword cx,dx,limit
	DPMI 0008h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
SetLimit       endp

   ;
   ;	int SetAccess(WORD sel,BYTE access,BYTE extaccess)
   ;
	public	C SetAccess
SetAccess PROC C \
	sel	:WORD, \
	access	:BYTE, \
	extaccess :BYTE

	mov	bx,sel
	mov	cl,access
	mov	ch,extaccess
	DPMI 0009h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
SetAccess      endp

   ;
   ;	int CreatAlias(WORD segsel,WORD *alias)
   ;
	public	C CreatAlias
CreatAlias  PROC C \
	segsel	:WORD , \
	alias	:PTR

	mov	bx,sel
	DPMI 000Ah
	CHECKERR
@@ok:
	mov	bx,alias
	mov	word ptr [bx],ax
	xor	ax, ax
@@end:
	ret
CreatAlias     endp

   ;
   ;	int GetDescriptor(WORD sel,NPDESCRIPTOR desc)
   ;
	public	C GetDescriptor
GetDescriptor PROC C USES DI, \
	sel	:WORD , \
	desc	:PTR

	push	ds
	pop	es
	mov	bx,sel
ifdef HAVE386
	.386
	movzx	edi, desc
	.286
else
	mov	di,desc
endif
	DPMI 000Bh
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
GetDescriptor  endp

   ;
   ;	int SetDescriptor(WORD sel,NPDESCRIPTOR desc)
   ;
	public	C SetDescriptor
SetDescriptor PROC C USES DI, \
	sel	:WORD, \
	desc	:PTR

	push	ds
	pop	es
ifdef HAVE386
	.386
	movzx	edi, sel
	.286
else
	mov	di,desc
endif
	mov	bx,sel
	DPMI 000Ch
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
SetDescriptor  endp

   ;
   ;	int AllocSpecialLDT(WORD sel)
   ;
	public	C AllocSpecialLDT
AllocSpecialLDT PROC C \
	sel	:WORD

	mov	bx,sel
	DPMI 000Dh
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
AllocSpecialLDT        endp

   ;
   ;	int AllocDosMem(WORD paragraphs,WORD *segment,WORD *selector)
   ;
	public	C AllocDosMem
AllocDosMem  PROC C \
	request :WORD , \
	result	:PTR , \
	sel	:PTR

	mov	bx,request
	DPMI 0100h
	jnc	short @@ok
	mov	dx,bx
	mov	bx,result
	mov	word ptr [bx],dx
	jmp	short @@end
@@ok:
	mov	bx,result
	mov	word ptr [bx],ax
	mov	bx,sel
	mov	word ptr [bx],dx
	xor	ax, ax
@@end:
	ret
AllocDosMem    endp

   ;
   ;	int FreeDosMem(WORD selector)
   ;
	public	C FreeDosMem
FreeDosMem PROC C \
	sel	:WORD

	mov	dx,sel
	DPMI 0101h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
FreeDosMem     endp

   ;
   ;	int ResizeDosMem(WORD paragraphs,WORD oldsel,WORD *maxpara)
   ;
	public	C ResizeDosMem
ResizeDosMem PROC C \
	paragr	:WORD , \
	oldsel	:WORD , \
	maxpara :PTR

	mov	bx,paragr
	mov	dx,oldsel
	DPMI 0102h
	jnc	short @@ok
	mov	dx,bx
	mov	bx,maxpara
	mov	word ptr [bx],dx
	jmp	short @@end
@@ok:
	xor	ax, ax
@@end:
	ret
ResizeDosMem   endp

   ;
   ;	int GetRealModeVector(BYTE b,WORD *seg,WORD *off)
   ;
	public	C GetRealModeVector
GetRealModeVector PROC C \
	no	:BYTE , \
	segm	:PTR , \
	offs	:PTR

	mov	bl,no
	DPMI 0200h
	CHECKERR
@@ok:
	mov	bx,segm
	mov	word ptr [bx],cx
	mov	bx,offs
	mov	word ptr [bx],dx
	xor	ax, ax
@@end:
	ret
GetRealModeVector      endp

   ;
   ;	int SetRealModeVector(BYTE b,WORD seg,WORD off)
   ;
	public	C SetRealModeVector
SetRealModeVector PROC C \
	b	:BYTE , \
	segm	:WORD , \
	offs	:WORD

	mov	bl,b
	mov	cx,segm
	mov	dx,offs
	DPMI 0201h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
SetRealModeVector      endp

   ;
   ;	int GetExceptionVector(BYTE b,WORD *sel,WORD *off)
   ;
	public	C GetExceptionVector
GetExceptionVector PROC C \
	no	:BYTE , \
	segm	:PTR , \
	offs	:PTR

	mov	bl,no
	DPMI 0202h
	CHECKERR
@@ok:
	mov	bx,segm
	mov	word ptr [bx],cx
	mov	bx,offs
	mov	word ptr [bx],dx
	xor	ax, ax
@@end:
	ret
GetExceptionVector     endp

ifdef HAVE386
   ;
   ;	int GetExceptionVector32(BYTE b,WORD *sel,DWORD *off)
   ;
	public	C GetExceptionVector32
GetExceptionVector32 PROC C \
	no	:BYTE , \
	segm	:PTR , \
	offs	:PTR

	mov	bl,no
	DPMI 0202h
	CHECKERR
@@ok:
	mov	bx,segm
	mov	word ptr [bx],cx
	mov	bx,offs
	mov	word ptr [bx],dx
	.386
	shr	edx,16
	.286
	mov	word ptr [bx].2,dx
	xor	ax,ax
@@end:
	ret
GetExceptionVector32   endp
endif

   ;
   ;	int SetExceptionVector(BYTE b,WORD sel,WORD off)
   ;
	public	C SetExceptionVector
SetExceptionVector PROC C \
	b	:BYTE , \
	segm	:WORD , \
	offs	:WORD

	mov	bl,b
	mov	cx,segm
	mov	dx,offs
	DPMI 0203h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
SetExceptionVector     endp

ifdef HAVE386
   ;
   ;	int SetExceptionVector32(BYTE b,WORD sel,DWORD off)
   ;
	public	C SetExceptionVector32
SetExceptionVector32 PROC C \
	b	:BYTE , \
	segm	:WORD , \
	offs	:DWORD

	mov	bl,b
	mov	cx,segm
	.386
	mov	edx,offs
	.286
	DPMI 0203h
	CHECKERR
@@ok:
	xor	ax,ax
@@end:
	.386
	xor	edx,edx
	.286
	ret
SetExceptionVector32   endp
endif

   ;
   ;	int GetProtModeVector(BYTE b,WORD *sel,WORD *off)
   ;
	public	C GetProtModeVector
GetProtModeVector PROC C \
	no	:BYTE , \
	segm	:PTR , \
	offs	:PTR

	mov	bl,no
	DPMI 0204h
	CHECKERR
@@ok:
	mov	bx,segm
	mov	word ptr [bx],cx
	mov	bx,offs
	mov	word ptr [bx],dx
	xor	ax, ax
@@end:
	ret
GetProtModeVector   endp

ifdef HAVE386
   ;
   ;	int GetProtModeVector32(BYTE b,WORD *sel,DWORD *off)
   ;
	public	C GetProtModeVector32
GetProtModeVector32 PROC C \
	no	:BYTE , \
	segm	:PTR , \
	offs	:PTR

	mov	bl,no
	DPMI 0204h
	CHECKERR
@@ok:
	mov	bx,segm
	mov	word ptr [bx],cx
	mov	bx,offs
	mov	word ptr [bx],dx
	.386
	shr	edx,16
	.286
	mov	word ptr [bx].2,dx
	xor	ax,ax
@@end:
	ret
GetProtModeVector32 endp
endif

   ;
   ;	int SetProtModeVector(BYTE b,WORD sel,WORD off)
   ;
	public	C SetProtModeVector
SetProtModeVector PROC C \
	b	:BYTE , \
	segm	:WORD , \
	offs	:WORD

	mov	bl,b
	mov	cx,segm
	mov	dx,offs
	DPMI 0205h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
SetProtModeVector   endp

ifdef HAVE386
   ;
   ;	int SetProtModeVector32(BYTE b,WORD sel,DWORD off)
   ;
	public	C SetProtModeVector32
SetProtModeVector32 PROC C \
	b	:BYTE , \
	segm	:WORD , \
	offs	:DWORD

	mov	bl,b
	mov	cx,segm
	.386
	mov	edx,offs
	.286
	DPMI 0205h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
SetProtModeVector32 endp
endif

   ;
   ;	int SimulateRMint(BYTE int,BYTE flag,WORD args,NPTRANSLATION call,..)
   ;
	public	C SimulateRMint
SimulateRMint PROC C USES SI DI, \
	intnr	:BYTE, \
	flags	:BYTE, \
	stwords :WORD, \
	trans	:PTR, \
	argv	:BYTE

	push	ds		; small model! ds=ss=es
	pop	es
	mov	cx,stwords
	jcxz	@@simulate
; copy
	sub	sp, cx		;
	sub	sp, cx		; space for cx words
	mov	di, sp
	lea	si, argv
	cld
	rep movsw

	mov	cx, stwords	; reload after movs
@@simulate:
	mov	bh, flags
	mov	bl, intnr
ifdef HAVE386
	.386
	movzx	edi, trans
	.286
else
	mov	di,trans
endif
	DPMI 0300h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	mov	cx, stwords
	add	sp,stwords
	add	sp,stwords
	ret
SimulateRMint  endp

   ;
   ;	int CallRMprocFar(BYTE flag,WORD args,NPTRANSLATION call,...)
   ;
	public	C CallRMprocFar
CallRMprocFar PROC C USES SI DI , \
	flags	:BYTE, \
	stwords :WORD, \
	trans	:PTR, \
	argv	:BYTE

	push	ds		; small model! ds=ss=es
	pop	es
	mov	cx,stwords
	jcxz	@@simulate
; copy
	sub	sp, cx
	sub	sp, cx		; space for cx words
	mov	di, sp
	lea	si, argv
	cld
	rep movsw

	mov	cx, stwords
@@simulate:
	xor	bx,bx	; don't use flags
ifdef HAVE386
	.386
	movzx	edi, trans
	.286
else
	mov	di,trans
endif
	DPMI 0301h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	mov	cx, stwords
	add	sp,cx
	add	sp,cx
	ret
CallRMprocFar  endp

   ;
   ;	int CallRMprocIret(BYTE flag,WORD args,NPTRANSLATION call,...)
   ;
	public	C CallRMprocIret
CallRMprocIret PROC C USES SI DI, \
	flags	:BYTE, \
	stwords :WORD, \
	trans	:PTR, \
	argv	:BYTE

	push	ds		; small model! ds=ss=es
	pop	es
	mov	cx,stwords
	mov	cx,stwords
	jcxz	@@simulate
; copy
	sub	sp, cx
	mov	di, sp
	lea	si, argv
	cld
	rep movsw

	mov	cx, stwords
@@simulate:
	mov	bh, flags
ifdef HAVE386
	.386
	movzx	edi, trans
	.286
else
	mov	di,trans
endif
	DPMI 0302h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	mov	cx, stwords
	add	sp,stwords
	add	sp,stwords
	ret
CallRMprocIret endp

   ;
   ;	int AllocRMcallAddress(WORD pmsel,WORD pmoff,NPTRANSLATION call,
   ;				WORD *rmseg,WORD *rmoff)
   ;
	public	C AllocRMcallAddress
AllocRMcallAddress PROC C USES SI DI, \
	pmsel	:WORD , \
	pmoff	:WORD , \
	trans	:PTR ,	\
	rmseg	:PTR ,	\
	rmoff	:PTR

	push	ds
	pop	es
	push	ds
	mov	ds,pmsel
ifdef HAVE386
	.386
	movzx	esi, pmoff
	movzx	edi, trans
	.286
else
	mov	si, pmoff
	mov	di, trans
endif
	DPMI 0303h
	pop	ds
	CHECKERR
@@ok:
	mov	bx,rmseg
	mov	word ptr [bx],cx
	mov	bx,rmoff
	mov	word ptr [bx],dx
	xor	ax, ax
@@end:
	ret
AllocRMcallAddress     endp

   ;
   ;	int FreeRMcallAddress(WORD rmseg,WORD rmoff)
   ;
	public	C FreeRMcallAddress
FreeRMcallAddress PROC C \
	rmseg	:WORD , \
	rmoff	:WORD

	mov	cx,rmseg
	mov	dx,rmoff
	DPMI 0304h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
FreeRMcallAddress      endp

   ;
   ;	int GetStateSaveAddress(WORD *size,POINTER16_16 *,POINTER16_16 *)
   ;
	public	C GetStateSaveAddress
GetStateSaveAddress PROC C USES SI DI, \
	bytes	:PTR ,	\
	realaddr:PTR ,	\
	protaddr:PTR ,	\

	DPMI 0305h
	CHECKERR
@@ok:
	mov	dx, bx
	mov	bx, bytes
	mov	word ptr [bx],ax
	mov	bx, realaddr
	setdword [bx],dx,cx
	mov	bx, protaddr
ifdef HAVE386
	.386
	xor	edi, edi
	.286
endif
	setdword [bx],si,di
	xor	ax, ax
@@end:
	ret
GetStateSaveAddress	endp

   ;
   ;	int SaveState(WORD *buffer,POINTER16_16);
   ;
	public	C SaveState
SaveState PROC C USES DI, \
	buffer	:PTR ,	\
	offaddr :BYTE

	push	ds
	pop	es
ifdef HAVE386
	.386
	movzx	edi, buffer
	.286
else
	mov	di, buffer
endif
	mov	ax, 0
	call	dword ptr offaddr
	ret
SaveState	endp

   ;
   ;	int RestoreState(WORD *buffer,POINTER16_16);
   ;
	public	C RestoreState
RestoreState PROC C USES DI, \
	buffer	:PTR ,	\
	offaddr :BYTE

	push	ds
	pop	es
ifdef HAVE386
	.386
	movzx	edi, buffer
	.286
else
	mov	di, buffer
endif
	mov	ax, 1
	call	dword ptr offaddr
	ret
RestoreState	   endp

   ;
   ;	void GetDPMIVersion(DPMIVERSION *v)
   ;
	public	C GetDPMIVersion
GetDPMIVersion PROC C USES SI, \
	verptr	:PTR
				; packed struct req!
	mov	si,verptr
	DPMI 0400h
	mov	byte ptr [si],ah
	mov	byte ptr [si+1],al
	mov	word ptr [si+2],bx
	mov	byte ptr [si+4],cl
	mov	byte ptr [si+5],dh
	mov	byte ptr [si+6],dl
	ret
GetDPMIVersion endp

   ;
   ;	int GetFreeMemInfo(NPFREEMEMINFO fm)
   ;
	public	C GetFreeMemInfo
GetFreeMemInfo PROC C USES DI, \
	fm	:PTR

	push	 ds
	pop	 es
ifdef HAVE386
	.386
	movzx	edi, word ptr fm
	.286
else
	mov	di,fm
endif
	DPMI 0500h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
GetFreeMemInfo endp

   ;
   ;	int AllocMem(DWORD bytes,DWORD *handle,DWORD *memaddress)
   ;
	public	C AllocMem
AllocMem PROC C USES SI DI, \
	nbytes	:DWORD , \
	handle	:PTR , \
	memadr	:PTR

	getdword bx,cx,nbytes
	DPMI 0501h
	CHECKERR
@@ok:
	mov	ax,bx
	mov	bx,handle
	setdword [bx],si,di
	mov	bx,memadr
	setdword [bx],ax,cx
	xor	ax, ax
@@end:
	ret
AllocMem       endp

   ;
   ;	int FreeMem(DWORD handle)
   ;
	public	C FreeMem
FreeMem PROC C USES SI DI, \
	handle	:DWORD

	getdword si,di,handle
	DPMI 0502h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
FreeMem        endp

   ;
   ;	int ResizeMem(DWORD bytes,DWORD oldhandle,DWORD *newhandle,DWORD *newaddress)
   ;
	public	C ResizeMem
ResizeMem PROC C USES SI DI , \
	nbytes	:DWORD , \
	oldh	:DWORD , \
	newh	:PTR   , \
	newadr	: PTR

	getdword bx,cx,nbytes
	getdword si,di,oldh
	DPMI 0503h
	CHECKERR
@@ok:
	mov	ax,bx
	mov	bx,newadr
	setdword [bx],ax,cx
	mov	bx,newh
	setdword [bx],si,di
	xor	ax, ax
@@end:
	ret
ResizeMem      endp

   ;
   ;	int LockLinRegion(DWORD size,DWORD address)
   ;
	public	C LockLinRegion
LockLinRegion PROC C USES SI DI, \
	sizeb	:DWORD , \
	addr	:DWORD

	getdword bx,cx,addr
	getdword si,di,sizeb
	DPMI 0600h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
LockLinRegion  endp

   ;
   ;	int UnlockLinRegion(DWORD size,DWORD address)
   ;
	public	C UnlockLinRegion
UnlockLinRegion PROC C USES SI DI, \
	sizeb	:DWORD , \
	address :DWORD

	getdword si,di,sizeb
	getdword bx,cx,address
	DPMI 0601h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
UnlockLinRegion        endp

   ;
   ;	int MarkRealModePageable(DWORD size,DWORD address)
   ;
	public	C MarkRealModePageable
MarkRealModePageable PROC C USES SI DI , \
	sizeb	:DWORD , \
	addr	:DWORD

	getdword bx,cx,addr
	getdword si,di,sizeb
	DPMI 0602h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
MarkRealModePageable   endp

   ;
   ;	int RelockRealModeRegion(DWORD size,DWORD address)
   ;
	public	C RelockRealModeRegion
RelockRealModeRegion PROC C USES SI DI, \
	sizeb	:DWORD , \
	addr	:DWORD

	getdword bx,cx,addr
	getdword si,di,sizeb
	DPMI 0603h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
RelockRealModeRegion   endp

   ;
   ;	int GetPageSize(DWORD *size)
   ;
	public	C GetPageSize
GetPageSize PROC C \
	sizeb	:PTR

	DPMI 0604h
	CHECKERR
@@ok:
	mov	ax,bx
	mov	bx,sizeb
	setdword [bx],ax,cx
	xor	ax, ax
@@end:
	ret
GetPageSize    endp

   ;
   ;	int MarkPageDemand(DWORD address,DWORD n)
   ;
	public	C MarkPageDemand
MarkPageDemand PROC C USES SI DI , \
	addr	:DWORD , \
	nbytes	:DWORD

	getdword bx,cx,addr
	getdword si,di,nbytes
	DPMI 0702h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
MarkPageDemand endp

   ;
   ;	int DiscardPage(DWORD address,DWORD size)
   ;
	public	C DiscardPage
DiscardPage PROC C USES SI DI , \
	addr	:DWORD , \
	sizeb	:DWORD

	getdword bx,cx,addr
	getdword si,di,sizeb
	DPMI 0703h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
DiscardPage    endp

   ;
   ;	int PhysicalMap(DWORD physical,DWORD size,DWORD *linear)
   ;
	public	C PhysicalMap
PhysicalMap PROC C USES SI DI , \
	physic	:DWORD , \
	sizeb	:DWORD , \
	linear	:PTR

	getdword bx,cx,physic
	getdword si,di,sizeb
	DPMI 0800h
	CHECKERR
@@ok:
	mov	di,linear
	setdword [di],bx,cx
	xor	ax, ax
@@end:
	ret
PhysicalMap    endp

   ;
   ;	BYTE DisableVirtuelInterruptState()
   ;
	public	C DisableVirtuelInterruptState
DisableVirtuelInterruptState PROC C
	DPMI 0900h
	xor	ah,ah
	ret
DisableVirtuelInterruptState	endp

   ;
   ;	BYTE EnableVirtuelInterruptState()
   ;
	public	C EnableVirtuelInterruptState
EnableVirtuelInterruptState PROC C
	DPMI 0901h
	xor	ah,ah
	ret
EnableVirtuelInterruptState	endp

   ;
   ;	BYTE GetVirtuelInterruptState()
   ;
	public	C GetVirtuelInterruptState
GetVirtuelInterruptState PROC C
	DPMI 0902h
	xor	ah,ah
	ret
GetVirtuelInterruptState	endp

   ;
   ;	int GetVendorEntry(BYTE *p,WORD *sel,WORD *off)
   ;
	public	C GetVendorEntry
GetVendorEntry PROC C USES ES SI DI , \
	string	:PTR , \
	sel	:PTR , \
	offs	:PTR

ifdef HAVE386
	.386
	movzx	edi,string
	.286
else
	mov	di,string
endif
	DPMI 0A00h
	CHECKERR
@@ok:
	mov	bx,sel
	mov	word ptr [bx],es
	mov	bx,offs
	mov	word ptr [bx],si
	xor	ax, ax
@@end:
	ret
GetVendorEntry endp

   ;
   ;	int SetDebugWatchpoint(DWORD address,WORD type,WORD *handle)
   ;
	public	C SetDebugWatchpoint
SetDebugWatchpoint PROC C , \
	addr	:DWORD , \
	types	:WORD , \
	handle	:PTR

	getdword bx,cx,addr
	mov	dx,types
	DPMI 0B00h
	CHECKERR
@@ok:
	mov	dx,bx
	mov	bx,handle
	mov	word ptr [bx],dx
	xor	ax, ax
@@end:
	ret
SetDebugWatchpoint     endp

   ;
   ;	int ClearDebugWatchpoint(WORD handle)
   ;
	public	C ClearDebugWatchpoint
ClearDebugWatchpoint PROC C \
	handle	:WORD

	mov	bx,handle
	DPMI 0B01h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
ClearDebugWatchpoint   endp

   ;
   ;	int GetStateDebugWatchpoint(WORD handle,WORD *execute)
   ;
	public	C GetStateDebugWatchpoint
GetStateDebugWatchpoint PROC C \
	handle	:WORD , \
	execute :PTR

	mov	bx,handle
	DPMI 0B02h
	CHECKERR
@@ok:
	mov	bx,execute
	mov	[bx],ax
	xor	ax, ax
@@end:
	ret
GetStateDebugWatchpoint        endp

   ;
   ;	int ResetDebugWatchpoint(WORD handle)
   ;
	public	C ResetDebugWatchpoint
ResetDebugWatchpoint PROC C \
	handle	:WORD

	mov	bx,handle
	DPMI 0B03h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
ResetDebugWatchpoint   endp


;
; Protected mode instructions
;

	.286p

   ;
   ;	WORD lsl16(WORD sel)	16-bit version of lsl for 80286
   ;
	public	C lsl16
lsl16 PROC C \
	sel	:WORD

	xor	 ax, ax
	lsl	 ax,sel
	ret
lsl16  endp

ifdef HAVE386
   ;
   ;	DWORD lsl32(WORD sel)  /* load selector limit for 80386 */
   ;
	public	C lsl32
lsl32  PROC C \
	sel	:WORD

	.386p
	movzx	ebx,sel
	lsl	eax,ebx
	mov	edx,eax
	shr	edx,16
	and	eax,dword ptr 0ffffh
	.286p
	ret
lsl32  endp
endif

   ;
   ;	WORD lar16(WORD sel)	16-bit version of lar for 80286
   ;
	public	C lar16
lar16 PROC C \
	sel	:WORD

	xor	 ax, ax
	lar	 ax,sel
	shr	 ax,8
	ret
lar16  endp

ifdef HAVE386
   ;
   ;	WORD lar16(WORD sel)	16-bit version of lar for 80286
   ;
	public	C lar32
lar32  PROC C \
	sel	:WORD
	.386p
	movzx	ebx,sel
	lar	eax,ebx
	mov	edx,eax
	shr	edx,16
	and	eax,dword ptr 0ffffh
	.286p
	ret
lar32  endp
endif

   ;
   ;	WORD verr(WORD sel)	verify read
   ;
	public	C verr16
verr16 PROC C \
	sel	:WORD

	mov	ax,1
	verr	sel
	je	short @@nok
	dec	ax
@@nok:
	ret
verr16 endp

   ;
   ;	WORD verw(WORD sel)	verify write
   ;
	public	C verw16
verw16 PROC C \
	sel	:WORD

	mov	ax,1
	verw	sel
	je	short @@nok
	dec	ax
@@nok:
	ret
verw16 endp

   ;
   ;	void sgdt(LPGDTR g)	save gdt table
   ;
	public	C sgdt16
sgdt16 PROC C \
	g	:DWORD

	les	 bx,g
	sgdt	 es:[bx]
	ret
sgdt16 endp

   ;
   ;	void sidt(LPGDTR g)	save idt table
   ;
	public	C sidt16
sidt16 PROC C \
	g	:DWORD

	les	 bx,g
	sidt	 es:[bx]
	ret
sidt16 endp

   ;
   ;	WORD sldt(void) 	save ldt-selector
   ;
	public	C sldt16
sldt16 PROC C
	sldt	 ax
	ret
sldt16 endp

   ;
   ;	WORD str16(void)	  save task-register
   ;
	public	C str16
str16 PROC C
	str	 ax
	ret
str16  endp

   ;
   ;	void far * IncFP(void far *a)	increment far piointer
   ;
	public	C IncFP
IncFP PROC C \
	aptr	:DWORD

	call	near ptr SelInc
	mov	cx, ax
	getdword dx,ax,aptr
	add	dx,cx
	ret
IncFP  endp

   ;
   ;	void far * DecFP(void far *a)	decrement far pointer
   ;
	public	C DecFP
DecFP PROC C \
	aptr	:DWORD

	call	near ptr SelInc
	mov	cx, ax
	getdword dx,ax,aptr
	sub	dx,cx
	ret
DecFP  endp

   ;
   ;	int IsPM()	execute in prot-mode ? ax==0, PMode under DPMI
   ;
	public	C IsPM
IsPM PROC C
	mov	ax,1686h
	int	02FH
	ret
IsPM   endp

   ;
   ;	int IsWindowsEnhanced(void)
   ;
	public	C IsWindowsEnhanced
IsWindowsEnhanced PROC C
	mov	ax,01600H
	int	02fH
	cmp	al,3
	jb	short @@not
	cmp	al,10
	ja	short @@not
	mov	ax, 1
	jmp	short @@end
@@not:
	xor	ax, ax
@@end:
	ret
IsWindowsEnhanced      endp

   ;
   ;	void yield() /* give control to operating system (like GetMassage) */
   ;
	public	C yield
yield PROC C
	mov	ax,1680H
	int	2Fh
	ret
yield  endp

	public dos_exit
dos_exit PROC C \
	errorlevel:WORD

	mov	ax, errorlevel
	mov	ah, 04Ch
	int	021h
	ret
dos_exit endp

	public DpmiEnableFpu
DpmiEnableFpu PROC C \
	bits	:WORD

	mov	bx, bits
	DPMI 0E01h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
DpmiEnableFpu endp

	public C DpmiDisableFpu
DpmiDisableFpu PROC C
	mov	bx, 0
	DPMI 0E01h
	CHECKERR
@@ok:
	xor	ax, ax
@@end:
	ret
DpmiDisableFpu endp

	public C GetCS
GetCS PROC C
	mov	ax,cs
	ret
GetCS endp

	public C GetDS
GetDS PROC C
	mov	ax,ds
	ret
GetDS endp

	public C GetES
GetES PROC C
	mov	ax,es
	ret
GetES endp

	public C GetDpmiEntryPoint
GetDpmiEntryPoint PROC C USES SI DI , \
	entry	:PTR, \
	dpmipara:PTR, \
	flags	:PTR, \
	dpmiver :PTR, \
	cpu	:PTR

	mov	ax, 1687h
	int	2Fh
	or	ax,ax
	jnz	noDPMI
	mov	ax, bx		; save bx = bits

	mov	bx, entry
	mov	[bx], di
	mov	[bx+2], es
	mov	bx, flags
	mov	[bx], ax
	mov	bx, dpmiver
	mov	[bx], dx
	mov	bx, cpu
	mov	[bx], cl
	mov	bx, dpmipara
	mov	[bx], si
	xor	ax, ax
noDPMI:
	ret
GetDpmiEntryPoint endp

	public C GetDpmiHostParagraph
GetDpmiHostParagraph PROC C \
	dpmipara:WORD

	mov	bx, dpmipara
	mov	ah, 48h
	int	21h
	jnc	@@end
	or	ax,ax
@@end:
	ret
GetDpmiHostParagraph endp

	public C DpmiEnterProtectedMode
DpmiEnterProtectedMode PROC C \
	entry	:DWORD, \
	flags	:WORD, \
	parasegm:WORD

	mov	ax, parasegm
	mov	es, ax
	mov	ax, flags
	call	dword ptr entry
	jnc	@@ok
	mov	ax, -1
	jmp	short @@end
@@ok:
	xor	ax, ax
@@end:
	ret
DpmiEnterProtectedMode endp

	end
