Hello,
Here you have a unit for calling XMS services in the same way as you
normally call interrupt services, using the REG register buffer.
I hope it will be useful, especially for programmers not accustomed to
assembly language and using pointers. You may save yourself from having
to buy a library to access XMS services. Of course you have to know wich
XMS services are available. You will find them in Ralph Brown's
interrupt list under interrupt 2Fh, function 4310h (get XMS driver
address).
'*****************************************************************************
*
' Unit CallXMS.bas
' Copyright (C) 1996 by Hans Lunsing. All Rights Reserved.
'*****************************************************************************
*
$COMPILE UNIT 'Destination of compilation
'Compiler directives for code generation
$CPU 80386 'Generate code for processor {8086 | 80286 | 80386}
$DIM ALL 'Declararations required for {ALL | ARRAY | NONE}
$EVENT OFF 'Generate event checking code
$FLOAT EMULATE 'FP math package '{EMULATE | NPX | PROCEDURE}
$OPTIMIZE SPEED 'Optimize code for {SPEED | SIZE}
$OPTION GOSUB OFF 'Preserve GOSUB stack if a runtime error occurs
$OPTION SIGNED OFF 'Return addresses by VARSEG etc. as signed integers
'Compiler directives for debugging and testing
$DEBUG UNIT OFF 'Attach debug information to unit file
$ERROR ALL OFF 'Generate test code for all types of errors
'*****************************************************************************
*
DEFINT A-Z
$INCLUDE "regnames.inc"
FUNCTION CallXMS () PUBLIC AS INTEGER
' ----------------------------------------------------------------------
' Function: to call XMS services in the same way as interrupt services:
' - fill REG register buffer
' - call service procedure
' - read REG register buffer
' XMS services are available only if an appropriate driver is loaded.
' If that is not the case, the function returns 1 instead of 0, and
' REG(%AX) = 0 and REG(%BX) = -1.
' ----------------------------------------------------------------------
DIM XMSEntry AS STATIC DWORD PTR 'Saved value of XMS entry point
DIM Entry AS DWORD PTR 'Local (stack) value of XMS entry
point
DIM rAX AS WORD 'All relevant registers on the stack
DIM rBX AS WORD
DIM rCX AS WORD
DIM rDX AS WORD
DIM rDS AS WORD
DIM rES AS WORD
DIM rSI AS WORD
DIM rDI AS WORD
DIM rFlags AS WORD 'Flags on the stack
FUNCTION = 0
IF XMSEntry = 0 THEN
' XMSEntry not yet known. We'll try to get it.
' First test if driver is available. If not, return
' FUNCTION = 1, REG(%AX) = 0, REG(%BX) = -1
ASM MOV AX, &h4300
ASM INT &h2F
ASM MOV rAX, AX
IF (rAX AND &hFF) &h80 THEN 'Driver not available
REG %AX, 0
REG %BX, -1
FUNCTION = 1
EXIT FUNCTION
ELSE 'Driver available. Get entry point.
ASM MOV AX, &h4310
ASM INT &h2F
ASM MOV XMSEntry, BX
ASM MOV AX, ES
ASM MOV XMSEntry[2], AX
END IF
END IF
' Place register buffer on the local stack
rAX = REG(%AX)
rBX = REG(%BX)
rCX = REG(%CX)
rDX = REG(%DX)
rDS = REG(%DS)
rES = REG(%ES)
rSI = REG(%SI)
rDI = REG(%DI)
' Place entry point vector on the local stack
Entry = XMSEntry
' Save adressing registers
ASM PUSH DS
ASM PUSH ES
ASM PUSH SI
ASM PUSH DI
' Fill registers from register buffer on stack
ASM MOV AX, rDS
ASM MOV DS, AX
ASM MOV AX, rES
ASM MOV ES, AX
ASM MOV SI, rSI
ASM MOV DI, rDI
ASM MOV AX, rAX
ASM MOV BX, rBX
ASM MOV CX, rCX
ASM MOV DX, rDX
' Call XMS service
ASM CALL DWORD PTR Entry
' Fill register buffer on stack from registers
ASM PUSHF
ASM POP rFlags
ASM MOV rAX, AX
ASM MOV rBX, BX
ASM MOV rCX, CX
ASM MOV rDX, DX
ASM MOV AX, DS
ASM MOV rDS, AX
ASM MOV AX, ES
ASM MOV rES, AX
ASM MOV rSI, SI
ASM MOV rDI, DI
>>> Continued to next message
Friendly greeting you,
Hans Lunsing, Fido : 2:281/607.214, 2:282/610.12
Internet : jlunsing@doge.nl
--- Terminate 4.00/Pro
# Origin: BBS De Lauwers For BASIC Programmers! ++31594688407 (2:282/610.12)
---------------
* Origin: United Bbs Systems Europe MailGate to -> Fido USA (2:2802/337.0)
|