2000 %title "XMSLIB.ASM - Interface to the XMS driver for TurboC 2.0 and TC++ 1.0" %subttl "Copyright 1990, 1991 by Michael Graff" ; $Id: xmslib.asm 1.7 91/09/02 12:18:03 explorer Exp Locker: explorer $ ; This package allows TurboC programs to use a XMS driver to store data ; Version 1.2, 08-Mar-91 ; Version 1.3, 07-May-91 Thanks to DTF ; Version 1.4, 26-May-91 ; Version 1.5, 12-Jun-91 Fixed a few little errors ; Version 1.6, 02-Sep-91 Fixed a few documentation errors ; MODIFIED 17-Sep-95 by Mats Petersson, fixed pushing of registers ; that would otherwise become destroyed ideal model SMALL ; tested: large, small, tiny, huge ; Other TC models (other than possibly ; HUGE) should work as well. TRUE equ 1 FALSE equ 0 XGetVersion equ 00h ; commands to the XMS driver XRequestHMA equ 01h XReleaseHMA equ 02h XGlobalE20 equ 03h XGlobalD20 equ 04h XLocalE20 equ 05h XLocalD20 equ 06h XQuery20 equ 07h XGetMemSize equ 08h XAllocEMB equ 09h XFreeEMB equ 0ah XMoveEMB equ 0bh XLockEMB equ 0ch XUnlockEMB equ 0dh XGetHandleInfo equ 0eh XReallocEMB equ 0fh XRequestUMB equ 10h XReleaseUMB equ 11h ENone equ 00h ; "no error" error code ENotInitd equ 01h ; XMSSetup was never called before other XMS funcs struc ExtMemMoveStruct TransferLength dd ? ; 32-bit number of bytes to transfer SourceHandle dw ? ; Handle of source block SourceOffset dd ? ; 32-bit offset into source block DestHandle dw ? ; Handle of dest block DestOffset dd ? ; 32-bit offset into dest block ends ExtMemMoveStruct codeseg _XMSDriver dd ? _XMSInitd dw FALSE public _XMS_Setup,_XMS_Version,_XMS_RequestHMA,_XMS_ReleaseHMA,_XMS_FreeMem public _XMS_GlobalEnableA20,_XMS_GlobalDisableA20,_XMS_LocalEnableA20 public _XMS_LocalDisableA20,_XMS_QueryA20,_XMS_AllocEMB,_XMS_FreeEMB public _XMS_MoveEMB,_XMS_LockEMB,_XMS_UnlockEMB,_XMS_GetEMBHandleInfo public _XMS_ReallocEMB,_XMS_RequestUMB,_XMS_ReleaseUMB ;-------------------------------------------------------------------------- ; extern unsigned int far XMS_Setup(void); ;-------------------------------------------------------------------------- proc _XMS_Setup far push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters mov [_XMSInitd],0 ; Routine has not init'd yet mov ax,4300h ; XMS Driver installation check int 2fh cmp al,80h ; returns 80h if installed je short @@xmsfound mov ax,FALSE ; XMS Driver not present jmp @@exit @@xmsfound: mov ax,4310h ; get address of XMS driver int 2fh mov [word _XMSDriver],bx ; store offset mov [word _XMSDriver+2],es ; store segment inc [_XMSInitd] ; we have init'd our code mov ax,TRUE @@exit: pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_Setup ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_Version( ; unsigned int far *version, unsigned int far *internal, ; unsigned int far *HMA); ;------------------------------------------------------------------------------- proc _XMS_Version far arg version:dword,internal:dword,HMA:dword push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push di cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XGetVersion ; function to get version of HMA driver call [dword _XMSDriver] ; call the XMS driver les di,[version] ; point es:di to variable mov [word ptr es:di],ax les di,[internal] mov [word ptr es:di],bx les di,[HMA] mov [word ptr es:di],dx mov al,ENone ; no error can occur here (?) @@exit: pop di pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_Version ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_RequestHMA(unsigned int mysize); ;------------------------------------------------------------------------------- proc _XMS_RequestHMA far arg mysize:word push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov dx,[mysize] ; ammount of HMA wanted mov ah,XRequestHMA ; function to allocate HMA call [dword _XMSDriver] ; call the XMS driver mov al,bl ; return any error codes generated @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_RequestHMA ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_ReleaseHMA(void); ;------------------------------------------------------------------------------- proc _XMS_ReleaseHMA far push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XReleaseHMA ; function to release HMA call [dword _XMSDriver] ; call the XMS driver mov al,bl ; return any error codes generated @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_ReleaseHMA ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_GlobalEnableA20(void); ;------------------------------------------------------------------------------- proc _XMS_GlobalEnableA20 far push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XGlobalE20 ; function code call [dword _XMSDriver] ; call the XMS driver mov al,bl ; return any error codes generated @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_GlobalEnableA20 ;--------------------------------------------------------- 2000 ---------------------- ; extern unsigned char far XMS_GlobalDisableA20(void); ;------------------------------------------------------------------------------- proc _XMS_GlobalDisableA20 far push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XGlobalD20 ; function code call [dword _XMSDriver] ; call the XMS driver mov al,bl ; return any error codes generated @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_GlobalDisableA20 ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_LocalEnableA20(void); ;------------------------------------------------------------------------------- proc _XMS_LocalEnableA20 far push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XLocalE20 ; function code call [dword _XMSDriver] ; call the XMS driver mov al,bl ; return any error codes generated @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_LocalEnableA20 ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_LocalDisableA20(void); ;------------------------------------------------------------------------------- proc _XMS_LocalDisableA20 far push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XLocalD20 ; function code call [dword _XMSDriver] ; call the XMS driver mov al,bl ; return any error codes generated @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_LocalDisableA20 ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_QueryA20(unsigned int far *state); ;------------------------------------------------------------------------------- proc _XMS_QueryA20 far arg state:dword push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx push di cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XQuery20 ; function code call [dword _XMSDriver] ; call the XMS driver les di,[state] ; point to return value mov [word ptr es:di],ax ; return A20 state mov al,bl ; return any error codes generated @@exit: pop di pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_QueryA20 ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_FreeMem( ; unsigned int far *freemem, unsigned int far *totmem); ;------------------------------------------------------------------------------- proc _XMS_FreeMem far arg freemem:dword,totmem:dword push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx push di cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XGetMemSize ; function to get free/total memory call [dword _XMSDriver] ; call the XMS driver les di,[freemem] ; point es:di to freemem mov [word ptr es:di],ax les di,[totmem] mov [word ptr es:di],dx mov al,bl ; transfer XMS error code to al @@exit: pop di pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_FreeMem ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_AllocEMB( ; unsigned int mysize, unsigned int far *handle); ;------------------------------------------------------------------------------- proc _XMS_AllocEMB far arg mysize:word,handle:dword push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx push di cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XAllocEMB ; function code mov dx,[mysize] ; number of K to allocate call [dword _XMSDriver] ; call the XMS driver les di,[handle] mov [word ptr es:di],dx ; save handle number mov al,bl ; transfer XMS error code to al @@exit: pop di pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_AllocEMB ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_FreeEMB(unsigned int handle); ;------------------------------------------------------------------------------- proc _XMS_FreeEMB far arg handle:word push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XFreeEMB ; function code mov dx,[handle] ; handle number to free call [dword _XMSDriver] ; call the XMS driver mov al,bl ; transfer XMS error code to al @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_FreeEMB ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_MoveEMB(struct EMMMoveStruct far *MoveRec); ;------------------------------------------------------------------------------- proc _XMS_MoveEMB far arg MoveRec:dword push bp ; save TurboC's bp mov bp,sp ; use bp to address par 2000 ameters push bx push si xor bl,bl ; reset error code to 0 cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: push ds ; save Turbo's data segment mov ah,XMoveEMB ; function code lds si,[MoveRec] ; Point ds:si to MoveRec call [dword cs:_XMSDriver] ; call the XMS driver mov al,bl ; transfer XMS error code to al pop ds ; restore Turbo's data segment @@exit: pop si pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_MoveEMB ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_LockEMB(unsigned int handle, void far *address); ;------------------------------------------------------------------------------- proc _XMS_LockEMB far arg handle:word,address:dword push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx push di cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XLockEMB ; function code mov dx,[handle] ; handle number to Lock call [dword _XMSDriver] ; call the XMS driver cmp ax,1 ; was the call successful? je @@success ; yep, so jump! mov al,bl ; transfer XMS error code to al jmp short @@exit ; get out @@success: mov al,0 ; return no error code les di,[address] ; point to address mov [word ptr es:di],bx ; store the offset mov [word ptr es:di+2],dx ; store the segment @@exit: pop di pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_LockEMB ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_UnlockEMB(unsigned int handle); ;------------------------------------------------------------------------------- proc _XMS_UnlockEMB far arg handle:word push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XUnlockEMB ; function code mov dx,[handle] ; handle number to Unlock call [dword _XMSDriver] ; call the XMS driver mov al,bl ; transfer XMS error code to al @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_UnlockEMB ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_GetEMBHandleInfoEMB( ; unsigned int handle, unsigned char far *LockCount, ; unsigned char far *EMBHandlesFree, unsigned int far *EMBlength); ;------------------------------------------------------------------------------- proc _XMS_GetEMBHandleInfo far arg handle:word,LockCount:dword,EMBHandlesFree:dword,EMBlength:dword push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx push di cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XGetHandleInfo ; function code mov dx,[handle] ; handle number to GetEMBHandleInfo call [dword _XMSDriver] ; call the XMS driver cmp ax,1 ; was the call successful? je @@success ; yep, so jump! mov al,bl ; transfer XMS error code to al jmp short @@exit ; get out @@success: mov al,0 ; return no error code les di,[LockCount] ; set up es:di as a pointer mov [byte ptr es:di],bh ; save lock count les di,[EMBHandlesFree] mov [byte ptr es:di],bl ; save # of free handles in system les di,[EMBlength] mov [word ptr es:di],dx ; save block length @@exit: pop di pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_GetEMBHandleInfo ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_ReallocEMB( ; unsigned int handle, unsigned int newsize); ;------------------------------------------------------------------------------- proc _XMS_ReallocEMB far arg handle:word,newsize:word push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XReallocEMB ; function code mov dx,[handle] ; handle number to reallocate mov bx,[newsize] ; new size wanted call [dword _XMSDriver] ; call the XMS driver mov al,bl ; transfer XMS error code to al @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_ReallocEMB ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_RequestUMB( ; unsigned int SizeWanted, ; unsigned int far *segaddr, ; unsigned int far *SizeUgot); ;------------------------------------------------------------------------------- proc _XMS_RequestUMB far arg sizewanted:word,segaddr:dword,SizeUgot:dword push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx push di cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XRequestUMB ; function code mov dx,[sizewanted] ; nuumber of paragraphs we want call [dword _XMSDriver] ; call the XMS driver les di,[SizeUgot] ; we store a value here all the time mov [word ptr es:di],dx ; either size requested or max free cmp ax,1 ; was the call successful? je @@success ; yep, so jump! mov al,bl ; transfer XMS error code to al jmp short @@exit ; get out @@success: mov al,0 ; return no error code les 5cb di,[segaddr] ; point to address mov [word ptr es:di],bx ; store the segment @@exit: pop di pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_RequestUMB ;------------------------------------------------------------------------------- ; extern unsigned char far XMS_ReleaseUMB(unsigned int segaddr); ;------------------------------------------------------------------------------- proc _XMS_ReleaseUMB far arg segaddr:word push bp ; save TurboC's bp mov bp,sp ; use bp to address parameters push bx cmp [_XMSInitd],0 ; has XMSSetup been called? jne @@hasinitd ; yes, continue mov al,ENotInitd ; nope, return error code jmp short @@exit @@hasinitd: mov ah,XReleaseUMB ; function code mov dx,[segaddr] ; handle number to Release call [dword _XMSDriver] ; call the XMS driver mov al,bl ; transfer XMS error code to al @@exit: pop bx pop bp ; restore TurboC's bp ret ; we outa here endp _XMS_ReleaseUMB ;------------- End of file! --------------------------------------------------- end . 0