home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / Basic / QLIB57.ZIP / EMSXMS.DOC < prev    next >
Encoding:
Text File  |  1993-02-10  |  21.1 KB  |  608 lines

  1. QLIB5 EMSXMS.DOC expanded and extended memory subroutines
  2. Copyright (C) 1991-1993 Douglas Herr ■ all rights reserved
  3.  
  4.  
  5. Expanded Memory subroutines take advantage of expanded memory conforming
  6. to the Lotus/Intel/Microsoft (LIM) Expanded Memory Specification (EMS).
  7. QLIB EMS subroutines allow your programs to store vast amounts of data in
  8. Expanded memory rather than creating temporary files on a disk.  A well-
  9. designed program using Expanded memory can be much faster than if Expanded
  10. memory isn't used.
  11.  
  12. Three primary versions of the EMS have been released: 3.0, 3.2 and 4.0.
  13. QLIB's EMS subroutines will work with all EMS versions.
  14.  
  15. EMS memory is allocated in "pages" of 16k bytes (actually 16,384 bytes)
  16. each.
  17.  
  18. Error codes returned by QLIB's EMS subroutines are:
  19.  
  20.      0 = no error
  21.      &H80 = memory manager software error - non-recoverable
  22.      &H81 = expanded memory hardware error - non-recoverable
  23.      &H83 = invalid EMS handle
  24.      &H85 = no available EMS handles
  25.      &H87 = not enough memory pages
  26.      &H88 = not enough memory pages available
  27.      &H89 = you tried to allocate zero pages
  28.  
  29.  
  30. XMS memory is available on many 286 or better computers with a suitable
  31. driver.  On 286 computers, XMS memory will be much slower than EMS memory.
  32. XMS memory is not available on XT (or compatible) computers.
  33.  
  34. XMS error codes include:
  35.      0 = no error
  36.      &HA0 = all extended memory is allocated
  37.      &HA1 = no handles available
  38.      &HA2, &HA3, &HA5 = handle is invalid
  39.      &HA4, &HA6 = offset is invalid
  40.      &HA7 = length is invalid
  41.  
  42.  
  43.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  44.  
  45.      Function: handle% = AllocEMS(bytes&)
  46.      object file: ems.obj
  47.  
  48.         Allocates a block of EMS memory, returning a handle for subsequent
  49.      access to the memory block.  Up to 2,097,120 bytes may be allocated
  50.      per handle if that much EMS memory is installed.  Any EMS memory
  51.      blocks must be released with FreeEMS(handle%) before your program ends,
  52.      or the memory allocated by AllocEMS will not be available to any other
  53.      programs.  AllocEMS updates the EMSError flag if something went wrong.
  54.      Note that EMS memory is available in "pages" of 16k bytes; AllocEMS
  55.      will allocate multiple "pages" if required, but any EMS memory
  56.      allocation will be in multiples of 16k bytes.
  57.  
  58.      Example:
  59.         REM $INCLUDE: 'qlib.bi'
  60.         .
  61.         .
  62.         .
  63.         bytes& = 32000
  64.         handle% = AllocEMS(bytes&)
  65.         IF EMSError THEN ...            ' check for errors
  66.  
  67.  
  68.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  69.  
  70.      Function: handle% = AllocXMS(bytes&)
  71.      object file: xms.obj
  72.  
  73.         Allocates a block of memory from extended memory, returning a
  74.      handle for subsequent access to the memory block.  AllocXMS updates
  75.      the XMSError flag if something went wrong.  Before exiting your program,
  76.      you must release any XMS handles with FreeXMS(handle%), or else
  77.      the memory allocated by AllocXMS will not be available to any other
  78.      programs.  XMS handles are in short supply, so you should plan your
  79.      program to use fewer large XMS blocks rather than many small XMS
  80.      blocks.  Note that bytes& is a LONG integer, and you may allocate as
  81.      much memory as your system has, up to 2,147,450,880 bytes.
  82.  
  83.      Example:
  84.         REM $INCLUDE: 'qlib.bi'
  85.         IF IsXMS THEN
  86.            bytes& = 100000
  87.            handle% = AllocXMS(bytes&)   ' allocate memory from XMS pool
  88.            IF XMSError GOTO oops
  89.         .
  90.         .
  91.         .
  92.  
  93.  
  94.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  95.  
  96.      Function: oops% = EMSError
  97.      object file: ems.obj
  98.  
  99.         EMSError is used after using a QLIB EMS function or subroutine to
  100.      determine if there was an EMS problem.  EMS error codes are listed on
  101.      the first page of this EMSXMS.DOC.
  102.  
  103.      Example:
  104.      REM $INCLUDE: 'qlib.bi'
  105.           .
  106.           .
  107.           .
  108.      handle% = AllocEMS(bytes&)
  109.      IF EMSError THEN  ...             ' test for errors
  110.                                        ' handle no good if errors
  111.  
  112.  
  113.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  114.  
  115.      Function: free& = EMSFree
  116.      object file: emsfree.obj
  117.  
  118.         EMSFree determines the total unallocated EMS memory available to
  119.      your program.  Note that free& is a LONG integer.
  120.  
  121.      Example:
  122.  
  123.      REM $INCLUDE: 'qlib.bi'
  124.      IF IsEMS THEN free& = EMSFree   ' get EMS memory available
  125.  
  126.  
  127.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  128.  
  129.      Function: total& = EMSTotal
  130.      object file: emsfree.obj
  131.  
  132.         EMSTotal determines the total EMS memory installed in the computer.
  133.      Note that total& is a LONG integer.
  134.  
  135.      Example:
  136.  
  137.      REM $INCLUDE: 'qlib.bi'
  138.      IF IsEMS THEN total& = EMSTotal   ' get EMS memory installed
  139.  
  140.  
  141.  
  142.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  143.  
  144.      Subroutine: EMSVersion(maj%, min%)
  145.      object file: ems30.obj
  146.  
  147.         Determines EMS version installed.  Use EMSReady to determine if
  148.      EMS memory is installed.
  149.  
  150.      Example:
  151.      CALL EMSVersion(maj%, min%)
  152.  
  153.  
  154.  
  155.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  156.  
  157.      Subroutine: EMGet(handle%, emsptr&, aseg%, aptr%, bytes&)
  158.      object file: emputget.obj (huge model: lowds2hi.obj)
  159.  
  160.         Copies data from EMS memory allocated by AllocEMS to an array.
  161.      aseg% and aptr% are segment and offset pointers to the array, bytes&
  162.      is the number of bytes to be copied, and handle% is the handle returned
  163.      by AllocEMS.  EMSptr& is the byte offset in the EMS memory block where
  164.      you want the read to start.  Note that EMSptr& = 0 at the start of the
  165.      block.  EMGet updates the EMSError flag.
  166.  
  167.      Example:
  168.      REM $INCLUDE: 'qlib.bi'
  169.      CALL EMGet(handle%, emsptr&, aseg%, aptr, bytes&)
  170.      IF EMSError THEN                                  ' check for errors
  171.  
  172.  
  173.  
  174.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  175.  
  176.      Subroutine: EMGet1(handle%, emsptr&, number%)
  177.      Subroutine: EMGet2(handle%, emsptr&, number%)
  178.      Subroutine: EMGet4(handle%, emsptr&, number[& or !])
  179.      Subroutine: EMGet8(handle%, emsptr&, number[# or @])
  180.      object file: emget.obj ($emspage.obj)
  181.  
  182.         Copies data from EMS memory to a single number.  EMGet1 gets a
  183.      single byte, EMGet2 gets an INTEGER, EMGet4 gets a LONG or SINGLE
  184.      number, and EMGet8 gets a DOUBLE, CURRENCY or COMPLEX number.
  185.      (COMPLEX number support may be found in COMPLEX.DOC.)  EMGet[n]
  186.      sets the EMSError flag if something went wrong.
  187.  
  188.      handle%                 = EMS handle
  189.      emsptr&                 = (LONG) offset of the number in the EMS block
  190.      number[%, &, !, # or @] = number returnd by EMGet[n]
  191.  
  192.      Example:
  193.         REM $INCLUDE: 'qlib.bi'
  194.         DIM a#(999)              ' DOUBLE array
  195.                                  ' program establishes values for array
  196.         .
  197.         .
  198.         .
  199.         REM  save a#() in EMS memory
  200.         IF IsEMS THEN
  201.              bytes& = CLNG(1000& * 8)            ' DOUBLE data is 8 bytes long
  202.              handle% = AllocEMS(bytes&)
  203.              IF EMSError THEN ...                ' check for errors
  204.  
  205.              aseg% = VARSEG(a#(0)): aptr% = VARPTR(a#(0))
  206.              emsptr& = 0
  207.              CALL EMPut(handle%, emsptr&, aseg%, aptr%, bytes&)
  208.              IF EMSError THEN ...                ' check for errors
  209.              .
  210.              .
  211.         ENDIF
  212.         .
  213.         .
  214.         REM I need to retrieve a#(12) from EMS
  215.         emsptr& = CLNG(12 * 8)                   ' calculate offset in EMS
  216.         CALL EMGet8(handle%, emsptr&, a#(12))
  217.  
  218.  
  219.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  220.  
  221.      Subroutine: EMPut(handle%, emoffset&, dataseg%, dataptr%, bytes&)
  222.      object file: emputget.obj ($emspage.obj)
  223.  
  224.          EMPut copies data to EMS memory from DOS or BASIC memory blocks.
  225.      EMPut safely handles even huge blocks of data > 64k in size.
  226.  
  227.      Example:
  228.          REM $INCLUDE: 'qlib.bi'
  229.          REM  I'll use expanded memory to store several 25-row text screens
  230.          REM  while I use graphics mode
  231.  
  232.          IF NOT IsEMS THEN
  233.               PRINT "This example uses EXPANDED memory"
  234.               PRINT "You cannot run this demo": END
  235.          ENDIF
  236.  
  237.          bytes& = 16000                    ' EMS drivers allocate
  238.                                            ' a minimum of 16k per block
  239.          handle% = AllocEMS(bytes&)
  240.          IF EMSError THEN
  241.               PRINT "There's a problem with EMS memory"
  242.               PRINT "You cannot run this demo": END
  243.          ENDIF
  244.  
  245.          bytes& = 4000                     ' 4,000 bytes for 80x25 screen
  246.          screenseg = &HB800                ' color monitor
  247.          emoffset& = 0
  248.  
  249.          FOR i = 0 to 3
  250.          CALL EMPut(handle%, emoffset&, screenseg, 0, bytes&)
  251.          emoffset& = emoffset& + bytes&
  252.          screenseg = screenseg + &H100
  253.          NEXT i
  254.          .
  255.          .
  256.          .
  257.  
  258.          REM  sometime later ...
  259.  
  260.          bytes& = 4000                     ' 4,000 bytes for 80x25 screen
  261.          screenseg = &HB800                ' color monitor
  262.          emoffset& = 0
  263.  
  264.          FOR i = 0 to 3
  265.          CALL EMGet(handle%, emoffset&, screenseg, 0, bytes&)
  266.          emoffset& = emoffset& + bytes&
  267.          screenseg = screenseg + &H0100
  268.          NEXT i
  269.  
  270.  
  271.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  272.  
  273.      Subroutine: EMPut1(handle%, emsptr&, number%)
  274.      Subroutine: EMPut2(handle%, emsptr&, number%)
  275.      Subroutine: EMPut4(handle%, emsptr&, number[& or !])
  276.      Subroutine: EMPut8(handle%, emsptr&, number[# or @])
  277.      object file: emget.obj ($emspage.obj)
  278.  
  279.         Copies data to EMS memory from a single number.  EMPut1 copies a
  280.      single byte, EMPut2 copies an INTEGER, EMPut4 copies a LONG or SINGLE
  281.      number, and EMPut8 copies a DOUBLE, CURRENCY or COMPLEX number.
  282.      (COMPLEX number support may be found in COMPLEX.DOC.)  EMPut[n]
  283.      sets the EMSError flag if something wnet wrong.
  284.  
  285.      handle%                 = EMS handle
  286.      emsptr&                 = (LONG) offset of the number in the EMS block
  287.      number[%, &, !, # or @] = number to be copied to EMS memory
  288.  
  289.      Example:
  290.         REM $INCLUDE: 'qlib.bi'
  291.         DIM a#(999)              ' DOUBLE array
  292.                                  ' program establishes values for array
  293.         .
  294.         .
  295.         .
  296.         REM  save a#() in EMS memory
  297.         IF IsEMS THEN
  298.              bytes& = CLNG(1000& * 8)            ' DOUBLE data is 8 bytes long
  299.              handle% = AllocEMS(bytes&)
  300.              IF EMSError THEN ...                ' check for errors
  301.  
  302.              aseg% = VARSEG(a#(0)): aptr% = VARPTR(a#(0))
  303.              emsptr& = 0
  304.              CALL EMPut(handle%, emsptr&, aseg%, aptr%, bytes&)
  305.              IF EMSError THEN ...                ' check for errors
  306.              .
  307.              .
  308.         ENDIF
  309.         .
  310.         .
  311.         REM a#(12) has changed and I need to update the the copy in EMS
  312.         emsptr& = CLNG(12 * 8)                   ' calculate offset in EMS
  313.         CALL EMPut8(handle%, emsptr&, a#(12))
  314.         IF EMSError THEN ...                     ' check for errors
  315.         
  316.  
  317.  
  318.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  319.  
  320.      Function: handle% = FLoadEMS(filename$)
  321.      object file: floadems.obj (ems.obj, q$alloc.obj, $asciiz.obj, fsize.obj)
  322.  
  323.         FLoadEMS reads a file from a disk and copies it into EMS memory.
  324.      FLoadEMS assumes that EMS is installed.  Use IsEMS to determine if
  325.      the computer has EMS memory.  FLoadEMS temporarily uses 16k of DOS
  326.      memory to read the file, but the file may be any size, up to
  327.      2,147,450,880 bytes if that much EMS is available.  This shouldn't be
  328.      a problem.  Several files may be loaded in EMS memory if memory is
  329.      available.  Use FreeEMS to release the EMS memory when you're done
  330.      using it.  If you don't release the EMS memory before the program
  331.      ends, that memory will not be available to other programs.
  332.  
  333.      Handle% returnd by FLoadEMS is a valid EMS handle, unless either
  334.      DOSError or EMSError <> 0.
  335.  
  336.      FLoadEMS fails if insufficient EMS memory is available, if 16k DOS
  337.      memory is not available, or if the specified file cannot be opened or
  338.      read.  See EMSError in this EMSXMS.DOC and DOSError in SYSTEM.DOC.
  339.  
  340.      Example:
  341.      REM $INCLUDE: 'qlib.bi'
  342.      SCREEN 12                          ' VGA graphics mode
  343.  
  344.      ' progam draws something on screen
  345.      ' I want to save the screen for later
  346.  
  347.      filename$ = "screen.12"            ' clever (?) file name
  348.      CALL GSave(filename$, oops)        ' see GRAPHICS.DOC
  349.      IF oops THEN                       ' check for errors
  350.          .
  351.          .
  352.          .
  353.      ENDIF
  354.          .
  355.          .
  356.          .
  357.      ' load "screen.12" into EMS memory
  358.      ' and copy to the screen
  359.      handle% = FLoadEMS(filename$)
  360.      IF DOSError OR EMSError THEN       ' check for errors
  361.          .                              ' handle% not valid if error
  362.          .
  363.          .
  364.      ENDIF
  365.      CALL GLoadEMS(handle%)             ' see GRAPHICS.DOC
  366.      IF EMSError THEN ...               ' more error control
  367.  
  368.      ' all done: release EMS memory
  369.      CALL FreeEMS(handle%)
  370.  
  371.  
  372.  
  373.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  374.  
  375.      Function: handle% = FLoadXMS(filename$)
  376.      object file: floadxms.obj (xms.obj, q$alloc.obj, $asciiz.obj, fsize.obj)
  377.  
  378.      Similar to FLoadEMS on previous page, but uses XMS memory instead of
  379.      EMS memory.
  380.  
  381.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  382.  
  383.      Subroutine: FreeEMS(handle%)
  384.      object file: ems.obj
  385.  
  386.      Releases a block of EMS memory allocated by AllocEMS.  Your program
  387.      should release any EMS blocks before the program terminates, or that
  388.      memory will not be available to other programs.  Do not confuse this
  389.      subroutine with the EMSFree function, which determines the total
  390.      expanded memory available.
  391.  
  392.      Example:
  393.          REM $INCLUDE: 'qlib.bi'
  394.          REM  this example allocates an EMS memory block and later
  395.          REM  releases it
  396.  
  397.          REM  see if extended memory is available
  398.          REM  and set a flag if so
  399.          EMSused = 0
  400.          IF IsEMS THEN
  401.               EMSused = 1
  402.               bytes& = 16384                  ' one EMS "page"
  403.               handle% = AllocEMS(bytes&)
  404.               IF EMSError THEM EMSused = 0
  405.          ENDIF
  406.          .                                   ' more program here
  407.          .
  408.          .
  409.          REM  release the EMS memory
  410.          CALL FreeEMS(handle%)
  411.  
  412.  
  413.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  414.  
  415.      Subroutine: FreeXMS(handle%)
  416.      object file: xms.obj
  417.  
  418.      De-allocates (releases) extended memory allocated by AllocXMS.  Your
  419.      program should release all XMS memory block before exiting, or those
  420.      blocks will not be available to other programs.  Do not confuse this
  421.      subroutine with the XMSFree function, which determines the total
  422.      extended memory available.
  423.  
  424.      Example:
  425.          REM $INCLUDE: 'qlib.bi'
  426.          REM  this example allocates an XMS memory block and later
  427.          REM  releases it
  428.  
  429.          REM  see if extended memory is available
  430.          REM  and set a flag if so
  431.          XMSused = 0
  432.          IF IsXMS THEN
  433.               XMSused = 1
  434.               kbytes = 16                    ' 16,384 bytes
  435.               handle% = AllocXMS(kbytes)
  436.               IF XMSError THEM XMSused = 0
  437.          ENDIF
  438.          .                                   ' more program here
  439.          .
  440.          .
  441.          REM  release the XMS memory
  442.          CALL FreeXMS(handle%)
  443.  
  444.  
  445.  
  446.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  447.  
  448.      Function: r% = IsEMS
  449.      object file: isems.obj
  450.  
  451.         Determines if EMS memory is installed in the computer.  Returns
  452.      r% = -1 if EMS is installed, r% = 0 if not.
  453.  
  454.      Example:
  455.      REM $INCLUDE: 'qlib.bi'
  456.  
  457.      IF IsEMS THEN
  458.           PRINT "EMS is installed"
  459.           ELSE
  460.           PRINT "no EMS memory or driver not installed"
  461.      END IF
  462.  
  463.  
  464.  
  465.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  466.  
  467.      Function: r% = IsXMS
  468.      object file: xms.obj
  469.  
  470.         Determines if XMS memory is installed in the computer.  Returns
  471.      r% = -1 if XMS is installed, r% = 0 if not.
  472.  
  473.      Example:
  474.      REM $INCLUDE: 'qlib.bi'
  475.  
  476.      IF IsXMS THEN
  477.           PRINT "XMS is installed"
  478.           ELSE
  479.           PRINT "no XMS memory or driver not installed"
  480.      END IF
  481.  
  482.  
  483.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  484.  
  485.      Function: kbytes% = XMSContig
  486.      object file: xmscont.obj (xms.obj)
  487.  
  488.      XMSContig determines the largest contiguous XMS memory block available
  489.      to your program.  The total available extended memory may more than
  490.      the value returned by XMSContig; see XMSFree.
  491.      Note that the number returned by XMSContig is kbytes, not bytes.
  492.  
  493.      Example:
  494.          REM $INCLUDE: 'qlib.bi'
  495.          IF IsXMS THEN
  496.              PRINT "Total XMS memory available is ";
  497.              PRINT XMSFree
  498.              PRINT "The largest contiguous XMS block is ";
  499.              PRINT XMSContig
  500.          ENDIF
  501.  
  502.  
  503.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  504.  
  505.      Function: errorcode% = XMSError
  506.      object file: xms.obj
  507.  
  508.      XMSError is used after a call to a QLIB XMS subroutine to determine if
  509.      an error was encountered by the XMS driver.
  510.  
  511.      Example:
  512.          REM $INCLUDE: 'qlib.bi'
  513.          IF IsXMS THEN
  514.              maxXMS = XMSFree              ' get total XMS memory available
  515.              IF XMSError THEN ...          ' check for errors after XMSFree
  516.          .
  517.          .
  518.          .
  519.  
  520.  
  521.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  522.  
  523.      Function: kbytes% = XMSFree
  524.      object file: xmsfree.obj (xms.obj)
  525.  
  526.      XMSFree determines the total XMS memory available to your program.
  527.      The available extended memory may not be contiguous; see XMSContig
  528.      to determine the largest contiguous block of XMS memory available.
  529.      Note that the number returned by XMSFree is kbytes, not bytes.
  530.      Do not confuse this function with the FreeXMS subroutine, which
  531.      releases a previously allocated XMS memory block.
  532.  
  533.      Example:
  534.          REM $INCLUDE: 'qlib.bi'
  535.          IF IsXMS THEN
  536.              PRINT "Total XMS memory available is ";
  537.              PRINT XMSFree
  538.          ENDIF
  539.  
  540.  
  541.  
  542.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  543.  
  544.      Subroutine: XMGet(handle%, xmoffset&, dataseg%, dataoffset%, bytes&)
  545.      object files: xmputget.obj (xms.obj)
  546.  
  547.      XMGet copies data from an extended memory block to DOS memory.
  548.      handle% is the XMS handle returned by AllocXMS, xmoffset is the
  549.      location in the extended memory block where the data is stored (the
  550.      start of the block is at xmoffset& = 0), dataseg% and dataoffset%
  551.      define the location of the DOS memory area and bytes& is the number of
  552.      bytes to copy from extended memory to DOS memory.
  553.      Note that xmoffset& and bytes& are both LONG integers.
  554.  
  555.      Example:
  556.          REM $INCLUDE 'qlib.bi'
  557.          REM  I'll use extended memory to store several 25-row text screens
  558.          REM  while I use graphics mode
  559.  
  560.          IF NOT IsXMS THEN
  561.               PRINT "This example uses EXTENDED memory"
  562.               PRINT "You cannot run this demo": END
  563.          ENDIF
  564.  
  565.          kbytes% = 16                      ' my XMS driver allocates
  566.                                            ' a minimum of 16k per block
  567.          handle% = AllocXMS(kbytes)
  568.          IF XMSError THEN
  569.               PRINT "There's a problem with XMS memory"
  570.               PRINT "You cannot run this demo": END
  571.          ENDIF
  572.  
  573.          bytes& = 4000                     ' 4,000 bytes for 80x25 screen
  574.          screenseg = &HB800                ' color monitor
  575.          xmoffset& = 0
  576.  
  577.          FOR i = 0 to 3
  578.          CALL XMPut(handle%, xmoffset&, screenseg, 0, bytes&)
  579.          xmoffset& = xmoffset& + bytes&
  580.          screenseg = screenseg + &H100
  581.          NEXT i
  582.          .
  583.          .
  584.          .
  585.  
  586.          REM  sometime later ...
  587.  
  588.          bytes& = 4000                     ' 4,000 bytes for 80x25 screen
  589.          screenseg = &HB800                ' color monitor
  590.          xmoffset& = 0
  591.  
  592.          FOR i = 0 to 3
  593.          CALL XMGet(handle%, xmoffset&, screenseg, 0, bytes&)
  594.          xmoffset& = xmoffset& + bytes&
  595.          screenseg = screenseg + &H0100
  596.          NEXT i
  597.  
  598.  
  599.  
  600.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  601.  
  602.      Subroutine: XMPut(handle%, xmoffset&, dataseg%, dataoffset%, bytes&)
  603.      object files: xmputget.obj (xms.obj)
  604.  
  605.      XMPut copies data from DOS memory to an extended memory block.
  606.      See XMGet for example.
  607.  
  608.