home *** CD-ROM | disk | FTP | other *** search
- {---------------------------------------------------------------------------}
- { eXtended Memory Specification Unit for Turbo Pascal 6.0 - Version 1.0 }
- { Written by Yuval Tal, 13 Glazer st, Rehovot 76283, Israel Date: 4-Mar-91 }
- { BitNet: NYYUVAL@WEIZMANN InterNet: NYYUVAL@WEIZMANN.WEIZMANN.AC.IL }
- {---------------------------------------------------------------------------}
- { This program may be freely distributed for non-commercial, non-business, }
- { and non-governmental uses, provided this notice is attached with it. My }
- { only request is that if you plan to use it regularly, you let me know of }
- { it through e-mail or postal mail, so that I have an idea of how useful }
- { this program is (if you will add some cash to that letter it would be }
- { nice, ofcourse :-)). Also, if you have any problems, suggestions etc' }
- { please let me know. For more information read the document file. }
- {---------------------------------------------------------------------------}
-
- Unit XMS;
-
- Interface
-
- Var
- Present: Boolean; {True if XMM driver is installed}
- XMSError: Byte; {Error number. If 0 -> no error}
-
- Function XMMPresent: Boolean;
- Function XMSErrorString(Error: Byte): String;
- Function XMSMemAvail: Word;
- Function XMSMaxAvail: Word;
- Function GetXMMVersion: Word;
- Function GetXMSVersion: Word;
- Procedure MoveFromEMB(Handle: Word; Var Dest; BlockLength: LongInt);
- Procedure MoveToEMB(Var Source; Handle: Word; BlockLength: LongInt);
- Function EMBGetMem(Size: Word): Word;
- Procedure EMBFreeMem(Handle: Word);
- Procedure EMBResize(Handle, Size: Word);
- Function GetAvailEMBHandles: Byte;
- Function GetEMBLock(Handle: Word): Byte;
- Function GetEMBSize(Handle: Word): Word;
- Function LockEMB(Handle: Word): LongInt;
- Procedure UnlockEMB(Handle: Word);
- Function UMBGetMem(Size: Word; Var Segment: Word): Word;
- Procedure UMBFreeMem(Segment: Word);
- Function GetA20Status: Boolean;
- Procedure DisableLocalA20;
- Procedure EnableLocalA20;
- Procedure DisableGlobalA20;
- Procedure EnableGlobalA20;
- Procedure HMAGetMem(Size: Word);
- Procedure HMAFreeMem;
- Function GetHMA: Boolean;
-
- Implementation
-
- Uses
- Dos;
-
- Const
- High=1;
- Low=2;
- NumberOfErrors=27;
- ErrorNumber: Array [1..NumberOfErrors] Of Byte = ($80,$81,$82,$8E,$8F,$90,
- $91,$92,$93,$94,$A0,$A1,$A2,$A3,$A4,$A5,$A6,$A7,$A8,$A9,$AA,
- $AB,$AC,$AD,$B0,$B1,$B2);
- ErrorString: Array [0..NumberOfErrors] Of String = (
- 'Unknown error',
- 'Function no implemented',
- 'VDISK device driver was detected',
- 'A20 error occured',
- 'General driver errror',
- 'Unrecoverable driver error',
- 'High memory area does not exist',
- 'High memory area is already in use',
- 'DX is less than the ninimum of KB that program may use',
- 'High memory area not allocated',
- 'A20 line still enabled',
- 'All extended memory is allocated',
- 'Extended memory handles exhausted',
- 'Invalid handle',
- 'Invalid source handle',
- 'Invalid source offset',
- 'Invalid destination handle',
- 'Invalid destination offset',
- 'Invalid length',
- 'Invalid overlap in move request',
- 'Parity error detected',
- 'Block is not locked',
- 'Block is locked',
- 'Lock count overflowed',
- 'Lock failed',
- 'Smaller UMB is available',
- 'No UMBs are available',
- 'Inavlid UMB segment number');
-
- Type
- XMSParamBlock=
- Record
- Length: LongInt;
- SHandle: Word;
- SOffset: Array[High..Low] Of Word;
- DHandle: Word;
- DOffset: Array[High..Low] Of Word;
- End;
-
- Var
- XMSAddr: Array[High..Low] Of Word; {XMM driver address 1=Low,2=High}
-
- {---------------------------------------------------------------------------}
-
- Function XMMPresent: Boolean;
-
- Var
- Regs: Registers;
-
- Begin
- With Regs Do
- Begin
- AX:=$4300;
- Intr($2F,Regs);
- XMMPresent:=AL=$80;
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function XMSErrorString(Error: Byte): String;
-
- Var
- I,Index: Byte;
-
- Begin
- Index:=0;
- For I:=1 To NumberOfErrors Do
- If ErrorNumber[I]=Error Then Index:=I;
- XMSErrorString:=ErrorString[Index];
- End;
-
- {---------------------------------------------------------------------------}
-
- Function XMSMemAvail: Word;
-
- Var
- Memory: Word;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,8
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov Memory,DX
- @@2:
- End;
- XMSMemAvail:=Memory;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function XMSMaxAvail: Word;
-
- Var
- Temp: Word;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,8
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov Temp,AX
- @@2:
- End;
- XMSMaxAvail:=Temp;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function EMBGetMem(Size: Word): Word;
-
- Var
- Temp: Word;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,9
- Mov DX,Size
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov Temp,DX
- @@2:
- End;
- EMBGetMem:=Temp;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure EMBFreeMem(Handle: Word);
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,0Ah
- Mov DX,Handle
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure EMBResize(Handle, Size: Word);
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,0Fh
- Mov DX,Handle
- Mov BX,Size
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure MoveToEMB(Var Source; Handle: Word; BlockLength: LongInt);
-
- Var
- ParamBlock: XMSParamBlock;
- XSeg,PSeg,POfs: Word;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- With ParamBlock Do
- Begin
- Length:=BlockLength;
- SHandle:=0;
- SOffset[High]:=Ofs(Source);
- SOffset[Low]:=Seg(Source);
- DHandle:=Handle;
- DOffset[High]:=0;
- DOffset[Low]:=0;
- End;
- PSeg:=Seg(ParamBlock);
- POfs:=Ofs(ParamBlock);
- XSeg:=Seg(XMSAddr);
-
- Asm
- Push DS
- Mov AH,0Bh
- Mov SI,POfs
- Mov BX,XSeg
- Mov ES,BX
- Mov BX,PSeg
- Mov DS,BX
- Call [ES:XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- Pop DS
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure MoveFromEMB(Handle: Word; Var Dest; BlockLength: LongInt);
-
- Var
- ParamBlock: XMSParamBlock;
- XSeg,PSeg,POfs: Word;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- With ParamBlock Do
- Begin
- Length:=BlockLength;
- SHandle:=Handle;
- SOffset[High]:=0;
- SOffset[Low]:=0;
- DHandle:=0;
- DOffset[High]:=Ofs(Dest);
- DOffset[Low]:=Seg(Dest);
- End;
- PSeg:=Seg(ParamBlock);
- POfs:=Ofs(ParamBlock);
- XSeg:=Seg(XMSAddr);
-
- Asm
- Push DS
- Mov AH,0Bh
- Mov SI,POfs
- Mov BX,XSeg;
- Mov ES,BX
- Mov BX,PSeg
- Mov DS,BX
- Call [ES:XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- Pop DS
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function GetXMSVersion: Word;
-
- Var
- HighB, LowB: Byte;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,0
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov HighB,AH
- Mov LowB,AL
- @@2:
- End;
- GetXMSVersion:=(HighB*100)+LowB;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function GetXMMVersion: Word;
-
- Var
- HighB, LowB: Byte;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,0
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov HighB,BH
- Mov LowB,BL
- @@2:
- End;
- GetXMMVersion:=(HighB*100)+LowB;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function GetHMA: Boolean;
-
- Var
- Temp: Boolean;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Temp:=False;
- Asm
- Mov AH,0
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Cmp DX,0
- Je @@2
- Mov Temp,1
- @@2:
- End;
- GetHMA:=Temp;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure HMAGetMem(Size: Word);
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,1
- Mov DX,Size
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure HMAFreeMem;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,2
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure EnableGlobalA20;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,3
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
-
- {---------------------------------------------------------------------------}
-
- Procedure DisableGlobalA20;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,4
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure EnableLocalA20;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,5
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure DisableLocalA20;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,6
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function GetA20Status: Boolean;
-
- Var
- Temp: Boolean;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Temp:=True;
- Asm
- Mov AH,6
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Or AX,AX
- Jne @@1
- Or BL,BL
- Jne @@2
- Mov Temp,0
- Jmp @@1
- @@2:
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function LockEMB(Handle: Word): LongInt;
-
- Var
- Temp1,Temp2: Word;
- Temp: LongInt;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,0Ch
- Mov DX,Handle
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov Temp1,DX
- Mov Temp2,BX
- @@2:
- End;
- Temp:=Temp1;
- LockEMB:=(Temp Shl 4)+Temp2;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure UnlockEMB(Handle: Word);
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,0Dh
- Mov DX,Handle
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function GetEMBSize(Handle: Word): Word;
-
- Var
- Temp: Word;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,0Eh
- Mov DX,Handle
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov Temp,DX
- @@2:
- End;
- GetEMBSize:=Temp;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function GetEMBLock(Handle: Word): Byte;
-
- Var
- Temp: Byte;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,0Eh
- Mov DX,Handle
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov Temp,BH
- @@2:
- End;
- GetEMBLock:=Temp;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function GetAvailEMBHandles: Byte;
-
- Var
- Temp: Byte;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,0Eh
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov Temp,BL
- @@2:
- End;
- GetAvailEMBHandles:=Temp;
- End;
-
- {---------------------------------------------------------------------------}
-
- Function UMBGetMem(Size: Word; Var Segment: Word): Word; {Actual size}
-
- Var
- Temp1,Temp2: Word;
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,10h
- Mov DX,Size
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- Jmp @@2
- @@1:
- Mov Temp2,BX
- @@2:
- Mov Temp1,DX
- End;
- Segment:=Temp2;
- UMBGetMem:=Temp1;
- End;
-
- {---------------------------------------------------------------------------}
-
- Procedure UMBFreeMem(Segment: Word);
-
- Begin
- XMSError:=0;
- If Not(Present) Then Exit;
- Asm
- Mov AH,10h
- Mov DX,Segment
- Call [XMSAddr]
- Or AX,AX
- Jne @@1
- Mov XMSError,BL
- @@1:
- End;
- End;
-
- {---------------------------------------------------------------------------}
-
- Var
- Regs: Registers;
-
- Begin
- If Not(XMMPresent) Then
- Begin
- WriteLn('XMS not supported!');
- Present:=False;
- Exit;
- End;
- Present:=True;
- With Regs Do
- Begin
- AX:=$4310;
- Intr($2F,Regs);
- XMSAddr[High]:=BX;
- XMSAddr[Low]:=ES;
- End;
- End.
-