123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517 |
- { $Id$ }
- {********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
- { }
- { DOS System XMS control unit }
- { }
- { Extracted from my original OBJECTS.PAS unit. }
- { }
- { Copyright (c) 1998 by Leon de Boer }
- { [email protected] - primary e-mail address }
- { [email protected] - backup e-mail address }
- { }
- {****************[ THIS CODE IS FREEWARE ]*****************}
- { }
- { This sourcecode is released for the purpose to }
- { promote the pascal language on all platforms. You may }
- { redistribute it and/or modify with the following }
- { DISCLAIMER. }
- { }
- { This SOURCE CODE is distributed "AS IS" WITHOUT }
- { WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
- { ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
- { }
- {*****************[ SUPPORTED PLATFORMS ]******************}
- { }
- { DOS - Turbo Pascal 7.0 + (16 Bit) }
- { }
- {******************[ REVISION HISTORY ]********************}
- { Version Date Fix }
- { ------- --------- --------------------------------- }
- { 1.00 31 Aug 98 First release moved from original }
- { objects unit. }
- {**********************************************************}
- UNIT XMSUnit;
- {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
- INTERFACE
- {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
- {====Include file to sort compiler platform out =====================}
- {$I Platform.inc}
- {====================================================================}
- {==== Compiler directives ===========================================}
- {$IFNDEF FPC}{ FPC doesn't support these switches }
- {$F+} { Force far calls }
- {$A+} { Word Align Data }
- {$B-} { Allow short circuit boolean evaluations }
- {$O+} { This unit may be overlaid }
- {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
- {$E+} { Emulation is on }
- {$N-} { No 80x87 code generation }
- {$ENDIF}
- {$X+} { Extended syntax is ok }
- {$R-} { Disable range checking }
- {$S-} { Disable Stack Checking }
- {$I-} { Disable IO Checking }
- {$Q-} { Disable Overflow Checking }
- {$V-} { Turn off strict VAR strings }
- {====================================================================}
- {$IFNDEF PROC_Real}
- This UNIT can only compile under DOS REAL MODE!!!!
- {$ENDIF}
- {***************************************************************************}
- { PUBLIC CONSTANTS }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { STANDARD XMS ERROR STATE CONSTANTS }
- {---------------------------------------------------------------------------}
- CONST
- XMSInvalidFunc = $80; { Invalid function }
- XMSVDiskDetect = $81; { VDisk detected }
- XMSA20GateError = $82; { A20 gating error }
- XMSGeneralError = $8E; { General error }
- XMSNoHMA = $90; { HMA does not exist }
- XMSHMAInUse = $91; { HMA already in use }
- XMSHMAMinError = $92; { HMA < /HMAMIN param }
- XMSHMANotAlloc = $93; { HMA not allocated }
- XMSA20Enabled = $94; { A20 still enabled }
- XMSNoXMSLeft = $A0; { All XMS allocated }
- XMSNoXMSHandle = $A1; { All handles used }
- XMSHandleInvalid = $A2; { Invalid XMS handle }
- XMSInvSrcHandle = $A3; { Invalid Source Handle }
- XMSInvSrcOffset = $A4; { Invalid Source Offset }
- XMSInvDestHandle = $A5; { Invalid Dest Handle }
- XMSInvDestOffset = $A6; { Invalid Dest Offset }
- XMSInvXferLength = $A7; { Invalid Length }
- XMSOverlapError = $A8; { Move has overlap }
- XMSParityError = $A9; { XMS parity error }
- XMSBlkNotLocked = $AA; { Block not locked }
- XMSBlockLocked = $AB; { Block is locked }
- XMSLockCountOver = $AC; { Lock count overflow }
- XMSLockFailed = $AD; { Lock failed }
- XMSSmallerUMB = $B0; { Smaller UMB avail }
- XMSNoUMBAvail = $B1; { No UMB's available }
- XMSUMBSegInvalid = $B2; { Invalid UMB segment }
- XMSNotPresent = $FF; { No XMS driver found }
- {***************************************************************************}
- { INTERFACE ROUTINES }
- {***************************************************************************}
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { XMS INTERFACE ROUTINES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {-IsXMSPresent-------------------------------------------------------
- Returns true/false as to the availability of XMS support functions.
- 31Aug98 LdB
- ---------------------------------------------------------------------}
- FUNCTION IsXMSPresent: Boolean;
- {-XMS_Version--------------------------------------------------------
- If XMS functions are available returns the version of XMS support that
- is supported. If no XMS support or error is encountered returns zero.
- 31Aug98 LdB
- ---------------------------------------------------------------------}
- FUNCTION XMS_Version: Word;
- {-XMS_MaxAvail-------------------------------------------------------
- If XMS functions are available returns the maximum XMS memory available
- if none was in use. No XMS support or error will return zero.
- 31Aug98 LdB
- ---------------------------------------------------------------------}
- FUNCTION XMS_MaxAvail: LongInt;
- {-XMS_MemAvail-------------------------------------------------------
- If XMS functions are available returns the XMS memory that is currently
- available. No XMS support or error will return zero.
- 31Aug98 LdB
- ---------------------------------------------------------------------}
- FUNCTION XMS_MemAvail: LongInt;
- {-XMS_GetMem---------------------------------------------------------
- If XMS functions are available and enough XMS memory is available the
- requested KB of xms is allocated and the XMS handle returned. No XMS
- support or error will return a zero handle.
- 31Aug98 LdB
- ---------------------------------------------------------------------}
- FUNCTION XMS_GetMem (KbSize: Word): Word;
- {-XMS_FreeMem--------------------------------------------------------
- If XMS functions are available and a valid XMS handle is given the XMS
- memory belonging to the handle is release and true returned. No XMS
- support, an invalid handle or an error will return a false result.
- 31Aug98 LdB
- ---------------------------------------------------------------------}
- FUNCTION XMS_FreeMem (Handle : Word): Boolean;
- {-XMS_ResizeMem------------------------------------------------------
- If XMS functions are available and enough XMS memory is available and
- a valid XMS handle is given the new XMS size will be allocated and
- all the data in the old memory will be moved to the new memory. No XMS
- support, insufficient XMS memory or error will return an XMS error state
- while successful operations will return zero.
- 31Aug98 LdB
- ---------------------------------------------------------------------}
- FUNCTION XMS_ResizeMem (OldSize, NewSize: Word; Var Handle: Word): Byte;
- {-XMS_MoveMem--------------------------------------------------------
- If XMS functions are available size amount of data held in FromAddress
- is transfered to the ToAddress. The handles can be XMS handles if the
- associated address is an XMS offset or zero if the address refers to
- a real mode address. No XMS support or error will return an XMS error
- state while successful operations will return zero.
- 31Aug98 LdB
- ---------------------------------------------------------------------}
- FUNCTION XMS_MoveMem (ToAddress: LongInt; ToHandle: Word; FromAddress: LongInt;
- FromHandle: Word; Size: LongInt): Byte;
- {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
- IMPLEMENTATION
- {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
- {***************************************************************************}
- { PRIVATE INITIALIZED VARIABLES }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { INITIALIZED XMS PRIVATE VARIABLES }
- {---------------------------------------------------------------------------}
- CONST
- XMSPresent : Boolean = False; { XMS present state }
- XMSInit : Boolean = False; { XMS ready flag }
- XMSReAlloc : Boolean = False; { XMS reallocatable }
- XMSEntryAddr: Pointer = Nil; { XMS entry address }
- {***************************************************************************}
- { PRIVATE INTERNAL ROUTINES }
- {***************************************************************************}
- {---------------------------------------------------------------------------}
- { InitializeXMS -> Platforms DOS - Checked 27Jan97 LdB }
- {---------------------------------------------------------------------------}
- PROCEDURE InitializeXMS; ASSEMBLER;
- ASM
- CMP [XMSInit], True; { XMS initialized }
- JZ @@Exit;
- XOR BX, BX;
- MOV ES, BX; { Zero out registers }
- MOV AX, 4310H;
- INT 2FH; { Driver entry point }
- MOV AX, ES;
- OR AX, BX; { Entry point check }
- JZ @@Exit;
- MOV [XMSPresent], True; { XMS is present }
- MOV XMSEntryAddr.Word[0], BX;
- MOV XMSEntryAddr.Word[2], ES; { Hold entry address }
- MOV AH, 09H;
- MOV DX, 0001H; { Allocate 1k block }
- CALL POINTER [XMSEntryAddr];
- PUSH DX; { Hold handle 1 }
- MOV AH, 09H;
- MOV DX, 0001H; { Allocate 1K block }
- CALL POINTER [XMSEntryAddr];
- MOV BX, DX; { Hold handle 2 }
- POP DX;
- PUSH BX; { Save handle 2 }
- PUSH DX; { Save handle 1 }
- MOV AH, 0FH;
- MOV BX, 0020H; { Realloc 32K block }
- CALL POINTER [XMSEntryADDR];
- OR AX, AX; { Chk success 0=fail }
- JZ @@ReAllocateFail;
- MOV BYTE PTR [XMSReAlloc], True; { XMS reallocate - IBM }
- @@ReAllocateFail:
- POP DX; { Recover handle 1 }
- MOV AH, 0AH;
- CALL POINTER [XMSEntryAddr]; { Release all blocks }
- POP DX; { Recover handle 2 }
- MOV AH, 0AH;
- CALL POINTER [XMSEntryAddr]; { Release all blocks }
- @@Exit:
- MOV [XMSInit], True; { XMS initialized }
- END;
- {---------------------------------------------------------------------------}
- { XMS_EvenMoveMem -> Platforms DOS - Checked 27Jan97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION XMS_EvenMoveMem (ToAddress: LongInt; ToHandle: Word; FromAddress: LongInt;
- FromHandle: Word; Size: LongInt): Byte; ASSEMBLER;
- ASM
- CMP BYTE PTR [XMSInit], True; { Is XMS initialized }
- JZ @@XMSInitialized;
- CALL InitializeXMS; { Initialize XMS }
- @@XMSInitialized:
- MOV BL, XMSNotPresent; { Preset error }
- CMP XMSPresent, True; { XMS present }
- JNZ @@XMSError; { No XMS so exit }
- MOV AH, 0BH; { Move function }
- LEA SI, Size; { Address of size }
- PUSH DS;
- POP ES; { Load data segment }
- PUSH SS;
- POP DS;
- CALL ES:[XMSEntryAddr]; { Call XMS handler }
- PUSH ES;
- POP DS;
- CMP AX, 1; { Check for AX=1 }
- JNZ @@XMSError; { Jump on error }
- MOV BL, 0H; { Clear error status }
- @@XMSError:
- MOV AL, BL; { Function failed }
- @@Exit:
- END;
- {***************************************************************************}
- { INTERFACE ROUTINES }
- {***************************************************************************}
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- { XMS INTERFACE ROUTINES }
- {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
- {---------------------------------------------------------------------------}
- { IsXMSPresent -> Platforms DOS - Checked 27Jan97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION IsXMSPresent: Boolean; ASSEMBLER;
- ASM
- CMP BYTE PTR [XMSInit], True; { Is XMS initialized }
- JZ @@XMSInitialized; { Jump if initialized }
- CALL InitializeXMS; { Initialize XMS }
- @@XMSInitialized:
- MOV AL, [XMSPresent]; { Return result }
- END;
- {---------------------------------------------------------------------------}
- { XMS_Version -> Platforms DOS - Checked 27Jan97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION XMS_Version: Word; ASSEMBLER;
- ASM
- CMP BYTE PTR [XMSInit], True; { Is XMS initialized }
- JZ @@XMSInitialized; { Jump if initialized }
- CALL InitializeXMS; { Initialize XMS }
- @@XMSInitialized:
- CMP XMSPresent, True; { Check XMS present }
- JNZ @@XMSError; { Jump if no XMS }
- MOV AH, 0H; { XMS version call id }
- CALL POINTER [XMSEntryAddr]; { XMS handler call }
- JMP @@Exit; { Now exit }
- @@XMSError:
- XOR AX, AX; { Return zero }
- @@Exit:
- END;
- {---------------------------------------------------------------------------}
- { XMS_MaxAvail -> Platforms DOS - Checked 27Jan97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION XMS_MaxAvail: LongInt; ASSEMBLER;
- ASM
- CMP BYTE PTR [XMSInit], True; { Is XMS initialized }
- JZ @@XMSInitialized; { Jump if initialized }
- CALL InitializeXMS; { Initialize XMS }
- @@XMSInitialized:
- CMP XMSPresent, True; { Check XMS present }
- JNZ @@XMSError; { Jump if no XMS }
- MOV AH, 08H; { Query memory call id }
- CALL POINTER [XMSEntryAddr]; { XMS handler call }
- OR BL, BL; { Check for error }
- JZ @@Exit; { Exit on no error }
- @@XMSError:
- XOR AX, AX; { Return zero }
- @@Exit: { AX = Kilobytes }
- XOR DX, DX; { Clear register }
- MOV CX, 000AH; { 1 SHL 10 = 1K }
- DB $0F; DB $A5; DB $C2; { SHL DX:AX, CL}
- SHL AX, CL; { Roll lower word }
- END;
- {---------------------------------------------------------------------------}
- { XMS_MemAvail -> Platforms DOS - Checked 27Jan97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION XMS_MemAvail: LongInt; ASSEMBLER;
- ASM
- CMP BYTE PTR [XMSInit], True; { Is XMS initialized }
- JZ @@XMSInitialized; { Jump if initialized }
- CALL InitializeXMS; { Initialize XMS }
- @@XMSInitialized:
- CMP XMSPresent, True; { Check XMS present }
- JNZ @@XMSError; { Jump if no XMS }
- MOV AH, 08H; { Query memory call id }
- CALL POINTER [XMSEntryAddr]; { XMS handler call }
- MOV AX, DX; { Transfer register }
- OR BL, BL; { Check for error }
- JZ @@Exit; { Exit on no error }
- @@XMSError:
- XOR AX, AX; { Return zero }
- @@Exit: { AX = Kilobytes }
- XOR DX, DX; { Clear register }
- MOV CX, 000AH; { 1 SHL 10 = 1K }
- DB $0F; DB $A5; DB $C2; { SHL DX:AX, CL}
- SHL AX, CL; { Roll lower word }
- END;
- {---------------------------------------------------------------------------}
- { XMS_GetMem -> Platforms DOS - Checked 27Jan97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION XMS_GetMem (KbSize: Word): Word; ASSEMBLER;
- ASM
- CMP BYTE PTR [XMSInit], True; { Is XMS initialized }
- JZ @@XMSInitialized; { Jump if initialized }
- CALL InitializeXMS; { Initialize XMS }
- @@XMSInitialized:
- CMP XMSPresent, True; { Check XMS present }
- JNZ @@XMSError; { Jump if no XMS }
- MOV AH, 09H; { Allocate blocks id }
- MOV DX, [KbSize]; { Size to allocate }
- CALL [XMSEntryAddr]; { Call XMS handler }
- CMP AX, 1; { Check for AX=1 }
- JZ @@Exit; { Jump on no error }
- @@XMSError:
- XOR DX, DX; { Clear handle }
- @@Exit:
- MOV AX, DX; { Transfer register }
- END;
- {---------------------------------------------------------------------------}
- { XMS_FreeMem -> Platforms DOS - Checked 27Jan97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION XMS_FreeMem (Handle : Word): Boolean; ASSEMBLER;
- ASM
- CMP BYTE PTR [XMSInit], True; { Is XMS initialized }
- JZ @@XMSInitialized; { Jump if initialized }
- CALL InitializeXMS; { Initialize XMS }
- @@XMSInitialized:
- CMP XMSPresent, True; { Check XMS present }
- JNZ @@XMSError; { Jump if no XMS }
- MOV AH, 0AH; { Deallocate blocks id }
- MOV DX, [Handle]; { Handle for blocks }
- CALL [XMSEntryAddr]; { Call XMS handler }
- CMP AX, 1; { Check for AX=1 }
- JNZ @@XMSError; { Jump on error }
- MOV AX, True; { Function success }
- JMP @@Exit; { Now exit }
- @@XMSError:
- MOV AX, False; { Function failed }
- @@Exit:
- END;
- {---------------------------------------------------------------------------}
- { XMS_ResizeMem -> Platforms DOS - Checked 28Feb97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION XMS_ResizeMem (OldSize, NewSize: Word; Var Handle: Word): Byte;
- ASSEMBLER;
- ASM
- CMP BYTE PTR [XMSInit], True; { Is XMS initialized }
- JZ @@XMSInitialized; { Jump if initialized }
- CALL InitializeXMS; { Initialize XMS }
- @@XMSInitialized:
- MOV AX, XMSNotPresent; { Preset error state }
- CMP XMSPresent, True; { Check XMS present }
- JNZ @@Exit; { Jump if no XMS }
- CMP BYTE PTR [XMSReAlloc], True; { Check Realloc flag }
- JZ @@DirectResize; { Jump if flag is set }
- { * REMARK * - This is a bug fix for early versions of XMS drivers }
- { in which the reallocate only worked for the last block }
- MOV AH, 09H; { Allocate new handle }
- MOV DX, [NewSize]; { New XMS size }
- CALL [XMSEntryAddr]; { Call XMS handler }
- CMP AX, 1; { Check for fail }
- JNZ @@ErrorExit; { Failed so exit }
- PUSH DX; { Save new handle }
- XOR AX, AX; { Clear register }
- PUSH AX;
- PUSH AX; { To address is nil }
- PUSH DX; { To handle }
- PUSH AX;
- PUSH AX; { From address is nil }
- LES SI, [Handle]; { Load handle address }
- MOV DX, ES:[SI]; { Load handle }
- PUSH DX; { From handle }
- MOV AX, [OldSize]; { Start with oldsize }
- CMP AX, [NewSize]; { Compare to new size }
- JLE @@NewBigger;
- MOV AX, [NewSize]; { Take smaller size }
- @@NewBigger:
- XOR DX, DX; { Clear register }
- MOV CX, 000AH; { 1 SHL 10 = 1K }
- DB $0F; DB $A5; DB $C2; { SHL DX:AX, CL}
- SHL AX, CL; { Roll lower word }
- PUSH DX; { Push new size }
- PUSH AX;
- CALL FAR PTR XMS_MoveMem; { Move old to new }
- POP DX; { Reload old handle }
- MOV BL, AL; { Transfer result }
- CMP AX, 0; { Check for success }
- JNZ @@ErrorExit; { No error so exit }
- LES SI, [Handle];
- MOV BX, ES:[SI]; { Hold old handle }
- MOV ES:[SI], DX; { Set new handle }
- MOV DX, BX;
- MOV AH, 0AH; { Release old handle }
- CALL [XMSEntryAddr]; { Call XMS handler }
- CMP AX, 1; { Check for success }
- JNZ @@ErrorExit; { No error so exit }
- XOR AX, AX; { Clear the register }
- JMP @@Exit; { Now exit }
- { * REMARK END * - Leon de Boer }
- @@DirectResize:
- MOV AH, 0FH; { Load function id }
- MOV BX, [NewSize]; { Load up new size }
- LES SI, [Handle]; { Address of handle }
- MOV DX, ES:[SI]; { Load handle }
- CALL [XMSEntryAddr]; { Call XMS handler }
- CMP AX, 1; { Check for success }
- JNZ @@ErrorExit; { If error jump exit }
- MOV BL, 0; { Clear the register }
- @@ErrorExit:
- MOV AL, BL; { Create return value }
- @@Exit:
- END;
- {---------------------------------------------------------------------------}
- { XMS_MoveMem -> Platforms DOS - Checked 28Feb97 LdB }
- {---------------------------------------------------------------------------}
- FUNCTION XMS_MoveMem (ToAddress: LongInt; ToHandle: Word; FromAddress: LongInt;
- FromHandle: Word; Size: LongInt): Byte;
- VAR Success: Byte; Temp1, Temp2: Array [1..2] Of Byte;
- BEGIN
- If Odd(Size) Then Begin { Size is odd }
- Success := XMS_EvenMoveMem(LongInt(@Temp1), 0,
- ToAddress, ToHandle, 2); { Dest fetch word }
- If (Success = 0) Then Begin
- Success := XMS_EvenMoveMem(LongInt(@Temp2), 0,
- FromAddress, FromHandle, 2); { Source fetch word }
- If (Success = 0) Then Begin
- Temp1[1] := Temp2[1]; { Source to dest }
- Success := XMS_EvenMoveMem(ToAddress,
- ToHandle, LongInt(@Temp1), 0, 2); { Update dest word }
- Inc(ToAddress); { Inc to address }
- Inc(FromAddress); { Inc from address }
- Dec(Size); { One less byte }
- End;
- End;
- End Else Success := 0; { Even size to move }
- If (Success = 0) AND (Size > 0) Then { Okay to move data }
- Success := XMS_EvenMoveMem(ToAddress, ToHandle,
- FromAddress, FromHandle, Size); { Move even size }
- XMS_MoveMem := Success; { Return result }
- END;
- END.
- {
- $Log$
- Revision 1.2 2000-08-24 12:00:23 marco
- * CVS log and ID tags
- }
|