This is what I read:
http://www.petesqbsite.com/sections/tut ... 1-xms.html
So I then created assembly code and compiled it with NASM. This is my code:
Code: Select all
main:
;Save registers
PUSH BP
MOV BP, SP
PUSH ES
PUSH DI
PUSH DS
PUSH SI
;We pass in a structure as last 2 CALL ABSOLUTE parameters.
;ES:DI will have the pointer to that structure here.
MOV DI,[BP+08h]
mov ES,[DI]
MOV DI,[BP+06h]
mov DI,[DI]
;our Wanted Function is first integer in structure
mov AX,[ES:DI]
cmp AX,00h ;00h=XMS install check
jne ninit
mov AX,4300h ;Call XMS checking routine
int 2Fh
cmp AL,80h ;AL must return 80h or XMS is not installed
jne noxms
mov AX,1h
;XMS status is 2nd integer in structure.
;Here it is 1 to let QB know XMS is installed
mov [ES:DI+02h],AX
mov AX,4310h
;Save our structure address
;so next call wont wreck it
push ES
push DI
;Get the call address to most XMS functions
int 2Fh
;ES:BX has call address but we will make it AX:BX
mov AX,ES
;Restore our structure address
pop DI
pop ES
;Store memory address into a long integer in our struct
;Am I formatting the value wrong here?
mov [ES:DI+08h],AX
mov [ES:DI+06h],BX
jmp ending
ninit:
cmp AX,01h
jne nquery ;386 query (Haven't tried this yet)
mov AX,8800h
call dword[ES:DI+06h]
mov BH,0h
;mov [ES:DI+0Ch],BX ;stat
;mov [ES:DI+0Eh],EAX ;largest block
;mov [ES:DI+12h],EDX ;total kb
;mov [ES:DI+16h],ECX ;addr
jmp ending
nquery:
cmp AX,00FFh
jne nver ;FFh=XMS version
mov AX,0h
call dword[ES:DI+06h] ;Use our long integer as address
mov [ES:DI+04h],AX ;Store version into final integer in struct
jmp ending
nver:
ending:
;restore registers
POP SI
POP DS
POP DI
POP ES
POP BP
;exit to QB
RETF 4h
noxms:
;Set our installed status to 0
mov AX,0h
mov [ES:DI+02h],AX
jmp ending
Code: Select all
DECLARE FUNCTION acode$ ()
'This is the struct
TYPE xms
func AS INTEGER 'The function we want
inst AS INTEGER 'value determining if XMS is installed.
xver AS INTEGER 'version of XMS installed
addr AS LONG 'Address to use to call extended XMS routines
END TYPE
DIM x AS xms 'call this as x in here
x.func = 0 'Start with function 0: Check for XMS existance
x.inst = 0 'Assume nothing is installed
x.xver = 0 'Assume no version
DIM cd AS STRING * 500 'Reserve 500 bytes for binary code
cd = acode$ 'and fit the binary code in (code length is under 300 bytes)
CLS 'clean screen
DEF SEG = VARSEG(cd) 'use our code
'Here we inject our structure into call absolute
CALL absolute(VARSEG(x), VARPTR(x), VARPTR(cd))
PRINT x.inst, x.xver 'here x.inst returns 1 which is correct for just about every computer
x.func = &HFF& 'Check for memory version
'Program never goes past this point and DOSBOX locks up
CALL absolute(VARSEG(x), VARPTR(x), VARPTR(cd))
PRINT "results"
PRINT x.xver
END
FUNCTION acode$
'First value is hex values of the compiled code after running unix utilities nasm and xxd -p on it.
'I used ndisasm on the binary and the code returned fine.
w$ = "5589e506571e568b7e088e058b7e068b3d268b0583f8007525b80043cd2f3c807548b8010026894502b810430657cd2f8cc05f072689450826895d06eb2483f801750cb800882666ff5506b700eb133dff00750eb800002666ff550626894504eb005e1f5f075dca0400b8000026894502ebef"
'here we manually convert hex values to binary and store it in memory
cd$ = "": FOR n% = 1 TO LEN(w$) STEP 2: cd$ = cd$ + CHR$(VAL("&H" + MID$(w$, n%, 2))): NEXT
acode$ = cd$
END FUNCTION
Am I formatting my call address in assembly code correctly for NASM? because I think the problem comes down to that because everytime I execute the second call absolute to retrieve the XMS version it always locks up.