Source file: /~heha/hsn/kcemu/[Download]kcemu_050.exe/SRC/KCEMUVXD.ASM

	IDEAL
	%MACS
	%NOINCL
	%TITLE "KCEMU pagemap support"
	include "tvmm2.inc"	;Generelles
	include	"debug2.inc"	;wegen Debugging
KCEMU_Device_ID	equ	3E69h	;von Kleinstweich
KCEMU_Major_Ver	equ	1
KCEMU_Minor_Ver	equ	0

ifdef DEBUG
	DISPLAY	!Assembliere Debugversion!
endif

Declare_Virtual_Device  KCEMU, KCEMU_Major_Ver, KCEMU_Minor_Ver,\
			KCEMU_Ctl, KCEMU_Device_ID,\
			Undefined_Init_Order, , KCEMU_API

;*********************************************************
;*** Obligatorischer VxD-Botschafts-Funktionsverteiler ***
;*********************************************************
VxD_Locked_Code_Seg
BeginProc KCEMU_Ctl
;	Control_Dispatch Device_Init, KCEMU_Init
;	Control_Dispatch System_Exit, KCEMU_Exit
;	Control_Dispatch 1bh, KCEMU_Dynamic_Init
;	Control_Dispatch 1ch, KCEMU_Dynamic_Exit
	cmp	eax,1bh
	jnz	@@ok
	VMMCall	Get_VMM_Version
	cmp	ah,4		;hier: Windows95 erforderlich!
	ret			;Win 3.11 VXDLDR untersttzt keine PM-API
@@ok:	clc
	ret
EndProc KCEMU_Ctl
VxD_Locked_Code_ends

;********************************************************
;*** Residenter Datenbereich und Konstantendefinition ***
;********************************************************

;API-Beschreibung (Parameter-šbergabe via FAR-PASCAL-Stack-Rahmen):
;AH=0 Versionsnummer holen, PA: AH=Major, AL=Minor
;AH=1 PageAlloc, PE: WORD Kilobytes (=0: 64K-Fenster), PA: AX: Selektor
;AH=2 PageFree, PE: WORD Selektor, PA: AX=0 wenn OK
;AH=3 PageMap, ???
;AH=5 Benutzungs-Z„hler setzen, PE: INT Inkrement, PA: (neuer) Z„hlerstand

;**********************
;*** API-Funktionen ***
;**********************

VxD_Locked_Data_Seg
Usage	dd	0
List	dd	?
FFPage	dd	?
struc TListNode
hmem	dd	?	;Speicher-Handle von _PageAllocate
sel	dw	?	;Selektor
inst	dw	?	;HInstance (=DS der anfordernden Anwendung)
ends
AListNode TListNode <>
VxD_Locked_Data_Ends

VxD_Locked_Code_Seg
KCEMU_Dynamic_Init:		;Einsprung Dynamische Initialisierung
	VMMCall	Get_VMM_Version
	cmp	ah,4		;hier: Windows95 erforderlich!!
	ret
proc PageMap
	ret
endp

proc PageFree
	ret
endp

proc PageAlloc
	movzx	eax,[word edi+6]	;Gr”įe des RAM-Bereichs (KB)
	BRES	ah,bit 7		;AlwaysMapped ignorieren
	or	eax,eax
	jz	@@1
	mov	esi,eax			;retten
	add	eax,3
	shr	eax,2			;aufrunden zur 4-KB-Grenze
	VMMCall	_PageAllocate,<eax,PG_VM,ebx,0,0,0,0,PageFixed>
	or	eax,eax			;Speicher-Handle
	jz	@@e
	mov	[AListNode.hmem],eax
	shl	esi,10			;KBytes-->Bytes
	xor	eax,eax
	cmp	esi,10000h		;mehr als 1MB?
	jc	@@s
	add	esi,0C00h		;3 KBytes dazurechnen
	shr	esi,12			;in Pages wandeln
	BSET	eax,D_Gran_Page
@@s:	dec	esi			;L„nge-->Limit
	VMMCall _BuildDescriptorDWords,<edx,esi,RW_Data_Type,eax,0>
@@sel:
	VMMCall _Allocate_LDT_Selector,<ebx,eax,edx,1,0>
	mov	[AListNode.sel],ax	;Selektor in die Liste tun
	mov	[PClient._AX],ax	;Rckgabewert
	mov	ax,[PClient._DS]
	mov	[AListNode.inst],ax
	mov	esi,[List]
	mov	eax,offset AListNode
	VMMCall	List_Attach

@@1:	VMMCall	_PageAllocate,<16,PG_Hooked,ebx,0,0,0,0,0>
	or	eax,eax			;Speicher-Handle
	jz	@@e
	mov	[AListNode.hmem],eax
	push	edx
	 VMMCall _PageAllocate,
	pop	edx
	VMMCall _BuildDescriptorDWords,<edx,0FFFFh,RW_Data_Type,0,0>
	jmp	@@s
@@e:	ret
endp

proc GetVer
	mov	ax,KCEMU_Version
	jmp	SetAX
endp

proc SetUsage
	movsx	eax,[word EDI+6]
	mov	edx,[Usage]
	add	eax,edx
	mov	[Usage],eax
	or	edx,edx
	jnz	SetAX
	or	eax,eax
	jz	SetAX
	push	eax
	 xor	eax,eax
	 mov	ecx,size TListNode
	 VMMCall List_Create		;bei Erstbenutzung anlegen
	 mov	[List],esi
	 VMMCall _PageAllocate,<1,PG_Sys,0,0,0,0,0,PageFixed>
	 mov	[AListNode.hmem],eax
	 mov	edi,edx
	 mov	ecx,400h
	 stc
	 sbb	eax,eax			;FFFFFFFF
	 cld
	 rep	stosd			;Seite mit FF fllen
	 mov	[FFPage],edx		;Lineare Adresse speichern
	 xor	eax,eax
	 mov	[dword AListNode.sel],eax
	 mov	eax,offset AListNode
	 mov	edi,[List]
	 VMMCall List_Attach
	pop	eax
SetAX:	mov	[PClient._AX],ax
	ret
endp

BeginProc KCEMU_Api
	Client_Ptr_Flat eax,ss,bp	;Stack-Rahmen
	xchg	edi,eax			;EDI+6=letzter Parameter
	mov	al,[PClient._AH]	;AH laden
Debug_Out "ApiCall Fkt=#AL"
	cmp	al,1
	jc	GetVer
	jz	PageAlloc
	cmp	al,3
	jc	PageFree
	je	PageMap
	cmp	al,5
	je	SetUsage
	mov	[PClient._AX],1		;Fehlercode (<32 wie bei WinExec)
	ret
EndProc KCEMU_Api

VxD_Locked_Code_Ends

	END
Detected encoding: UTF-80