Thank you very much,
Maybe this code to be useful for many PowerBasic programmers.
Jose Antonio Esteva Ramirez
MEXICO
------------------
* UNNECESSARY message quoting removed by ADMINISTRATOR!
Announcement
Collapse
No announcement yet.
XMS
Collapse
X
-
Guest replied
-
As I started posting to this thread, I had to finish fixing your code!
(I am thankful for the many people on this forum who helped me to learn
new things, so I am glad being able to help somebody else.)
Here follows the code which works (at least on my computer...):
Code:'================================================================== ' XMS handling code, original by Jose Antonio Esteva R. ' BUGS FIXED: ' 1) The following lines will fail because of an error I learnt about some ' weeks ago in this forum (see Topic "Inline Assembler Bug?", don't ' remember the exact date): ' ! mov DS, SegEstructura?? ' ! mov SI, DesEstructura?? ' ! call Dword Ptr Pointer ' --> "Pointer" is a PB variable, so DS must correspond to the PB Data ' Segment when you refer to it. But you are modifying DS two lines before. ' In this special case, where you NEED to pass a parameter in DS, ' you have to declare "Pointer" as a Code Segment variable. ' (See code below for the way to implement it.) ' 2) - very easy this one: ' If you set bufferXMS$ to "", you are implicitly allocating ZERO data ' bytes to bufferXMS$, so you cannot expect this string to return any ' data. You must define the length of the string before using it to ' receive data. (The allocated length of a string is not altered by just ' writing data to its address; more likely you will overwrite other data ' which is located past the end of the string.) ' 3) - a more subtle one: ' When passing a 32-bit pointer as you are doing it in "Estructura", ' the Offset value (Low-order word) comes FIRST, the Segment value ' (high-order word) comes SECOND. Therefore you must assign STRPTR(bufferXMS$) ' first, STRSEG(bufferXMS$) second. (You did this right when initializing ' the value of "Pointer", but not when filling in the EMM structure.) ' - You might probably want to rename the members of your type declaration ' in order to reflect this change. I preserved your original names in the ' following code. ' Hans Ruegg, March 2001 Cls '********************************************************* Variables: Shared BufferXMS$ Shared Identificador?? Type EstructuraParaMoverDatos NoBytes as DWORD IDFuente as WORD SegDirFuente as WORD DesDirFuente as WORD IDDestino as WORD SegDirDestino as WORD DesDirDestino as WORD end type DIM Estructura as shared EstructuraParaMoverDatos '********************************************************* Inicio: Print "CITLALLI 3.0" Print "Memoria extendida." Print ! mov ax,&H4300 ! int &H2F ! mov SiHay?,al If SiHay?=128 then Call VersionXMS Call TotalMemoriaExtendida Call ReservarBloqueDeMemoriaExtendida BufferXMS$="01234567890123456789012345678912" Call SubirInformacionXMS BufferXMS$ = STRING$(32,0) 'allocating space here for receiving data Call BajarInformacionXMS Print "-"; BufferXMS$; "-" Call LiberarBloqueDeMemoriaExtendida else Print "No se encontr¢ administrador de memoria extendida" end if End '********************************************************* 'Here are 4 bytes reserved for the Code Segment variable "Pointer". 'Make sure you put these lines in a place which is NEVER reached by 'the program execution flow, else your program will try to execute 'the contents of these 4 bytes as a machine instruction. 'Code Segment variables are always shared, but if you have a very long 'program with different segments, you must make sure that you are referring 'only to CS variables within the same segment. ' (If you put a $SEGMENT metastatement between these lines and any ' code which refers to CS:Pointer, your program would crash.) ' Note also that you can access Code Segment variables ONLY in Assembly ' Language statements, not in PB statements; so you will see that I ' translated all PB statements referring to "Pointer" into Assembler. Pointer: ! DW 0 ! DW 0 '********************************************************* SubProcedimientos: SUB VersionXMS() ! CMP WORD CS:Pointer, 0 ; These four lines replace the ! JNZ alreadyInitialized01 ; original IF pointer=0 THEN. ! CMP WORD CS:Pointer[2], 0 ! JNZ alreadyInitialized01 ! push DS ! mov AX, &h4310 ! int &h2f ! mov CS:Pointer[0], BX ! mov CS:Pointer[2], ES ! pop DS alreadyInitialized01: ! push DS ! mov AH, 0 ! mov BL, 0 ! call Dword Ptr Pointer ! pop DS ; Restore DS here to be able to access ! mov OK??, DX ; PB variables again. ! mov Version1?, AH ; In this place it does not matter because ! mov Version2?, AL ; DS is not modified, but in other places ' it DOES matter! If OK??=1 then Print "Version del controlador XMS: "; Print LTrim$(Str$(Version1?)); "." LTrim$(Str$(Version2?)) end if END SUB SUB TotalMemoriaExtendida() ! CMP WORD CS:Pointer, 0 ; These four lines replace the ! JNZ alreadyInitialized02 ; original IF pointer=0 THEN. ! CMP WORD CS:Pointer[2], 0 ! JNZ alreadyInitialized02 ! push DS ! mov AX, &h4310 ! int &h2f ! mov CS:Pointer[0], BX ! mov CS:Pointer[2], ES ! pop DS alreadyInitialized02: ! push DS ! mov AH, 8 ! mov BL, 0 ! call Dword Ptr CS:Pointer ! pop DS ! mov TMB??, AX ! mov Libre??, DX Print "Memoria extendida libre: "; Libre??; "KB" Print "Tama¤o del maximo bloque libre: "; TMB??; "KB" END SUB SUB ReservarBloqueDeMemoriaExtendida() Rem Por ahora siempre de 32K ! CMP WORD CS:Pointer, 0 ; These four lines replace the ! JNZ alreadyInitialized03 ; original IF pointer=0 THEN. ! CMP WORD CS:Pointer[2], 0 ! JNZ alreadyInitialized03 ! push DS ! mov AX, &h4310 ! int &h2f ! mov Word Ptr Pointer[0], BX ! mov Word Ptr Pointer[2], ES ! pop DS alreadyInitialized03: ! push DS ! mov AH, 9 ! mov BL, 0 ! mov DX, 100 ! call Dword Ptr CS:Pointer ! pop DS ! mov OK??, AX ! mov Identificador??, DX If OK??=1 then Print "Se reserv¢ bloque de memoria extendida ID: "; Hex$(Identificador??) end if END SUB SUB LiberarBloqueDeMemoriaExtendida() ! CMP WORD CS:Pointer, 0 ; These four lines replace the ! JNZ alreadyInitialized04 ; original IF pointer=0 THEN. ! CMP WORD CS:Pointer[2], 0 ! JNZ alreadyInitialized04 ! push DS ! mov AX, &h4310 ! int &h2f ! mov CS:Pointer[0], BX ! mov CS:Pointer[2], ES ! pop DS alreadyInitialized04: ! push DS ! mov AH, &H0A ! mov BL, 0 ! mov DX, Identificador?? ! call Dword Ptr CS:Pointer ! pop DS ! mov OK??, AX If OK??=1 then Print "Se liber¢ bloque de memoria extendida ID: "; Hex$(Identificador??) end if END SUB SUB SubirInformacionXMS() Estructura.NoBytes = 32 Estructura.IDFuente = 0 Estructura.SegDirFuente = STRPTR(BufferXMS$) Estructura.DesDirFuente = STRSEG(BufferXMS$) Estructura.IDDestino = Identificador?? Estructura.SegDirDestino = 0 Estructura.DesDirDestino = 0 SegEstructura?? = VARSEG(Estructura) DesEstructura?? = VARPTR(Estructura) ! CMP WORD CS:Pointer, 0 ; These four lines replace the ! JNZ alreadyInitialized05 ; original IF pointer=0 THEN. ! CMP WORD CS:Pointer[2], 0 ! JNZ alreadyInitialized05 ! push DS ! mov AX, &h4310 ! int &h2f ! mov CS:Pointer[0], BX ! mov CS:Pointer[2], ES ! pop DS alreadyInitialized05: ! push DS ! mov AH, &H0B ! mov SI, DesEstructura?? ! mov DS, SegEstructura?? ; from here on you cannot use PB variables any longer ! call Dword Ptr CS:Pointer ; because DS is modified!! ! pop DS ; Restore DS HERE to be able to access PB variables again ! mov OK??, AX ! mov ER?, BL Print "Subir datos a la memoria extendida: "; Print " OK="; Hex$(OK??) If OK??<>1 then print " Error "; Hex$(ER?) END SUB SUB BajarInformacionXMS() Estructura.NoBytes = 32 Estructura.IDFuente = Identificador?? Estructura.SegDirFuente = 0 Estructura.DesDirFuente = 0 Estructura.IDDestino =0 Estructura.SegDirDestino = STRPTR(BufferXMS$) Estructura.DesDirDestino = STRSEG(BufferXMS$) SegEstructura?? = VARSEG(Estructura) DesEstructura?? = VARPTR(Estructura) ! CMP WORD CS:Pointer, 0 ; These four lines replace the ! JNZ alreadyInitialized06 ; original IF pointer=0 THEN. ! CMP WORD CS:Pointer[2], 0 ! JNZ alreadyInitialized06 ! push DS ! mov AX, &h4310 ! int &h2f ! mov CS:Pointer[0], BX ! mov CS:Pointer[2], ES ! pop DS alreadyInitialized06: ! push DS ! mov AH, &H0B ! mov SI, DesEstructura?? ! mov DS, SegEstructura?? ! call Dword Ptr CS:Pointer ! pop DS ; Restore DS HERE to be able to access PB variables again ! mov OK??, AX ! mov ER?, BL Print "Bajar datos de la memoria extendida: "; Print " OK="; Hex$(OK??) If OK??<>1 then print " Error "; Hex$(ER?) END SUB
Leave a comment:
-
Guest repliedSorry,
I correct that problem but it not works jet, here is again my
code with all the corrections:
1.- I verify if there is an Extended Memory driver
2.- Get XMS version
3.- Query Free Extended Memory
4.- Allocate Extended Memory Block
5.- Upload BufferXMS$ to Extended Memory
6.- Erase BufferXMS$
7.- Download the data at Extended Memory to BufferXMS$
8.- Print BufferXMS$ (But there is not data)
9.- Free Extended Memory Block
Rem CITLALLI 3.0, memoria extendida.
Rem JAER Mex2001
Cls
'*********************************************************
Variables:
Shared BufferXMS$
Shared Identificador??
Type EstructuraParaMoverDatos
NoBytes as DWORD
IDFuente as WORD
SegDirFuente as WORD
DesDirFuente as WORD
IDDestino as WORD
SegDirDestino as WORD
DesDirDestino as WORD
end type
DIM Estructura as shared EstructuraParaMoverDatos
'*********************************************************
Inicio:
Print "CITLALLI 3.0"
Print "Memoria extendida."
Print
! mov ax,&H4300
! int &H2F
! mov SiHay?,al
If SiHay?=128 then
Call VersionXMS
Call TotalMemoriaExtendida
Call ReservarBloqueDeMemoriaExtendida
BufferXMS$="01234567890123456789012345678912"
Call SubirInformacionXMS
BufferXMS$=""
Call BajarInformacionXMS
Print "-"; BufferXMS$; "-"
Call LiberarBloqueDeMemoriaExtendida
else
Print "No se encontr¢ administrador de memoria extendida"
end if
End
'*********************************************************
SubProcedimientos:
SUB VersionXMS()
DIM Pointer AS SHARED DWORD
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, 0
! mov BL, 0
! call Dword Ptr Pointer
! mov OK??, DX
! mov Version1?, AH
! mov Version2?, AL
! pop DS
If OK??=1 then
Print "Version del controlador XMS: ";
Print LTrim$(Str$(Version1?)); "." LTrim$(Str$(Version2?))
end if
END SUB
SUB TotalMemoriaExtendida()
DIM Pointer AS SHARED DWORD
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, 8
! mov BL, 0
! call Dword Ptr Pointer
! mov TMB??, AX
! mov Libre??, DX
! pop DS
Print "Memoria extendida libre: "; Libre??; "KB"
Print "Tama¤o del maximo bloque libre: "; TMB??; "KB"
END SUB
SUB ReservarBloqueDeMemoriaExtendida()
DIM Pointer AS SHARED DWORD
Rem Por ahora siempre de 32K
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, 9
! mov BL, 0
! mov DX, 100
! call Dword Ptr Pointer
! mov OK??, AX
! mov Identificador??, DX
! pop DS
If OK??=1 then
Print "Se reserv¢ bloque de memoria extendida ID: "; Hex$(Identificador??)
end if
END SUB
SUB LiberarBloqueDeMemoriaExtendida()
DIM Pointer AS SHARED DWORD
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, &H0A
! mov BL, 0
! mov DX, Identificador??
! call Dword Ptr Pointer
! mov OK??, AX
! pop DS
If OK??=1 then
Print "Se liber¢ bloque de memoria extendida ID: "; Hex$(Identificador??)
end if
END SUB
SUB SubirInformacionXMS()
DIM Pointer AS SHARED DWORD
Estructura.NoBytes = 32
Estructura.IDFuente = 0
Estructura.SegDirFuente = STRSEG(BufferXMS$)
Estructura.DesDirFuente = STRPTR(BufferXMS$)
Estructura.IDDestino = Identificador??
Estructura.SegDirDestino = 0
Estructura.DesDirDestino = 0
SegEstructura?? = VARSEG(Estructura)
DesEstructura?? = VARPTR(Estructura)
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, &H0B
! mov DS, SegEstructura??
! mov SI, DesEstructura??
! call Dword Ptr Pointer
! mov OK??, AX
! mov ER?, BL
! pop DS
Print "Subir datos a la memoria extendida: ";
Print " OK="; Hex$(OK??)
If OK??<>1 then print " Error "; Hex$(ER?)
END SUB
SUB BajarInformacionXMS()
DIM Pointer AS SHARED DWORD
Estructura.NoBytes = 32
Estructura.IDFuente = Identificador??
Estructura.SegDirFuente = 0
Estructura.DesDirFuente = 0
Estructura.IDDestino =0
Estructura.SegDirDestino = STRSEG(BufferXMS$)
Estructura.DesDirDestino = STRPTR(BufferXMS$)
SegEstructura?? = VARSEG(Estructura)
DesEstructura?? = VARPTR(Estructura)
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, &H0B
! mov DS, SegEstructura??
! mov SI, DesEstructura??
! call Dword Ptr Pointer
! mov OK??, AX
! mov ER?, BL
! pop DS
Print "Bajar datos de la memoria extendida: ";
Print " OK="; Hex$(OK??)
If OK??<>1 then print " Error "; Hex$(ER?)
END SUB
Originally posted by Gary Akins:
Jose -
Estructura may not be a string, but BufferXM$ is a string, as identified by the $ type declarator. From the PowerBASIC Reference Guide, p284:
So when you do this:
Code:Estructura.SegDirFuente = VARSEG(BufferXM$) Estructura.DesDirFuente = VARPTR(BufferXM$)
Code:Estructura.SegDirFuente = STRSEG(BufferXM$) Estructura.DesDirFuente = STRPTR(BufferXM$)
------------------
Leave a comment:
-
Guest repliedJose -
Estructura may not be a string, but BufferXM$ is a string, as identified by the $ type declarator. From the PowerBASIC Reference Guide, p284:
When you use VARSEG to get the segment of a string, keep in mind that the value being returned is the segment where the string handle is located, not the segment where the actual contents of the string are located; use STRPTR and STRSEG to fond this address.
When you use VARPTR to get the offset of a string, keep in mind that the value being returned is the offset of the string handle not the actual data in the string.
Code:Estructura.SegDirFuente = VARSEG(BufferXM$) Estructura.DesDirFuente = VARPTR(BufferXM$)
Code:Estructura.SegDirFuente = STRSEG(BufferXM$) Estructura.DesDirFuente = STRPTR(BufferXM$)
------------------
[This message has been edited by Gary Akins (edited March 09, 2001).]
Leave a comment:
-
Guest repliedBut Estructura is not a string!
Originally posted by Hans Ruegg:
Forgot to mention also: You must refer to the address of a string
with STRSEG and STRPTR, not VARSEG and VARPTR.
Greetings,
Hans Ruegg.
------------------
Leave a comment:
-
Guest repliedYes, I declare this variables:
Shared BufferXMS$
Shared Identificador??
Type EstructuraParaMoverDatos
NoBytes as DWORD
IDFuente as WORD
SegDirFuente as WORD
DesDirFuente as WORD
IDDestino as WORD
SegDirDestino as WORD
DesDirDestino as WORD
end type
DIM Estructura as shared EstructuraParaMoverDatos
Buffer$ is where I like download the information that is at the
extended memory.
And Estructura is the "Extended Memory Move Structure" defined at
the XMS 2.0.
Originally posted by Hans Ruegg:
Maybe you have to check some "obvious" error sources before doubting
about the XMS support code itself (which I did not check exactly).
But the following lines called my attention:
Estructura.SegDirFuente = VARSEG(BufferXM$)
Estructura.DesDirFuente = VARPTR(BufferXM$)
Estructura.IDDestino = Identificador??
These lines are inside a SUB. Did you declare BufferXM$ and
Identificador?? as SHARED ? If not, these variables are not
initialized when you enter the SUB, so you are passing invalid
values to the XMS manager.
Hans Ruegg
------------------
Leave a comment:
-
Well spotted Hans!
------------------
Lance
PowerBASIC Support
mailto:[email protected][email protected]</A>
Leave a comment:
-
Forgot to mention also: You must refer to the address of a string
with STRSEG and STRPTR, not VARSEG and VARPTR.
Greetings,
Hans Ruegg.
Leave a comment:
-
Maybe you have to check some "obvious" error sources before doubting
about the XMS support code itself (which I did not check exactly).
But the following lines called my attention:
Estructura.SegDirFuente = VARSEG(BufferXM$)
Estructura.DesDirFuente = VARPTR(BufferXM$)
Estructura.IDDestino = Identificador??
These lines are inside a SUB. Did you declare BufferXM$ and
Identificador?? as SHARED ? If not, these variables are not
initialized when you enter the SUB, so you are passing invalid
values to the XMS manager.
Hans Ruegg
Leave a comment:
-
That is an "unknown" error - it is not documented in the list I have.
BTW, you may want to note the O/S and XMS driver are you using...
Can anyone else help with this problem?
------------------
Lance
PowerBASIC Support
mailto:[email protected][email protected]</A>
Leave a comment:
-
Guest repliedBL return 32H.
------------------
Leave a comment:
-
I understood that support for MAXLIB was dropped a couple of years ago, any registering it was no longer possible... meaning that it can't be used in any commercial/shareware applications anymore.
Does anyone know differently?
------------------
Lance
PowerBASIC Support
mailto:[email protected][email protected]</A>
Leave a comment:
-
Download Brian McLaughlin's MAXLIB -- MAX12C.ZIP at http://www.powerbasic.com/files/pub/pbdos/library/
This will give PB support for XMS.
If you're using PB 3.5, you must first convert
the MAXLIB.PBL to the new format. Run the
release 3.2 (or whatever < 3.5) PBLIB program
and list and extract the object files, then
with the 3.5 PBLIB build them into a new
MAXLIB.PBL.
Brian gives out MAXLIB free for personal use.
------------------
Leave a comment:
-
What is the error code returned by the XMS driver?
The error code for that function is returned in the BL register... a table of the error values can be found at http://www.ctyme.com/intr/rb-4768.htm#Table2775
An overview of the XMS functions can be found at http://www.ctyme.com/intr/rb-4768.htm
------------------
Lance
PowerBASIC Support
mailto:[email protected][email protected]</A>
Leave a comment:
-
XMS
I am developing a XMS support to my programs based on a script
writing by Dave Navarro, Jr.
I can:
08h) Query Free Extended Memory
09h) Allocate Extended Memory Block
0Ah) Free Extended Memory Block
But not:
0Bh) Move Extended Memory Block
My code is it:
Sub VersionXMS()
DIM Pointer AS DWORD
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, 0
! mov BL, 0
! call Dword Ptr Pointer
! mov OK??, DX
! mov Version1?, AH
! mov Version2?, AL
! pop DS
If OK??=1 then
Print "Version del controlador XMS: ";
Print LTrim$(Str$(Version1?)); "." LTrim$(Str$(Version2?))
end if
END SUB
SUB TotalMemoriaExtendida()
DIM Pointer AS DWORD
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, 8
! mov BL, 0
! call Dword Ptr Pointer
! mov TMB??, AX
! mov Libre??, DX
! pop DS
Print "Memoria extendida libre: "; Libre??; "KB"
Print "Tama¤o del maximo bloque libre: "; TMB??; "KB"
END SUB
SUB ReservarBloqueDeMemoriaExtendida()
DIM Pointer AS DWORD
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, 9
! mov BL, 0
! mov DX, 40
! call Dword Ptr Pointer
! mov OK??, AX
! mov Identificador??, DX
! pop DS
If OK??=1 then
Print "Se reserv¢ bloque de memoria extendida ID: "; Hex$(Identificador??)
end if
END SUB
SUB LiberarBloqueDeMemoriaExtendida()
DIM Pointer AS DWORD
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, &H0A
! mov BL, 0
! mov DX, Identificador??
! call Dword Ptr Pointer
! mov OK??, AX
! pop DS
If OK??=1 then
Print "Se liber¢ bloque de memoria extendida ID: "; Hex$(Identificador??)
end if
END SUB
SUB SubirInformacionXMS()
DIM Pointer AS DWORD
DIM Estructura as EstructuraParaMoverDatos
Estructura.NoBytes = 10
Estructura.IDFuente = 0
Estructura.SegDirFuente = VARSEG(BufferXM$)
Estructura.DesDirFuente = VARPTR(BufferXM$)
Estructura.IDDestino = Identificador??
Estructura.DesDirDestino = 0
Estructura.SegDirDestino = 1
SegEstructura?? = VARSEG(Estructura)
DesEstructura?? = VARPTR(Estructura)
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, &H0B
! mov DI, SegEstructura??
! mov SI, DesEstructura??
! call Dword Ptr Pointer
! mov OK??, AX
! mov ER?, BL
! pop DS
If OK??=1 then
Print "Se subieron los datos a la memoria extendida."
else
Print "ERROR "; Hex$(ER?)
end if
END SUB
SUB BajarInformacionXMS()
DIM Pointer AS DWORD
DIM Estructura as EstructuraParaMoverDatos
Estructura.NoBytes = 10
Estructura.IDFuente = Identificador??
Estructura.SegDirFuente = 0
Estructura.DesDirFuente = 1
Estructura.IDDestino =0
Estructura.SegDirDestino = VARSEG(BufferXM$)
Estructura.DesDirDestino = VARPTR(BufferXM$)
SegEstructura?? = VARSEG(Estructura)
DesEstructura?? = VARPTR(Estructura)
IF Pointer = 0 THEN
! push DS
! mov AX, &h4310
! int &h2f
! mov Word Ptr Pointer[0], BX
! mov Word Ptr Pointer[2], ES
! pop DS
END IF
! push DS
! mov AH, &H0B
! mov DS, SegEstructura??
! mov SI, DesEstructura??
! call Dword Ptr Pointer
! mov OK??, AX
! mov ER?, BL
! pop DS
If OK??=1 then
Print "Se bajaron los datos de la memoria extendida."
else
Print "ERROR "; Hex$(ER?)
end if
END SUB
Someone can help me?
JAER Mex2001
------------------
Tags: None
Leave a comment: