unit My_Mem; INTERFACE CONST SegEMMFrame : word = $d000; EMMVersion : byte = $32; AbsEMM : pointer = Ptr($D000,0); Type EMMRec = record EMMHandle : word; PageCount : word; end; Function InitEMM:boolean; Function TestAllocEMM(asize : LongInt):boolean; Function AllocEMM(aSize : longInt;var aRec:EMMRec):boolean; Function FreeEMM(var aRec:EMMRec):boolean; Function MapEMMMemory(aRec:EMMRec;aPageBeg,aPageEnd:word):boolean; Function MaxEMM:LongInt; IMPLEMENTATION CONST EMMInited : boolean = false; type EMSMoveInfoRec = record RngLen : LongInt; SrcType : byte; SrcHandle : word; SrcAddress : word; SrcOffset : word; DestType : byte; DestHandle : word; DestAddress: word; DestOffset : word; end; {-------------} Function MoveEMMMemory(var aRec:EMSMoveInfoRec):byte;assembler; asm push ds mov ax, 5700h lds di, aRec int 67h mov al, ah mov ah, 0 pop ds end;{MoveEMMMemory} {------------------} Function GetEMMStatus:byte;assembler; asm mov ax, 4000h int 67h mov al, ah mov ah, 0 end;{GetEMMStatus} {---------------------------------} Function TestEMMInstalled:Boolean;assembler; asm mov ax, 3d00h mov dx, offset @@Name push ds push cs pop ds int 21h pop ds jc @@NoEMS mov bx, ax mov ax, 4407h int 21h test al, al mov ah, 3eh int 21h jnz @@EMS jmp @@NoEMS @@EMS: mov ax, 1 ret @@NoEMS: xor ax,ax ret @@Name: db 'EMMXXXX0',0 end;{TestEMMInstalled} {--------------------------} Function GetEmmFrameSeg(var aSeg:word):byte;assembler; asm mov ax, 4100h int 67h les di, aSeg mov es:[di], bx mov al, ah mov ah, 0 end;{GetEmmFrameSeg} {-----------------------------------} Function GetEmmVersion(var aVer:byte):byte;assembler; asm mov ax, 4600h int 67h les di, aVer mov es:[di], al mov al, ah mov ah, 0 end;{GetEmmFrameSeg} {-----------------------------------} Function InitEMM; begin InitEMM := false; if TestEMMInstalled then if (GetEmmStatus = 0) and (GetEmmFrameSeg(SegEMMFrame) = 0) and (GetEMMVersion(EMMVersion)=0) then begin AbsEMM := Ptr(SegEMMFrame,0); EMMInited := true; InitEMM:=true; end; end;{InitEMM} {---------------} Function GetMaxPages(var a:word):byte;assembler; asm mov ax, 4200h int 67h les di, a mov es:[di], bx mov al, ah mov ah, 0 end;{GetMaxPages} {----------------------} Function MaxEMM; var MaxMem : longint; Pages : word; begin MaxEMM:=0; if not EMMInited then exit; if GetMaxPages(Pages) = 0 then begin MaxMem := Pages; MaxEMM := MaxMem shl 14; end end;{MaxEMM} {----------------------} Function TestAllocEMM(asize : LongInt):boolean; var MaxPages : word; begin TestAllocEMM:=false; if not EMMInited then exit; if GetMaxPages(MaxPages) = 0 then if MaxPages > ((aSize shr 14)+1) then TestAllocEMM := true; end;{TestAlloc} {------------------------} Function AllocEMMPages(var aHandle:word;aP:word):byte;assembler; asm mov ax, 4300h mov bx, aP int 67h les di, aHandle mov es:[di], dx mov al, ah mov ah, 0 end;{AllocEMMPages} {---------------------------} Function AllocEMM(aSize : longInt;var aRec:EMMRec):boolean; begin AllocEMM:=false; if not EMMInited then exit; aRec.PageCount := aSize shr 14; if (aSize mod 16384) <> 0 then Inc(aRec.PageCount); if AllocEMMPages(aRec.EMMHandle,aRec.PageCount) = 0 then AllocEMM:=true; end;{AllocEMM} {------------------------} Function FreeEMMPages(aHandle:word):byte;assembler; asm mov ax, 4500h mov dx, word ptr aHandle int 67h mov al, ah mov ah, 0 end;{FreeEMMPages} {---------------------------} Function FreeEMM(var aRec:EMMRec):boolean; begin FreeEMM:=false; if not EMMInited then exit; if FreeEMMPages(aRec.EMMHandle) = 0 then with aRec do begin EMMHandle := 0; PageCount := 0; FreeEMM:=true; end; end; {----------------------} Function MapEMMPages(aHandle,aPageBeg,aPageEnd:word):byte;assembler; asm mov al, 0 mov bx, aPageBeg mov dx, word ptr aHandle @@LOOP: mov ah, 44h int 67h test ah, ah jnz @@OUT inc al inc bx cmp bx, aPageEnd jnz @@LOOP @@OUT: mov al, ah mov ah, 0 end;{MapEMMPages} {--------------------------------} Function MapEMMMemory; begin MapEMMMemory:=false; if not EMMInited then exit; if (aPageBeg>aPageEnd) or (aPageEnd > aRec.PageCount) or ((aPageEnd - aPageBeg) > 3) then exit; if MapEMMPages(aRec.EMMHandle,aPageBeg,aPageEnd+1) = 0 then MapEMMMemory:=true; end; END.