home *** CD-ROM | disk | FTP | other *** search
- {This unit is a kit to EMS functions.}
-
- Unit EMSLib;
- { Copyright (c) 1994 by Andrew Eigus FidoNet: 2:5100/33 }
- { LIM EMS Interface V1.01 for Turbo Pascal version 7.0 }
-
- (*
- Material used:
- Interrupt List V1.02 (WindowBook) (c) 1984-90 Box Company, Inc.
- Tech Help V4.50
- *)
-
- {$X+} { Enable extended syntax }
- {$G+} { Enable 286 instructions }
-
- interface
-
- const
-
- PageSize = 16384; { EMS Page size: 16384 bytes }
-
- { LIM EMS 3+ function numbers }
-
- EGetPageFrame = $41;
- EGetPageCount = $42;
- EAllocPages = $43;
- EMapPages = $44;
- EReleasePages = $45;
- EGetVersion = $46;
-
- { LIM EMS functions result codes }
-
- emsrOk = $00; { Function successful }
- emsrNotInitd = $01; { EMS not installed }
- emsrIntrnlError = $80; { Internal error }
- emsrHardwareMalf = $81; { Hardware malfunction }
- emsrBadHandle = $83; { Invalid handle }
- emsrBadFunction = $84; { Undefined function requested }
- emsrNoMoreHandles = $85; { No more handles available }
- emsrMapContError = $86; { Error in save or restore of mapping context }
- emsrMorePagesPhys = $87; { More pages requested than physically exist }
- emsrMorePagesCurr = $88; { More pages requested than currently available }
- emsrZeroPages = $89; { Zero pages requested }
- emsrBadPageLogNum = $8A; { Invalid page logical number }
- emsrBadPagePhyNum = $8B; { Invalid page physical number }
-
- function EMS_Setup : boolean;
- function EMS_GetVersion(var Version : byte) : byte;
- function EMS_GetMemAvail(var FreeMem : word) : byte;
- function EMS_AllocEMB(var Handle, PageSeg : word; Pages : word) : byte;
- function EMS_FreeEMB(Handle : word) : byte;
- function EMS_MapPages(Handle, LogicalPage : word; PhysicalPage : byte) : byte;
-
- function EMS_GetErrorMsg(ErrorCode : byte) : string;
-
- implementation
-
- const
- DOS = $21; { DOS interrupt number }
- EMS = $67; { EMS interrupt number }
-
- var
- EMSInitd : boolean;
-
- Function EMS_Setup; assembler;
- { EMM Installation check }
- const DeviceDriver : PChar = 'EMMXXXX0';
- Asm
- MOV EMSInitd,False
- PUSH DS
- MOV AX,3D02h { DOS function to open the device as file }
- LDS DX,DeviceDriver
- INT DOS
- POP DS
- JC @@1
- PUSH AX { store device handle to close the file afterwards }
- MOV AX,4407h { DOS function to test device status }
- INT DOS
- MOV EMSInitd,AL
- POP BX
- MOV AH,3Eh { close the file using it's handle in BX }
- INT DOS
- @@1:
- MOV AL,EMSInitd
- End; { EMS_Setup }
-
- Function EMS_GetVersion; assembler;
- { Get Expanded Memory Manager version number }
- Asm
- MOV AL,emsrNotInitd
- CMP EMSInitd,False { If library not initialized by EMS_Setup }
- JE @@1 { then exit }
- MOV AH,EGetVersion { Get EMS version }
- INT EMS
- LES DI,Version
- MOV [ES:DI],AL { Store version number }
- MOV AL,AH { Store result byte }
- @@1:
- End; { EMS_GetVersion }
-
- Function EMS_GetMemAvail; assembler;
- { Returns free memory in FreeMem parameter }
- Asm
- MOV AL,emsrNotInitd
- CMP EMSInitd,False
- JE @@1
- MOV AH,EGetPageCount
- INT EMS
- SHL BX,4 { Got in pages, convert to K-bytes }
- LES DI,FreeMem
- MOV [ES:DI],BX { Store memory available in K-Bytes }
- MOV AL,AH { Store result byte }
- @@1:
- End; { EMS_GetMemAvail }
-
- Function EMS_AllocEMB; assembler;
- { Allocates specified number of 16 K-byte pages and returns handle number in
- Handle parameter. Page frame segment address stored in PageSeg. To access
- data, use the following function:
- DataPtr := Ptr(PageSeg, PhysicalPageNumber * PageSize) }
- Asm
- MOV AL,emsrNotInitd
- CMP EMSInitd,False
- JE @@2
- MOV AH,EGetPageFrame
- INT EMS
- CMP AH,0
- JNE @@1
- LES DI,PageSeg { Store page frame segment }
- MOV [ES:DI],BX
- MOV BX,Pages
- MOV AH,EAllocPages
- INT EMS
- LES DI,Handle
- MOV [ES:DI],DX { Store handle number }
- @@1:
- MOV AL,AH { Return result code }
- @@2:
- End; { EMS_AllocEMB }
-
- Function EMS_FreeEMB; assembler;
- { Deallocates (releases) allocated expanded memory }
- Asm
- MOV AL,emsrNotInitd
- CMP EMSInitd,False
- JE @@1
- MOV AH,EReleasePages
- MOV DX,Handle
- INT EMS
- MOV AL,AH { Return result code }
- @@1:
- End; { EMS_FreeEMB }
-
- Function EMS_MapPages; assembler;
- { Maps a logical page number at physical page number }
- Asm
- MOV AL,emsrNotInitd
- CMP EMSInitd,False
- JE @@1
- MOV AH,EMapPages
- MOV DX,Handle
- MOV BX,LogicalPage
- MOV AL,PhysicalPage
- INT EMS
- MOV AL,AH
- @@1:
- End; { EMS_MapPages }
-
- Function EMS_GetErrorMsg;
- { Get an error message according to ErrorCode }
- Begin
- case ErrorCode of
- emsrNotInitd: EMS_GetErrorMsg := 'EMM not initialized';
- emsrIntrnlError: EMS_GetErrorMsg := 'Internal error';
- emsrHardwareMalf: EMS_GetErrorMsg := 'Hardware malfunction';
- emsrBadHandle: EMS_GetErrorMsg := 'Invalid block handle';
- emsrBadFunction: EMS_GetErrorMsg := 'Function not implemented';
- emsrNoMoreHandles: EMS_GetErrorMsg := 'No more handles available';
- emsrMapContError: EMS_GetErrorMsg := 'Error in save or restore of ' +
- 'mapping context';
- emsrMorePagesPhys: EMS_GetErrorMsg := 'More pages requested than ' +
- 'physically exist';
- emsrMorePagesCurr: EMS_GetErrorMsg := 'More pages requested than ' +
- 'currently available';
- emsrZeroPages: EMS_GetErrorMsg := 'Zero pages requested';
- emsrBadPageLogNum: EMS_GetErrorMsg := 'Invalid page logical number';
- emsrBadPagePhyNum: EMS_GetErrorMsg := 'Invalid page physical number';
- else EMS_GetErrorMsg := 'Unknown error'
- end
- End; { EMS_GetErrorMsg }
-
- Begin
- EMSInitd := False
- End. { EMSLib }
-
- { -------------------------- DEMO --------------------------------- }
-
- Program EMSLibDemo;
- { Copyright (c) 1994 by Andrew Eigus FidoNet: 2:5100/33 }
- { LIM EMS Interface V1.01 for Turbo Pascal version 7.0 demonstration program }
-
- (*
- Tested on IBM 486 SX 33Mhz with 4MB RAM with the following configuration:
- HIMEM.SYS (MS-DOS 6.2 XMS memory manager)
- EMM386.EXE (MS-DOS 6.2 EMS memory manager)
-
- If any bugs occur in your system while running this demo,
- please inform me:
-
- AndRew's BBS Phone: 003-712-559777 (Riga, Latvia) 24h 2400bps
- Voice Phone: 003-712-553218
- FidoNet: 2:5100/33
- E-Mail: aeigus@fgate.castle.riga.lv
- *)
-
- {$X+}{$R-} { Enable extended syntax }
-
- uses EMSLib;
-
- type TMsg = array[1..13] of Char;
-
- const
- Message1 : TMsg = 'First string ';
- Message2 : TMsg = 'Second string';
-
- var
- Version : byte;
- FreeMemory, Handle, SegAddr, I : word;
- P : pointer;
-
- Function Hex(Num : longint; Places : byte) : string;
- const HexTab : array[0..15] of Char = '0123456789ABCDEF';
- var
- HS : string[8];
- Digit : byte;
- Begin
- HS[0] := Chr(Places);
- for Digit := Places downto 1 do
- begin
- HS[Digit] := HexTab[Num and $0000000F];
- Num := Num shr 4
- end;
- Hex := HS
- End; { Hex }
-
- Function Check(Result : byte; Func : string) : byte;
- Begin
- if Result <> emsrOk then
- WriteLn(Func, ' returned ',
- Hex(Result, 2), 'h (', Result, '): ', EMS_GetErrorMsg(Result));
- Check := Result
- End; { Check }
-
- Procedure PrintFreeMemory;
- Begin
- WriteLn;
- if Check(EMS_GetMemAvail(FreeMemory), 'EMS_GetMemAvail') = emsrOk then
- WriteLn('EMS memory available: ', FreeMemory, ' KB');
- WriteLn
- End; { PrintFreeMemory }
-
- Begin
- WriteLn('LIM EMS Library V1.01 Demonstration program by Andrew Eigus'#10);
- if EMS_Setup then
- begin
- if Check(EMS_GetVersion(Version), 'EMS_GetVersion') = emsrOk then
- WriteLn('EMS driver version ',
- Version shr 4, '.', Version shr 8, ' detected');
- PrintFreeMemory;
- if FreeMemory = 0 then Halt(8);
- if Check(EMS_AllocEMB(Handle, SegAddr, 1), 'EMS_AllocEMB') = emsrOk then
- begin
- WriteLn('Message1: ', Message1);
- WriteLn('Message2: ', Message2);
- WriteLn('16 KB (one page) of EMS allocated. Linear address: ',
- Hex(SegAddr, 8), 'h');
- PrintFreeMemory;
- WriteLn('Transferring Message1 to EMS...');
- for I := 0 to SizeOf(TMsg) - 1 do
- EMS_MapPages(Handle, I, 0);
- P := Ptr(SegAddr, 0);
- Move(Message1, P^, SizeOf(TMsg));
- WriteLn('Transferring Message1 from EMS to Message2...');
- Move(P^, Message2, SizeOf(TMsg));
- WriteLn('Message1: ', Message1);
- WriteLn('Message2: ', Message2);
- if Check(EMS_FreeEMB(Handle), 'EMS_FreeEMB') = emsrOk then
- begin
- WriteLn('Memory deallocated (released). ');
- PrintFreeMemory
- end
- end
- end else
- WriteLn('EMM386 manager not installed.');
- End.