Announcement

Collapse
No announcement yet.

XMS

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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

    ------------------

  • #2
    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>
    Lance
    mailto:[email protected]

    Comment


    • #3
      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.


      ------------------
      Algorithms - interesting mathematical techniques with program code included.

      Comment


      • #4
        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>
        Lance
        mailto:[email protected]

        Comment


        • #5
          BL return 32H.



          ------------------

          Comment


          • #6
            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]support[email protected]</A>
            Lance
            mailto:[email protected]

            Comment


            • #7
              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

              Comment


              • #8
                Forgot to mention also: You must refer to the address of a string
                with STRSEG and STRPTR, not VARSEG and VARPTR.

                Greetings,

                Hans Ruegg.

                Comment


                • #9
                  Well spotted Hans!

                  ------------------
                  Lance
                  PowerBASIC Support
                  mailto:[email protected][email protected]</A>
                  Lance
                  mailto:[email protected]

                  Comment


                  • #10
                    Yes, 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


                    ------------------

                    Comment


                    • #11
                      But 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.


                      ------------------

                      Comment


                      • #12
                        Jose -

                        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.
                        and from p.282:

                        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.
                        So when you do this:
                        Code:
                        Estructura.SegDirFuente = VARSEG(BufferXM$)
                        Estructura.DesDirFuente = VARPTR(BufferXM$)
                        Estructura.SegDirFuente and Estructura.DesDirFuente contain the segment : offset address of BufferXM$'s handle, not the segment : offset address of BufferXM$'s data space. If you change it to:

                        Code:
                        Estructura.SegDirFuente = STRSEG(BufferXM$)
                        Estructura.DesDirFuente = STRPTR(BufferXM$)
                        then Estructura.SegDirFuente and Estructura.DesDirFuente will point to the segment : offset address of BufferXM$'s data space.

                        ------------------


                        [This message has been edited by Gary Akins (edited March 09, 2001).]

                        Comment


                        • #13
                          Sorry,

                          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$)
                          Estructura.SegDirFuente and Estructura.DesDirFuente contain the segment : offset address of BufferXM$'s handle, not the segment : offset address of BufferXM$'s data space. If you change it to:

                          Code:
                          Estructura.SegDirFuente = STRSEG(BufferXM$)
                          Estructura.DesDirFuente = STRPTR(BufferXM$)
                          then Estructura.SegDirFuente and Estructura.DesDirFuente will point to the segment : offset address of BufferXM$'s data space.



                          ------------------

                          Comment


                          • #14
                            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

                            Comment


                            • #15
                              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!

                              Comment

                              Working...
                              X