home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / Basic / QBXM10.ZIP / QBXM.DOC < prev    next >
Encoding:
Text File  |  1991-06-18  |  96.1 KB  |  2,929 lines

  1.  
  2.                                                              QBXM ver 1.0
  3.                                          Copyright 1991, Thomas J. Vought
  4.  
  5.  
  6.  
  7.                                     Overview
  8.  
  9.         QBXM  is  a library of routines that allow you  to  transparently
  10.         access either expanded (LIM 4.0 EMS) or extended memory (XMS 2.0)
  11.         directly from your BASIC program.
  12.  
  13.         The type of memory installed in the computer your application  is
  14.         running on makes no difference, the same calls are used to manip-
  15.         ulate  either expanded or extended memory.  QBXM adjusts for  the
  16.         type of memory installed.
  17.  
  18.         QBXM  will preserve the extra memory across programs so  you  can
  19.         load  frequently used data once and access it later through  QBXM
  20.         from other programs that you "RUN" or "CHAIN".  The only require-
  21.         ment  is that either a LIM 4.0 EMS expanded memory driver, or  an
  22.         XMS  2.0  extended  memory driver (ie:  HIMEM.SYS)  be  installed
  23.         before the QBXM routines are called.
  24.  
  25.         Throughout  this  manual,  I will try to avoid  using  the  terms
  26.         expanded and extended, since the type is unimportant, and  simply
  27.         refer  to  the EMS/XMS memory as eXtra Memory. (hence  the  name,
  28.         QBXM.)
  29.  
  30.  
  31.                                  Files Supplied:
  32.  
  33.         The QBXM10.ZIP file should contain:
  34.  
  35.              QBXM.LIB         The object file library.
  36.              QBXM.DOC         This file, the manual.
  37.              QBXMAPND.DOC     An appendix to the manual which highlights
  38.                                 some differences between LIM and XMS,
  39.                                 and how they're resolved with QBXM.
  40.              QBXM.BI          Basic include file with declare statements.
  41.              XMDEMO1.BAS      Demo programs showing most of the features
  42.              XMDEMO2.BAS        of QBXM with emphasis on preserving extra
  43.              XMDEMO3.BAS        memory across programs.
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.                                         1
  63.  
  64.  
  65.                                                              QBXM ver 1.0
  66.                                          Copyright 1991, Thomas J. Vought
  67.  
  68.                                 Getting Started:
  69.  
  70.         The QBXM routines are distributed with just the OBJ file library,
  71.         QBXM.   Due to the number of different QuickLibrary  support  li-
  72.         braries that are in circulation, it makes a smaller archive  file
  73.         to  leave  the QuickLibraries up to you to  build.   So  charging
  74.         right  ahead,  determine which QuickLib support  file  you  have.
  75.         Some examples are:
  76.  
  77.              BQLB40.LIB     for QuickBasic 4.0
  78.              BQLB41.LIB     for QuickBasic 4.0b / BASIC 6.0
  79.              BQLB45.LIB     for QuickBasic 4.5
  80.  
  81.         Note  that this shareware release of QBXM does not support  BASIC
  82.         PDS  7.0+'s  far  strings.  That precludes using them  in  a  QBX
  83.         QuickLib, though the .LIB file can be linked in with EXE's gener-
  84.         ated  with the default near strings of the BC  compiler.   Regis-
  85.         tered users will receive a 7.0 far string compatible library.
  86.  
  87.         From the command line, issue the following command,  substituting
  88.         the proper support library from above for "supportLIB":
  89.  
  90.  
  91.         >LINK /Q QBXM.LIB,QBXM.QLB,null,supportLIB;
  92.  
  93.  
  94.         To  add  the QBXM.LIB file to other LIB files you have,  use  the
  95.         LIB.EXE program:
  96.  
  97.  
  98.         >LIB yourLib.LIB +QBXM.LIB;
  99.  
  100.  
  101.         Which adds the QBXM routines to the LIB file named "yourLib.lib".
  102.         After which you can create a new QuickLibrary just like above:
  103.  
  104.  
  105.         >LINK /Q yourLib.LIB,yourLib.QLB,nul,supportLIB;
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.                                         2
  125.  
  126.  
  127.                                                              QBXM ver 1.0
  128.                                          Copyright 1991, Thomas J. Vought
  129.  
  130.                                   Design Logic
  131.  
  132.         Expanded memory accessed through an Expanded Memory Manager  (LIM
  133.         EMS 4.0) and extended memory accessed through an Extended  Memory
  134.         Manager  (XMS  spec 2.0) are obviously two  completely  different
  135.         animals.   What  I've tried to do with QBXM is to  tame  the  two
  136.         beasts and use features of each in a consistent way.  This causes
  137.         features  of  one  specification to be added to  the  other,  and
  138.         limits  of one to be imposed on the other.  If you  are  familiar
  139.         with  both  the expanded memory specification  and  the  extended
  140.         memory  specification, you may recognize where  adjustments  were
  141.         made  to each.  If you're interested, I've included  an  appendix
  142.         that  outlines  the differences in the specifications and  how  I
  143.         adjusted QBXM to end up with a unified interface.
  144.  
  145.         What was most important to me in writing these routines was to be
  146.         able  to  ignore the coding hassles of two  different  specifica-
  147.         tions.   All you should have to do is write one line of  code  to
  148.         access the extra memory, whether it is expanded or extended.  One
  149.         alternative is to write the program for one type of extra memory,
  150.         and  not allow your program to run on machines without that  spe-
  151.         cific  type  of  memory.
  152.  
  153.         Another  alternative is to write your program in such a way  that
  154.         decisions  are made in the code depending on what type of  memory
  155.         is installed at run time.  For example:
  156.  
  157.              IF ems THEN
  158.                   CALL allocateEMS...
  159.              ELSEIF xms THEN
  160.                   CALL allocateXMS...
  161.              ELSE
  162.                   ...whatever..
  163.              END IF
  164.  
  165.         This  would require using two separate sets of  library  routines
  166.         whose  code  would  be linked in to access both  types  of  extra
  167.         memory.  Only one set of routines would be called,  depending  on
  168.         the  run  time  conditions.  Why link in twice as  much  code  as
  169.         needed  with the resulting waste of space?  QBXM eliminates  this
  170.         overhead by having one set of routines for either type of memory.
  171.  
  172.         The  QBXM routines are written entirely in assembly  language  to
  173.         ensure  the highest possible execution speed.  In  addition,  the
  174.         library  consists of 12 separate object modules.  Each module  is
  175.         geared  toward  a different area of extra memory use.   Only  the
  176.         code actually needed will be linked into your program,  resulting
  177.         in the smallest possible .EXE file.
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.                                         3
  187.  
  188.  
  189.                                                              QBXM ver 1.0
  190.                                          Copyright 1991, Thomas J. Vought
  191.  
  192.                                 Terms & One Rule
  193.  
  194.         Some  terms  I use throughout this documentation  should  be  ex-
  195.         plained.   One I already mentioned is that I refer to either  EMS
  196.         or  XMS  memory as "Extra Memory."  Since the  routines  in  QBXM
  197.         handle  both  transparently, there is no  need  to  differentiate
  198.         between the two.  Another term is "Pages", borrowed from the  EMS
  199.         paged memory technique.  In QBXM, a page is 16,384 (16K) bytes of
  200.         memory,  and is the smallest amount that can be allocated by  the
  201.         routines.  Records are the same as you're used to in dealing with
  202.         random  access files or user defined TYPE'd structures, with  one
  203.         major difference:
  204.  
  205.                        All records must be an EVEN length.
  206.  
  207.         This is a limitation imposed by the XMS which does not allow byte
  208.         memory  moves, only word (2 byte) moves.  For more  on  accessing
  209.         odd length records, see the appendix file.
  210.  
  211.  
  212.                                 Calling Sequence
  213.  
  214.         The  GetXM routine must be called before any of the  other  extra
  215.         memory routines.  It checks for expanded memory first, and if not
  216.         found, checks for XMS.  Since EMS access is quicker in most cases
  217.         than  XMS, if both are installed, only EMS will be used. An   EMS
  218.         driver  or  an  XMS driver (such as HIMEM.SYS)  must  be  loaded.
  219.         There are other ways to access extended memory, but they are  not
  220.         standardized, thus I felt it was the better course not to use any
  221.         extended memory except through the XMS driver.
  222.  
  223.         GetXM  sets internal flags within the QBXM routines,  and  clears
  224.         other  QBXM  variables, so it should only be called  once  in  an
  225.         application.  If you are CHAIN'ing or RUN'ing to another  program
  226.         and you want to preserve the data that is in extra memory,  GetXM
  227.         should NOT be called by the CHAIN'd to program, just the  initial
  228.         program.  Most of the routines will fail with a -1 error code (No
  229.         extra memory) if GetXM wasn't called previously.
  230.  
  231.         The GetXM routine will return the type of extra memory installed,
  232.         and  the major and minor version of the driver in use.  One  trio
  233.         of  routines, PutNameXM, GetNameXM and ClearNamesXM require  ver-
  234.         sion  4.0 of the EMS driver, if EMS is in use.  If  your  program
  235.         will  use the PutNameXM, GetNameXM or ClearNamesXM routines,  and
  236.         EMS  is in use, then you have to check that the major version  of
  237.         the  EMS driver is 4 or greater.  If you use the  PutNameXM  rou-
  238.         tine, and do not use one of the 'automatic' extra memory clean up
  239.         routines,  then  ClearNamesXM must be called at the end  of  your
  240.         program.
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.                                         4
  249.  
  250.  
  251.                                                              QBXM ver 1.0
  252.                                          Copyright 1991, Thomas J. Vought
  253.  
  254.         After the extra memory routines are initialized by GetXM, any  of
  255.         the other routines can be called in any order.  Any extra  memory
  256.         that  your programs allocate, though, must be released when  your
  257.         program is finished running.  Both the EMS and XMS specifications
  258.         rely  on well behaved programs.  If you don't release  the  extra
  259.         memory you allocate, it will not be available for later  programs
  260.         to use, until the machine is rebooted.
  261.  
  262.         QBXM supplies three methods for making sure that memory allocated
  263.         by  your program(s) is released.  The first requires you to  take
  264.         on the burden, by closing each memory handle you open individual-
  265.         ly.  For each open/allocate call, there is a close/release call:
  266.  
  267.                   Open/Allocate:                Close/Release:
  268.                   --------------                --------------
  269.                   OpenXM                        CloseXM
  270.                   OpenScreenXM                  CloseScreenXM
  271.                   OpenRecXM                     CloseXM
  272.                   PutNameXM                     ClearNamesXM
  273.                   LoadFileXM                    CloseXM
  274.                   LoadScrFileXM                 CloseScreenXM
  275.  
  276.         A  second  method  is to make one call at the  point  where  your
  277.         program terminates, whether in an error routine or normally:
  278.  
  279.                   CloseAllXM
  280.  
  281.         Both  of  the previous methods allow you to select the  point  at
  282.         which  extra  memory is released.  Both will also  allow  you  to
  283.         CHAIN or RUN another program and leave the extra memory intact by
  284.         not releasing the extra memory.
  285.  
  286.         The last method is to call AutoCloseXM anywhere in your  program.
  287.         When  called,  AutoCloseXM forces BASIC and  QuickBASIC  to  call
  288.         CloseAllXM when your program ends, whether via an error or normal
  289.         termination.   This is the simplest method for programs  that  do
  290.         not RUN or CHAIN another program that will need the data in extra
  291.         memory.   When  BASIC encounters a CHAIN or  RUN  statement,  and
  292.         AutoCloseXM  has  been called, CloseAllXM will be  invoked.  This
  293.         means that  the extra memory data  that you may want to pass to a
  294.         subsequent program will be lost.
  295.  
  296.         When  you are working in the QuickBASIC environment,  AutoCloseXM
  297.         should  be used while you are debugging your program.  This  will
  298.         ensure that if you select "Continue" at a "You must restart  your
  299.         program after this change" prompt, extra memory will be released.
  300.         Same case if you restart your program from someplace after  extra
  301.         memory  has  been allocated, having invoked  AutoCloseXM  earlier
  302.         will make sure that the extra memory is released.
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.                                         5
  311.  
  312.  
  313.                                                              QBXM ver 1.0
  314.                                          Copyright 1991, Thomas J. Vought
  315.  
  316.                       Sharing Extra Memory Between Programs
  317.  
  318.         The key to sharing extra memory among a series of programs is  to
  319.         make  sure  that the current state of extra memory and  QBXM  are
  320.         passed to and from each program.  Remember that extra memory will
  321.         not change, but when a program starts up, there is no information
  322.         about  what  extra memory holds.  When QBXM is initialized  by  a
  323.         call to GetXM, flags and variables within QBXM are set to default
  324.         values.   Each time you manipulate extra memory, these  variables
  325.         are adjusted.
  326.  
  327.         The QBXM status variables require a total of 530 bytes.  They can
  328.         be  passed to your program via a call to SaveParamXM.   Once  you
  329.         have  these  parameters in a BASIC variable, you can pass  it  to
  330.         another  program that you CHAIN to.  The BASIC variable  must  be
  331.         declared  as  a  "COMMON  SHARED"  variable  in  both   programs.
  332.         XMDEMO1.BAS  and  XMDEMO2.BAS show how this is done.   CHAIN  re-
  333.         quires  the  BASIC  run time module to work  correctly.   If  you
  334.         prefer to "RUN" a second program, and compile with the /O switch,
  335.         then  pass  the status variable via a disk file.   The  receiving
  336.         program  must  call RestParamXM and pass the routine  the  status
  337.         variable.   Once  the internal QBXM variables are  restored,  the
  338.         extra  memory blocks and data are available as they were  in  the
  339.         previous program.
  340.  
  341.         An  example  of  how to share extra memory between  a  series  of
  342.         programs may be in order at this point.
  343.  
  344.         Assume  you have an order entry, inventory and invoicing  system,
  345.         and  that  each of the major areas are  processed  by  individual
  346.         programs invoked from MENU.BAS, the start-up program:
  347.  
  348.              MENU.BAS:
  349.                   Needs no data in particular, but does load a file of
  350.                   help screens for the system, if they haven't been
  351.                   loaded  already.  So print your sign on copyright
  352.                   message and a "just a moment" line.
  353.  
  354.                   Test the COMMON SHARED variable that holds the extra
  355.                   memory status.  If it is all zeros, then MENU.EXE is
  356.                   being run for the first time.  In that case call GetXM
  357.                   to initialize extra memory and load the help screens.
  358.                   If the variable is not all zeros, then MENU is being
  359.                   CHAINed  to by one of the other programs:
  360.  
  361.              DEFINT A-Z
  362.              COMMON SHARED xmBuf AS STRING * 530
  363.  
  364.              IF xmBuf = STRING$(530, 0) THEN
  365.                   CALL GetXM(major, minor, memType)
  366.                   CALL LoadScrFileXM("HELPSCRN.DAT", hScreens, errCode)
  367.              ELSE
  368.                   CALL RestParamXM(VARSEG(xmBuf), VARPTR(xmBuf), errCode)
  369.              END IF
  370.  
  371.  
  372.                                         6
  373.  
  374.  
  375.                                                              QBXM ver 1.0
  376.                                          Copyright 1991, Thomas J. Vought
  377.  
  378.                   After the menu program checks extra memory, loads help
  379.                   screens if needed etc. it then present a menu for the
  380.                   user to select an operation from:
  381.  
  382.         User selects order entry:
  383.  
  384.                   MENU.BAS calls SaveParamXM and passes the buffer to
  385.                   the order entry program via the COMMON SHARED variable
  386.                   and by CHAIN'ing to the order entry program:
  387.  
  388.              CALL SaveParamXM(VARSEG(xmBuf), VARPTR(xmBuf), errCode)
  389.              CHAIN "ORDERS"
  390.  
  391.                   Order entry needs to access both "customers" and
  392.                   "inventory" data.
  393.  
  394.                   Calls GetNameXM to see if "customers" is in memory.
  395.                        If not, checks available extra memory and loads
  396.                        the customer data base into extra memory and uses
  397.                        PutNameXM to name the memory handle "customers".
  398.  
  399.              DEFINT A-Z
  400.              COMMON SHARED xmBuf AS STRING * 530
  401.  
  402.              CALL GetNameXM ("CUSTOMERS", cMemHandle, errCode)
  403.  
  404.              IF cMemHandle = 0 THEN
  405.                   f$ = drive$ + ":\" + path$ + "CUSTOMER.DAT"
  406.                   cLen = LEN (customerRec)
  407.                   CALL LoadFileXM (f$, cLen, cMemHandle, cRecs&, errCode)
  408.                   IF errCode THEN GOSUB xmErrorTrap
  409.              END IF
  410.  
  411.                   Calls GetNameXM to see if "inventory" is in memory.
  412.                        If not, it calls LoadFileXM to load the data
  413.                        and uses PutNameXM to name the memory handle
  414.                        "inventory".
  415.  
  416.              CALL GetNameXM ("INVENTORY", iMemHandle, errCode)
  417.  
  418.              IF iMemHandle = 0 THEN
  419.                   f$ = drive$ + ":\" + path$ + "INVENTORY.DAT"
  420.                   iLen = LEN (inventoryRec)
  421.                   CALL LoadFileXM (f$, iLen, iMemHandle, iRecs&, errCode)
  422.                   IF errCode THEN GOSUB xmErrorTrap
  423.              END IF
  424.  
  425.              .... program does it's thing ....
  426.  
  427.              If an error, like not enough memory to load a file:
  428.                   Use GetNameXM to see if "invoices" is hogging memory.
  429.                   If it is, call CloseXM with the handle that GetNameXM
  430.                   returns to free some up.  Then load the file that order
  431.                   entry needs, either Customers or Inventory.
  432.  
  433.  
  434.                                         7
  435.  
  436.  
  437.                                                              QBXM ver 1.0
  438.                                          Copyright 1991, Thomas J. Vought
  439.  
  440.  
  441.                   When finished with order entry, before CHAIN'ing back
  442.                   to the main menu program, call SaveParamXM to pass the
  443.                   current extra memory status back to the main menu
  444.                   program.
  445.  
  446.              CALL SaveParamXM(VARSEG(xmBuf), VARPTR(xmBuf), errCode)
  447.              CHAIN "MENU"
  448.  
  449.              The MENU program will test xmBuf and find that it's not
  450.              a string of zeros, meaning there is extra memory in use.
  451.              This time, MENU will just restore the extra memory status:
  452.  
  453.  
  454.         User selects inventory:
  455.  
  456.                   MENU.BAS calls SaveParamXM and passes the buffer to
  457.                   the inventory program via a COMMON SHARED variable
  458.                   and by CHAIN'ing to the inventory program.
  459.  
  460.                   Inventory needs to access only "inventory" data.
  461.                   Calls GetNameXM to see if "inventory" is in memory.
  462.  
  463.                   If it's not, it calls LoadFileXM to load the data
  464.                        and uses PutNameXM to name the memory handle.
  465.  
  466.                   If an error, like not enough memory to load a file:
  467.                        Use GetNameXM to see if another program is using
  468.                        memory, and if it is, call CloseXM with the handle
  469.                        that GetNameXM returned to free some up.  Load the
  470.                        the data that the inventory program needs, and
  471.                        name it with PutNameXM as "inventory".
  472.  
  473.                   When the inventory program is finished, it calls
  474.                   SaveParamXM to save the current conditions of extra
  475.                   memory, and passes the buffer back to the Menu program
  476.                   with a common shared variable and a CHAIN.
  477.  
  478.         User selects invoices:
  479.  
  480.                   MENU.BAS calls SaveParamXM and passes the buffer to
  481.                   the invoicing program via a COMMON SHARED variable
  482.                   and by CHAIN'ing to the order entry program.
  483.  
  484.                   The invoice program needs to access both "customers"
  485.                   "inventory" and "invoice" data.
  486.  
  487.                   Calls GetNameXM to see if "customers" is in memory.
  488.                   Calls GetNameXM to see if "invoices" is in memory.
  489.                   Calls GetNameXM to see if "inventory" is in memory.
  490.  
  491.                   If one or more isn't in extra memory, it calls
  492.                   LoadFileXM to load the data it needs, and uses
  493.                   PutNameXM to name each memory handle.
  494.  
  495.  
  496.                                         8
  497.  
  498.  
  499.                                                              QBXM ver 1.0
  500.                                          Copyright 1991, Thomas J. Vought
  501.  
  502.                   If there's an error, like not enough memory to load a
  503.                   complete file:
  504.  
  505.                        Decide the best course of action....  In this
  506.                        situation, leaving the invoice file data on disk
  507.                        is probably best.  Customer data and inventory
  508.                        data needs to be accessed more often then the
  509.                        invoice file.
  510.  
  511.  
  512.                   Once the invoice program is done, it calls SaveParamXM
  513.                   to save the current state of extra memory to a common
  514.                   shared buffer variable and CHAIN's back to the main
  515.                   menu program.
  516.  
  517.         User selects EXIT from MENU.BAS:
  518.  
  519.                   Call CloseAllXm and exit MENU.BAS to system.
  520.  
  521.         Now the above is pretty simplistic, but nowhere in the system  is
  522.         there  a close/release call, except when the user exits from  the
  523.         main  menu.   This allows all the individual programs  to  access
  524.         data  loaded  by other programs, only loading what's  needed  one
  525.         time,  or  if  there's a memory squeeze, dumping  data  that  the
  526.         current  program doesn't need.  Of course each program  needs  an
  527.         error  trap. If an error is trapped, and it is  an  unrecoverable
  528.         error,  files should be written from extra memory and  CloseAllXM
  529.         invoked to clean up memory.
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.                                         9
  559.  
  560.  
  561.                                                              QBXM ver 1.0
  562.                                          Copyright 1991, Thomas J. Vought
  563.  
  564.         The  programs described previously all use the CHAIN  command  so
  565.         that  a  buffer with the extra memory information can  be  passed
  566.         from one application to the next.  CHAIN requires the use of  the
  567.         BASIC  run  time module.  If you prefer  to  compile  stand-alone
  568.         applications  (with the /O option), another means of passing  the
  569.         extra memory status information has to be used.  The only  method
  570.         I  can think of is to write a file to disk when exiting the  pro-
  571.         gram, and read it upon start up of the next program in  sequence.
  572.         For  example, PROG_A.BAS takes the following action upon  comple-
  573.         tion:
  574.  
  575.              CALL SaveParamXM (VARSEG(xmBuf), VARPTR(xmBuf), errCode)
  576.  
  577.              handle = FREEFILE
  578.              OPEN "XM_STATUS.DAT" FOR BINARY AS handle
  579.              PUT handle, 1, xmBuf
  580.              CLOSE handle
  581.              RUN "PROG_B"
  582.  
  583.         Where xmBuf is DIM'ed as STRING * 530.
  584.  
  585.         Then PROG_B.BAS would take the following actions upon start-up:
  586.  
  587.              DIM xmBuf AS STRING * 530
  588.  
  589.              handle = FREEFILE
  590.              OPEN "XM_STATUS.DAT" FOR BINARY AS handle
  591.              GET handle, 1, xmBuf
  592.              CLOSE handle
  593.              KILL "XM_STATUS.DAT"
  594.  
  595.              CALL RestParamXM (VARSEG(xmBuf), VARPTR(xmBuf), errCode)
  596.  
  597.  
  598.                                   Routine Types
  599.  
  600.         The  routines  in QBXM can be broken down into  four  categories,
  601.         Status/Informational, Bulk Memory Moves, Full Screen Handling and
  602.         Record Orientated.
  603.  
  604.         Each procedure is described in detail on the following pages.
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.                                         10
  621.  
  622.  
  623.                                                              QBXM ver 1.0
  624.                                          Copyright 1991, Thomas J. Vought
  625.  
  626.  
  627.         NAME:     AutoCloseXM
  628.  
  629.         SYNTAX:   CALL AutoCloseXM
  630.  
  631.         PASS:     Nothing
  632.  
  633.         RETURNS:  Nothing
  634.  
  635.  
  636.         AutoCloseXM  registers the CloseAllXM routine with  BASIC.   When
  637.         the  current  application ends, all extra memory  that  has  been
  638.         allocated  is released.  The memory released will be  the  memory
  639.         allocated  by the current program and any that was  allocated  in
  640.         previous  programs,  if the extra memory status has  been  passed
  641.         from  previous programs to the current one properly.
  642.  
  643.         CloseAllXM  will be invoked by a CHAIN, RUN, END or STOP (not  in
  644.         QB) statement if AutoCloseXM has been previously invoked.
  645.  
  646.         I have found it best to use AutoCloseXM at the start of a program
  647.         when working in the QuickBASIC environment.  While developing  an
  648.         application,  you're more likely to stop and restart, or to  make
  649.         changes  to the code requiring a restart.  I have found  it  very
  650.         easy  to use up 3 megs of EMS by not remembering to  close  extra
  651.         memory handles that were opened by my program that didn't run  to
  652.         normal  termination.   If you don't  have  TurboPower  Software's
  653.         MAPMEM  program,  look for it.  A real help  during  development.
  654.         MAPMEM version 2.9 shows XMS memory also.
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.         EXAMPLE:
  674.                   CALL AutoCloseXM
  675.  
  676.  
  677.         SEE ALSO: CloseAllXM,  CloseScreenXM, CloseXM
  678.  
  679.  
  680.  
  681.  
  682.                                         11
  683.  
  684.  
  685.                                                              QBXM ver 1.0
  686.                                          Copyright 1991, Thomas J. Vought
  687.  
  688.  
  689.         NAME:     ClearNamesXM
  690.  
  691.         SYNTAX:   CALL ClearNamesXM
  692.  
  693.         PASS:     Nothing
  694.  
  695.         RETURNS:  Nothing
  696.  
  697.  
  698.         When  called, ClearNamesXM wipes out any names assigned to  extra
  699.         memory  handles that were allocated by the current (or  previous)
  700.         program(s).   It  is included to help maintain the  integrity  of
  701.         extra memory when your program terminates.
  702.  
  703.         When memory handles are assigned a name under an XMS environment,
  704.         the  first  call to PutNameXM allocates a 2k  block  of  extended
  705.         memory for use by QBXM to handle the housekeeping involved.    As
  706.         handles are named, searched for and subsequently closed, this  2k
  707.         block  of  memory is accessed and updated.  There is  no  way  to
  708.         directly  access this memory block from BASIC, but it  does  have
  709.         to  be  released when your program terminates, otherwise  the  2k
  710.         would not be available to later applications.
  711.  
  712.         When  the  CloseAllXM routine is called, it in turn  evokes  this
  713.         routine  to make sure that the 2k XMS buffer is released.   Auto-
  714.         CloseXM ensures that CloseAllXM is called when the program termi-
  715.         nates, so most bases are covered.  Care has to be taken to ensure
  716.         that  the  2k block is released when memory  handles  are  closed
  717.         individually, and your program has used the PutNameXM routine.
  718.  
  719.         If  you  do not use CloseAllXM or AutoCloseXM, and  you  use  the
  720.         PutNameXM routine, then ClearNamesXM should be called at the  end
  721.         of your program.  There is no way for QBXM to 'know' to close out
  722.         the named handle buffer unless you instruct it to do so.
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.         SEE ALSO: AutoCloseXM, CloseAllXM, PutNameXM
  740.  
  741.  
  742.  
  743.  
  744.                                         12
  745.  
  746.  
  747.                                                              QBXM ver 1.0
  748.                                          Copyright 1991, Thomas J. Vought
  749.  
  750.  
  751.         NAME:     CloseAllXM
  752.  
  753.         SYNTAX:   CALL CloseAllXM
  754.  
  755.         PASS:     Nothing
  756.  
  757.         RETURNS:  Nothing
  758.  
  759.  
  760.         CloseAllXM releases all extra memory, including any screen memory
  761.         or  named  handle memory that was allocated  by  your  program(s)
  762.         through  QBXM.   This routine is invoked  when  your  application
  763.         terminates, if AutoCloseXM was called previously.
  764.  
  765.         If  you  do not use AutoCloseXM, for instance  when  CHAINing  or
  766.         RUNning other programs that will access the same handles in extra
  767.         memory, then this procedure must be called when the program  ends
  768.         either because of an error or a normal termination.
  769.  
  770.         Remember  that both the expanded and extended  memory  specifica-
  771.         tions  rely  on applications deallocating memory  when  they  are
  772.         finished with the resources.  If you don't deallocate the memory,
  773.         it will not be available again until you reboot.
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.         EXAMPLE:
  795.  
  796.                   CALL CloseAllXM
  797.                   END
  798.  
  799.  
  800.  
  801.         SEE ALSO: AutoCloseXM,  CloseScreenXM, CloseXM
  802.  
  803.  
  804.  
  805.  
  806.                                         13
  807.  
  808.  
  809.                                                              QBXM ver 1.0
  810.                                          Copyright 1991, Thomas J. Vought
  811.  
  812.  
  813.         NAME:     CloseScreenXM
  814.  
  815.         SYNTAX:   CALL CloseScreenXM
  816.  
  817.         PASS:     Nothing
  818.  
  819.         RETURNS:  Nothing
  820.  
  821.  
  822.         CloseScreenXM closes a previously opened extra memory buffer used
  823.         for screen display and swapping.  No parameters need to be passed
  824.         because QBXM tracks the memory handle assigned to a screen inter-
  825.         nally.
  826.  
  827.         Extra  memory  allocated for screen storage is  released  by  the
  828.         CloseAllXM or AutoCloseXM routines also.
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.         EXAMPLE:
  858.                   CALL CloseScreenXM
  859.  
  860.  
  861.  
  862.  
  863.         SEE ALSO: OpenScreenXM
  864.  
  865.  
  866.  
  867.  
  868.                                         14
  869.  
  870.  
  871.                                                              QBXM ver 1.0
  872.                                          Copyright 1991, Thomas J. Vought
  873.  
  874.  
  875.         NAME:     CloseXM
  876.  
  877.         SYNTAX:   CALL CloseXM (handle%, errCode%)
  878.  
  879.         PASS:     handle%   the extra memory handle that was returned by
  880.                             one of the extra memory open routines.
  881.  
  882.         RETURNS:  errCode%  equal to zero if no problems are encountered.
  883.  
  884.  
  885.         CloseXM  releases any memory that was allocated to the  specified
  886.         handle,  without affecting the status of any other  extra  memory
  887.         handles.
  888.  
  889.         The method used to open the extra memory handle is not important.
  890.         Handles are returned for record orientated and bulk memory  allo-
  891.         cations only.
  892.  
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.         EXAMPLE:
  914.                   pgs = 3
  915.                   invLen = LEN (invoiceRecord)
  916.                   CALL OpenRecXM (pgs, invLen, invHandle, errCode)
  917.                   ...
  918.                   ...
  919.                   ...
  920.                   CALL CloseXM (invHandle, errCode)
  921.  
  922.  
  923.  
  924.  
  925.         SEE ALSO: AutoCloseXM,  CloseAllXM, CloseScreenXM
  926.  
  927.  
  928.  
  929.  
  930.                                         15
  931.  
  932.  
  933.                                                              QBXM ver 1.0
  934.                                          Copyright 1991, Thomas J. Vought
  935.  
  936.  
  937.         NAME:     Conv2XM
  938.  
  939.         SYNTAX:
  940.  
  941.            CALL Conv2XM (fSeg%, fOfs%, hndle%, bytes%, xmOfs&, errCode%)
  942.  
  943.         PASS:
  944.              fSeg%     The segment address of the memory block you want
  945.                        to move to extra memory.  VARSEG(variable)
  946.  
  947.              fOfs%     The offset address of the memory block you want
  948.                        to move to extra memory.  VARPTR(variable)
  949.  
  950.              hndle%    The extra memory handle that was returned by a
  951.                        previous OpenXM call.
  952.  
  953.              bytes%    The EVEN number of bytes to transfer, must be
  954.                        less than or equal to 64k.
  955.  
  956.              xmOfs&    A long integer specifying where in extra memory
  957.                        the data is to be placed.  First byte = 0.
  958.  
  959.         RETURNS:
  960.              errCode%  If there is a problem.
  961.  
  962.  
  963.         Right off I'm going to tell you to avoid passing variable  length
  964.         strings.  The address calculations, SADD, SSEG and all will  make
  965.         you  crazy,  plus there is the LEN calculation on  each,  keeping
  966.         track of where in extra memory different strings are etc.   Think
  967.         in structures, arrays, records, user defined types etc.  It  will
  968.         keep your programming challenges to a minimum.
  969.  
  970.         That  said, Conv2XM is a bulk memory move type  operation,  where
  971.         you  specify the location of the data in the conventional  memory
  972.         BASIC  data area.  The routine needs both the segment and  offset
  973.         addresses  of the source memory.  Target memory consists of  both
  974.         an extra memory handle and an offset within that handle at  which
  975.         to start storing x number of bytes.
  976.  
  977.         This routine is intended for passing arrays into and out of extra
  978.         memory, whether they are arrays of integers, longs, single preci-
  979.         sion,  double  precision or a user defined type.  The key  is  to
  980.         remember  that  the bytes to move should be an even  number.  The
  981.         only  place where an odd number of bytes may become a  factor  is
  982.         with a user defined type with an odd number of subscripts.
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.                                         16
  993.  
  994.  
  995.                                                              QBXM ver 1.0
  996.                                          Copyright 1991, Thomas J. Vought
  997.  
  998.         NAME:     Conv2XM   (continued)
  999.  
  1000.         Calculating  the  number of bytes depends on the  type  of  array
  1001.         times  the number of elements.  Each integer element  requires  2
  1002.         bytes,  a long or single precision requires 4 and a  currency  or
  1003.         double  precision  requires  8 bytes.  A  user  defined  type  of
  1004.         course, can be variable.
  1005.  
  1006.         EXAMPLE:
  1007.  
  1008.         TYPE CustomerRecord
  1009.              name      AS STRING * 26
  1010.              addr1     AS STRING * 26
  1011.              addr2     AS STRING * 26
  1012.              city      AS STRING * 16
  1013.              state     AS STRING * 2
  1014.              zip       AS STRING * 5
  1015.              acctID    AS STRING * 9
  1016.         END TYPE
  1017.  
  1018.         DIM SHARED customer AS CustomerRecord
  1019.                ...
  1020.                ...
  1021.              cLen = LEN (customer)
  1022.              f$ = "CUSTOMER.DAT"
  1023.              CALL LoadFileXM (f$, cLen, cHandle, cAvail&, errCode)
  1024.               ...
  1025.               ...
  1026.              INPUT "Customer ID: ",id$
  1027.              id$ = UCASE$(id$)
  1028.              id$ = LEFT$(id$ + STRING$(9,0), 9)       'Think 0 is right.
  1029.              CALL GetCustomer (id$, found)
  1030.  
  1031.         SUB GetCustomer (id$, found)
  1032.              SHARED cHandle, cAvail&
  1033.  
  1034.            'Routine searches the customer database previously loaded into
  1035.            'extra memory, for the customer ID passed in.  Returns found
  1036.            'equal to the record number and the customer record filled in.
  1037.            'If not found, will return found = 0.  CASE sensitive.
  1038.  
  1039.              memFree& = FRE(-1)                   'How much memory free?
  1040.  
  1041.              IF memFree& > 64000& THEN
  1042.                   memFree& = 64000&               'Stay within 64k limit.
  1043.              END IF
  1044.  
  1045.              elements& = memFree& / LEN(customer)
  1046.  
  1047.              IF elements& > 32000& THEN elements& = 32000&
  1048.              IF elements& > cAvail& THEN elements& = cAvail&
  1049.                 ....(continued)....
  1050.  
  1051.  
  1052.  
  1053.  
  1054.                                         17
  1055.  
  1056.  
  1057.                                                              QBXM ver 1.0
  1058.                                          Copyright 1991, Thomas J. Vought
  1059.  
  1060.         NAME:     Conv2XM   (continued)
  1061.  
  1062.              DIM temp(1 to elements&) AS CustomerRecord
  1063.  
  1064.              a& = elements& * LEN(customer)     'Bytes to move might be
  1065.              byteHex$ = HEX$(a&)                'greater than 32767. If
  1066.              bytes = VAL (byteHex$)             'so, this will pass a
  1067.                                                 'negative number.
  1068.              xmOfs& = 0                         'Read from offset in XM
  1069.              count = 0                          'Elements checked
  1070.              found = 0                          'Assume not found
  1071.  
  1072.              DO
  1073.                vSeg = VARSEG(temp(1))           'May move, so check
  1074.                vPtr = VARPTR(temp(1))           '  before each call.
  1075.                CALL XM2Conv (vSeg, vPtr, cHandle, bytes, xmOfs&, errCode)
  1076.  
  1077.                FOR i = 1 TO elements
  1078.                   IF temp(i).acctID = id$ THEN
  1079.                      found = count + i
  1080.                      customer = temp(i)
  1081.                      EXIT SUB
  1082.                   END IF
  1083.                NEXT
  1084.  
  1085.                count = count + elements
  1086.                xmOfs& = xmOfs& + bytes
  1087.              LOOP UNTIL count > cAvail
  1088.  
  1089.         END SUB
  1090.  
  1091.  
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.  
  1099.  
  1100.  
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.         SEE ALSO:      XM2Conv
  1112.  
  1113.  
  1114.  
  1115.  
  1116.                                         18
  1117.  
  1118.  
  1119.                                                              QBXM ver 1.0
  1120.                                          Copyright 1991, Thomas J. Vought
  1121.  
  1122.  
  1123.         NAME:     GetNameXM
  1124.  
  1125.         SYNTAX:   CALL GetNameXM (handleName$, handle%, errCode%)
  1126.  
  1127.         PASS:     handleName$    A string specifying the text to search
  1128.                                  for.
  1129.  
  1130.         RETURNS:  handle%        The integer extra memory handle that
  1131.                                  handleName is assigned to, if not found
  1132.                                  will be zero.
  1133.  
  1134.                   errCode%       If the handle name is not found, or
  1135.                                  another error occurs.
  1136.  
  1137.  
  1138.         REQUIRES: EMS version 4.0 only if EMS is in use.
  1139.  
  1140.  
  1141.         GetNameXM  allows you to search the extra memory handles  in  use
  1142.         for  a specified name.  Case is not sensitive, handle  names  are
  1143.         converted  to all uppercase by PutNameXM when it is assigned  and
  1144.         the name you pass to GetNameXM is converted before the search.
  1145.  
  1146.         Now a little technical note.  The XMS (extended memory)  specifi-
  1147.         cation does not provide for named handles.  QBXM implements  them
  1148.         internally and uses it's own routines to manipulate them.   Named
  1149.         handles are a feature of EMS (expanded memory) specification 4.0,
  1150.         and  QBXM uses the expanded memory manager to manage  the  handle
  1151.         names.   This  brings up two points.  One is that  attempting  to
  1152.         call GetNameXM or PutNameXM when running under EMS versions lower
  1153.         than  4  will cause an errCode return.  My feeling is  that  this
  1154.         should  not  be a problem, EMS 4.0 having been available  for  as
  1155.         long as it has.  However, when GetXM is called, it may be  advan-
  1156.         tageous  to  check the major% variable returned if flag%  is  re-
  1157.         turned  equal  to 1 (EMS), and your code uses  the  named  handle
  1158.         routines.   The  second thing is the rare  possibility  that  two
  1159.         different programs running under a multitasking system may employ
  1160.         the  same handle.  Slim chance, I agree, but I felt it should  be
  1161.         mentioned,  as your code may be running in tandem.  Again,  these
  1162.         are  only  situations that may arise when your  code  is  running
  1163.         under  EMS.  Under XMS, with QBXM handling the names, there  will
  1164.         be no conflict because the multiple sessions will each have their
  1165.         own, individual environments.
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.         SEE ALSO: PutNameXM
  1174.  
  1175.  
  1176.  
  1177.  
  1178.                                         19
  1179.  
  1180.  
  1181.                                                              QBXM ver 1.0
  1182.                                          Copyright 1991, Thomas J. Vought
  1183.  
  1184.  
  1185.         NAME:     GetPagesXM
  1186.  
  1187.         SYNTAX:   CALL GetPagesXM (total%, pages%)
  1188.  
  1189.         PASS:     Nothing
  1190.  
  1191.         RETURNS:  For expanded memory:
  1192.  
  1193.                        total%    equals the pages of memory installed.
  1194.  
  1195.                        pages%    equals the number of free (unallocated)
  1196.                                  pages.
  1197.  
  1198.                   For extended memory:
  1199.  
  1200.                        total%    equals the number of pages available.
  1201.  
  1202.                        pages%    equals the largest number of pages that
  1203.                                  can be allocated to a handle.
  1204.  
  1205.  
  1206.         GetPagesXM  can be called to determine what the status  of  extra
  1207.         memory is at a particular point.  If a memory allocation  request
  1208.         fails with a "not enough memory available" error, GetPagesXM  can
  1209.         be  called to determine what amount may be available.  Your  pro-
  1210.         gram  should  then take appropriate action based  on  the  amount
  1211.         available.
  1212.  
  1213.         There  is a slight difference in the total% variable passed  back
  1214.         from GetPagesXM depending on whether EMS or XMS is in use.   With
  1215.         EMS  the  total  variable is the total  of  physically  installed
  1216.         pages.   With XMS, the total variable represents the total amount
  1217.         of free extended memory, not the physically installed amount.  If
  1218.         another program is concurrently using extended memory, you  won't
  1219.         know about it.  There may be occasions in a multi-tasking  situa-
  1220.         tion  where extended memory is broken up, and the pages  variable
  1221.         will  be  lower then the total variable.  With  extended  memory,
  1222.         pages indicates the largest block of memory that can be allocated
  1223.         to one handle.
  1224.  
  1225.         EXAMPLE:
  1226.              'Calculate amount of extra memory needed to store an array:
  1227.              needed& = (UBOUND(array) - LBOUND(array) + 1) * bytesPerElem
  1228.              pgsNeeded = CINT(needed& \ 16384)
  1229.              IF needed& MOD 16384 then pgsNeeded = pgsNeeded + 1
  1230.              CALL GetPagesXM (total, free)
  1231.              IF free >= pgsNeeded THEN
  1232.                   CALL OpenXM (pgsNeeded, arrayHandle, errCode)
  1233.              ELSE .....
  1234.  
  1235.  
  1236.         SEE ALSO: GetXM
  1237.  
  1238.  
  1239.  
  1240.                                         20
  1241.  
  1242.  
  1243.                                                              QBXM ver 1.0
  1244.                                          Copyright 1991, Thomas J. Vought
  1245.  
  1246.  
  1247.         NAME:     GetRecXM
  1248.  
  1249.         SYNTAX:   CALL GetRecXM (hndle%, recNum&, vSeg%, vPtr%, errCode%)
  1250.  
  1251.         PASS:     hndle%    the extra memory handle returned by QBXM when
  1252.                             the file was loaded, or the memory allocated.
  1253.  
  1254.                   recNum&   the record number to retrieve, (first record
  1255.                             is one) as a long integer.
  1256.  
  1257.                   vSeg%     is the segment where the record data is to be
  1258.                             put in BASIC's data area.
  1259.  
  1260.                   vPtr%     is the offset address where the record data
  1261.                             is to be put in BASIC's data area.
  1262.  
  1263.         RETURNS:  errCode%  if there is a problem.
  1264.  
  1265.         GetRecXM  retrieves a record from extra memory and stores  it  at
  1266.         the address specified by the vSeg and vPtr variables.  The varia-
  1267.         ble pointed to by the segment address and offset address must  of
  1268.         course,  be large enough to hold the record.  The record size  is
  1269.         determined  by the record length variable passed to QBXM  in  the
  1270.         LoadFileXM or OpenRecXM sub programs.
  1271.  
  1272.         EXAMPLE:
  1273.              TYPE InventoryRecord
  1274.                 part   AS STRING * 8
  1275.                 onHand AS INTEGER
  1276.                 cost   AS SINGLE
  1277.                 retail AS SINGLE
  1278.              END TYPE
  1279.  
  1280.              DIM SHARED inventory AS inventoryRecord
  1281.              'LoadFileXM etc....
  1282.              INPUT "Part? "; partWanted$
  1283.              getRec& = 1
  1284.              found% =0
  1285.              DO
  1286.                 CALL GetRecXM (iHndle%, getRec&, VARSEG(inventory) _
  1287.                           VARPTR(inventory), errCode%)
  1288.                 IF errCode% THEN ....
  1289.                 IF inventory.part = partWanted$ THEN
  1290.                   found% = -1
  1291.                   EXIT DO
  1292.                 ELSE
  1293.                   getRec& = getRec& + 1
  1294.                 END IF
  1295.              LOOP WHILE getRec& <= maxRecs&
  1296.  
  1297.         SEE ALSO: LoadFileXM, OpenXM, PutRecXM
  1298.  
  1299.  
  1300.  
  1301.  
  1302.                                         21
  1303.  
  1304.  
  1305.                                                              QBXM ver 1.0
  1306.                                          Copyright 1991, Thomas J. Vought
  1307.  
  1308.  
  1309.         NAME:     GetXM
  1310.  
  1311.         SYNTAX:   CALL GetXM (major%, minor%, flag%)
  1312.  
  1313.         PASS:     Nothing
  1314.  
  1315.         RETURNS:  major%    the integer portion of the EMS/XMS driver
  1316.                             version installed.
  1317.  
  1318.                   minor%    the fractional portion of the EMS/XMS driver
  1319.                             version installed.
  1320.  
  1321.                   flag%     indicates what type of extra memory is
  1322.                             installed:
  1323.                                 0  =  None
  1324.                                 1  =  Expanded (EMS)
  1325.                                 2  =  Extended (XMS)
  1326.  
  1327.         GetXM,  besides  returning  the  information  above,  initializes
  1328.         internal variables used by other routines in QBXM.  The important
  1329.         thing to remember is that this routine should only be called once
  1330.         by a single program, or once by the first program in a series  of
  1331.         programs that are CHAIN'd to, or RUN by the initial program.   If
  1332.         the  version of the driver, or the type of driver is of  concern,
  1333.         it should be passed in common to other programs in the chain.
  1334.  
  1335.         The major version of the driver is returned as an integer, as  is
  1336.         the  minor version.  Dividing the minor version integer  returned
  1337.         by 10 should be sufficient for most needs.  For example:
  1338.  
  1339.              CALL GetXM (major%, minor%, flag%)
  1340.              version! = major% + (minor% / 10)
  1341.              IF flag% = 1 THEN PRINT USING "EMS version: #.##"; version%
  1342.              IF flag% = 2 THEN PRINT USING "XMS version: #.##"; version%
  1343.  
  1344.         GetXM must be called before any other routine in QBXM so that the
  1345.         type  of extra memory being used can be determined for  following
  1346.         routines.  Most other routines will fail with an error code of -1
  1347.         (no  extra  memory)  if GetXM hasn't been  called.   The  Screen-
  1348.         CountXM% FUNCTION is an exception, it can be called before  GetXm
  1349.         and will return 0.
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.  
  1359.         SEE ALSO: GetPagesXM
  1360.  
  1361.  
  1362.  
  1363.  
  1364.                                         22
  1365.  
  1366.  
  1367.                                                              QBXM ver 1.0
  1368.                                          Copyright 1991, Thomas J. Vought
  1369.  
  1370.  
  1371.         NAME:     LoadFileXM
  1372.  
  1373.         SYNTAX:   CALL LoadFileXM (fileNme$,recLen%,hndle%,recs&,eCode%)
  1374.  
  1375.         PASS:     fileNme$  A fully qualified file name that can include
  1376.                             a drive and path.
  1377.  
  1378.                   recLen%   Specify the size of the records in the file
  1379.                             for use by the GetRecXM, PutRecXM, SaveFileXM
  1380.                             routines etc.
  1381.  
  1382.         RETURNS:  hndle%    An extra memory handle that can used by other
  1383.                             QBXM routines to access the data from the
  1384.                             file.
  1385.  
  1386.                   recs&     A LONG integer indicating the number of
  1387.                             records loaded from the file.
  1388.  
  1389.                   eCode%    If there is a problem.
  1390.  
  1391.  
  1392.         LoadFileXM  attempts to copy a file from disk into extra  memory.
  1393.         The extra memory allocated is always rounded up to the next page.
  1394.         For example, a 20,000 byte file of 20 byte long records would use
  1395.         two pages of extra memory, or 32,768 bytes.  The records&  varia-
  1396.         ble  returned divides the total bytes in the file by  the  record
  1397.         size.   In  the  above example, 20,000 divided by  20  bytes  per
  1398.         record would return a record count of 1000.  The actual number of
  1399.         records  that can be stored in extra memory can be determined  by
  1400.         using  the  RecCountXM&  FUNCTION.  The  difference  between  the
  1401.         memory space allocated and the number of records in the file   is
  1402.         the amount you can add to the memory 'file' before a write is re-
  1403.         quired.   In  the above example, 1638 records& in  extra  memory,
  1404.         (32,768  \  20 = 16384) less 1000 records in the file  means  638
  1405.         records can be added without an extra memory error.  If the  file
  1406.         size happens to be an exact multiple of 16,384, an extra page  is
  1407.         still  allocated.   For example a file of 2048 records,  each  32
  1408.         bytes long would create a file size of 65,536 bytes.  When  load-
  1409.         ed, an extra page would be added: 65,536 + 16,384 = 81,920  bytes
  1410.         of  extra memory (5 pages) would be allocated.  The 81,920  bytes
  1411.         divided by a record size of 32 means that RecCountXM would return
  1412.         2560, allowing an extra 512 records to be appended to the file.
  1413.  
  1414.         You can use SaveFileXM when the memory 'file' reaches it's  maxi-
  1415.         mum extra memory allocation, close the extra memory handle,  then
  1416.         call LoadFileXM again to gain more room for appending records.
  1417.  
  1418.         LoadFileXM will run slower when XMS is in use then when EMS is in
  1419.         use.  For details, see the documentation appendix file.
  1420.  
  1421.         SEE ALSO: GetRecXM, PutRecXM, SaveFileXM
  1422.  
  1423.  
  1424.  
  1425.  
  1426.                                         23
  1427.  
  1428.  
  1429.                                                              QBXM ver 1.0
  1430.                                          Copyright 1991, Thomas J. Vought
  1431.  
  1432.  
  1433.         NAME:     LoadScrFileXM
  1434.  
  1435.         SYNTAX:   CALL LoadScrFileXM (fileName$, screenCount%, errCode%)
  1436.  
  1437.         PASS:     fileName$      The fully qualified file name to load.
  1438.  
  1439.         RETURNS:  screenCount%   The number of screens in the file.
  1440.  
  1441.                   errCode%       If there is a problem.
  1442.  
  1443.  
  1444.         LoadScrFileXM loads a file into extra memory that can be  manipu-
  1445.         lated  by the SaveScreenXM, RestScreenXM and  SaveScrFileXm  rou-
  1446.         tines.  The screens used by all the QBXM routines are full sized,
  1447.         25 row by 80 column text screens, and use video page 0 only.
  1448.  
  1449.         The screenCount% variable returned by this routine is a count  of
  1450.         the  screens in the file.  Each screen requires 4,000  bytes,  so
  1451.         the  file size being loaded is divided by 4,000 to determine  the
  1452.         proper value for screenCount%.  Note that a full page multiple is
  1453.         always  allocated, so there may be room to store an extra  screen
  1454.         or two.  The number of screens allocated can always be determined
  1455.         with the ScreenCountXM% FUNCTION.
  1456.  
  1457.         My examples use help screens, but "Fill in the form" screens  are
  1458.         another good use for these routines.
  1459.  
  1460.         EXAMPLE:
  1461.  
  1462.              f$ = drive$ + ":\" + path$ + "HELPSCRN.DAT"
  1463.              CALL LoadScrFileXM (f$, helpScreens, errCode)
  1464.              lastScreen = ScreenCountXM%
  1465.              ...
  1466.              'user hits help Function key, set helpNumber based on
  1467.              'operation currently being implemented, then CALL a
  1468.              'a BASIC routine that looks like...
  1469.              ....
  1470.              CALL SaveScreenXM(lastScreen, errCode)
  1471.              CALL RestScreenXM(helpNumber, errCode)
  1472.              DO:LOOP WHILE INKEY$ = ""
  1473.              CALL RestScreenXM(lastScreen, errCode)
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.         SEE ALSO: OpenScreenXM, CloseScreenXM
  1484.                   SaveScrFileXM, ScreenCountXM%
  1485.  
  1486.  
  1487.  
  1488.                                         24
  1489.  
  1490.  
  1491.                                                              QBXM ver 1.0
  1492.                                          Copyright 1991, Thomas J. Vought
  1493.  
  1494.  
  1495.         NAME:     OpenRecXM
  1496.  
  1497.         SYNTAX:   CALL OpenRecXM (pages%, recLen%, handle%, errCode%)
  1498.  
  1499.         PASS:     pages%    Number of 16k blocks of memory requested.
  1500.  
  1501.                   recLen%   The record length to assign to this handle.
  1502.                             The record length must be an even number.
  1503.  
  1504.         RETURNS:  handle%   The extra memory handle assigned to the block
  1505.                             allocated, if successful.
  1506.  
  1507.                   errCode%  If there is a problem.
  1508.  
  1509.  
  1510.         OpenRecXM allows you to allocate a block of extra memory that you
  1511.         can access with the record orientated QBXM routines.  The  record
  1512.         length  you  pass must be even (a multiple of 2)  and  is  stored
  1513.         internally  by QBXM so it does not have to be passed  with  every
  1514.         put or get call. If successful,  OpenRecXM  will return a  handle
  1515.         that  you must use to access the allocated block of  memory  with
  1516.         other routines.  If an error code is returned, the handle  number
  1517.         should be considered invalid.
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531.  
  1532.  
  1533.  
  1534.  
  1535.  
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.         SEE ALSO: CloseXM, GetRecXM, PutRecXM
  1546.  
  1547.  
  1548.  
  1549.  
  1550.                                         25
  1551.  
  1552.  
  1553.                                                              QBXM ver 1.0
  1554.                                          Copyright 1991, Thomas J. Vought
  1555.  
  1556.  
  1557.         NAME:     OpenScreenXM
  1558.  
  1559.         SYNTAX:   CALL OpenScreenXM (screenCount%, errCode%)
  1560.  
  1561.         PASS:     screenCount%   The number of full 25x80 screens you
  1562.                                  want to store in extra memory.
  1563.  
  1564.         RETURNS:  errCode%       If there is a problem.
  1565.  
  1566.  
  1567.         OpenScreenXM allocates 4000 bytes for each screen you specify  in
  1568.         the screenCount integer.  As with all the extra memory  routines,
  1569.         only  multiples of an extra memory page are allocated.  Since  an
  1570.         extra  memory page is 16384 bytes, a rule of thumb is that  there
  1571.         will be a multiple of 4 screens actually available.  If you  want
  1572.         to store a screen on the fly, you can usually do so by using  one
  1573.         of  the  extra screens that may be available.   The  ScreenCount%
  1574.         FUNCTION  is available to give the true number of screens  avail-
  1575.         able.
  1576.  
  1577.         No  extra memory handle is returned by the OpenScreenXM  routine.
  1578.         The  handle  is stored internally by QBXM, thus  eliminating  the
  1579.         need to store and pass an extra memory handle.
  1580.  
  1581.  
  1582.         EXAMPLE:
  1583.  
  1584.              '  Suppose that you always want space for an extra screen
  1585.              '  to be available for on the fly saves.
  1586.  
  1587.              screensNeeded = whatever
  1588.  
  1589.              IF screensNeeded MOD 4 = 0 THEN
  1590.                   screensNeeded = screensNeeded + 1
  1591.              END IF
  1592.  
  1593.              CALL OpenScreenXM (screensNeeded, errCode)
  1594.  
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.  
  1601.  
  1602.  
  1603.  
  1604.  
  1605.  
  1606.  
  1607.         SEE ALSO: CloseScreenXM, LoadScrFileXM
  1608.                   SaveScrFileXM, ScreenCountXM%
  1609.  
  1610.  
  1611.  
  1612.                                         26
  1613.  
  1614.  
  1615.                                                              QBXM ver 1.0
  1616.                                          Copyright 1991, Thomas J. Vought
  1617.  
  1618.  
  1619.         NAME:     OpenXM
  1620.  
  1621.         SYNTAX:   CALL OpenXM (pages%, handle%, errCode%)
  1622.  
  1623.         PASS:     pages%    The number of 16K extra memory pages needed.
  1624.  
  1625.         RETURNS:  handle%   An integer handle that must be used when
  1626.                             accessing the extra memory block.
  1627.  
  1628.                   errCode%  If there is a problem.
  1629.  
  1630.  
  1631.         OpenXM  allocates a block of extra memory, which can be  accessed
  1632.         with  the 'bulk' memory transfer routines, Conv2XM  and  XM2Conv.
  1633.         You  need to pass it the number of 16k pages that you  want,  and
  1634.         OpenXM  will return an integer extra memory handle that  you  can
  1635.         use to access the block.  The bulk memory routines are handy  for
  1636.         freeing up conventional memory to make room for more data as it's
  1637.         needed.   If  you use a number of arrays for instance,  that  are
  1638.         SHARED  throughout the program, it's possible to initialize  each
  1639.         one, store it in extra memory, ERASE the array, then continue the
  1640.         initialize,  store,  erase sequence for all the arrays.   When  a
  1641.         procedure  needs  to access the data, REDIM the array,  copy  the
  1642.         data  back from extra memory to conventional and use it.  If  the
  1643.         procedure  doesn't  change  the values in the array,  it  can  be
  1644.         erased again upon exit from the procedure, or if changed,  trans-
  1645.         ferred back to extra memory.
  1646.  
  1647.         Another  bulk  memory  move might use the BASIC  screen  pages  0
  1648.         through 3 (on a color machine), where QBXM's screen routines only
  1649.         save  and restore video page 0.  If you wanted to save  all  four
  1650.         video  pages, you would allocate one extra memory page, then  use
  1651.         Conv2XM to save the display pages like this:
  1652.  
  1653.              CALL OpenXM (1, handle, errCode)
  1654.              IF errCode THEN.....
  1655.              CALL Conv2XM(&hB800, 0, handle, 16384, 0&, errCode)
  1656.  
  1657.         Video pages are 4096 bytes long in the real world, so four  would
  1658.         require the full 16384 bytes.  The B800hex is the segment address
  1659.         of the color screen text buffer, B000hex is the monochrome  buff-
  1660.         er, which is only 4096 (1 video page) bytes long anyway.
  1661.  
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.         SEE ALSO: Conv2XM, XM2Conv
  1670.  
  1671.  
  1672.  
  1673.  
  1674.                                         27
  1675.  
  1676.  
  1677.                                                              QBXM ver 1.0
  1678.                                          Copyright 1991, Thomas J. Vought
  1679.  
  1680.  
  1681.         NAME:     PageCountXM%  FUNCTION
  1682.  
  1683.         SYNTAX:   x% = PageCountXM% (handle%)
  1684.  
  1685.         PASS:     handle%   The extra memory handle your inquiring about.
  1686.  
  1687.         RETURNS:            An integer count of the pages allocated to
  1688.                             the specified handle.
  1689.  
  1690.  
  1691.  
  1692.         PageCountXM is an INTEGER FUNCTION (and as such must be  declared
  1693.         to  be of use!) that returns the number of pages that  have  been
  1694.         allocated to a specific extra memory handle.  This is useful  for
  1695.         when a previous program allocated the extra memory and you'd like
  1696.         to know what is available in a later program.
  1697.  
  1698.         When loading a file into extra memory, QBXM rounds up to the next
  1699.         full page, so there is always room to append extra records.  If a
  1700.         subsequent program is running after the file has been  allocated,
  1701.         the  previous  program should pass the number of  valid  records.
  1702.         Then  this routine can be called to determine the number  of  re-
  1703.         cords that can be appended to the extra memory 'file'.
  1704.  
  1705.         Formula would be (assuming handle% and validRecs& are known):
  1706.  
  1707.              x% = PageCountXM (handle%)
  1708.              totalRecs& = (CLNG(x%) * 16384&) \ recSize%
  1709.              freeRecs& = totalRecs& - validRecs&
  1710.  
  1711.  
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.  
  1724.  
  1725.  
  1726.  
  1727.  
  1728.  
  1729.  
  1730.  
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.                                         28
  1737.  
  1738.  
  1739.                                                              QBXM ver 1.0
  1740.                                          Copyright 1991, Thomas J. Vought
  1741.  
  1742.  
  1743.         NAME:     PutNameXM
  1744.  
  1745.         SYNTAX:   CALL PutNameXM (hName$, handle%, errCode%)
  1746.  
  1747.         PASS:     hName$    A string specifying the text name to assign
  1748.                             to the extra memory handle.  8 bytes max.
  1749.  
  1750.                   handle%   The integer extra memory handle that hName$
  1751.                             is to be assigned to.
  1752.  
  1753.         RETURNS:  errCode%  If there is a problem.
  1754.  
  1755.  
  1756.         REQUIRES: EMS version 4.0 only if EMS is in use.
  1757.  
  1758.  
  1759.         PutNameXM  allows you to assign an extra memory handle  a  unique
  1760.         name.   Case is not sensitive, handle names are converted to  all
  1761.         uppercase  by PutNameXM when called.  Only the first eight  bytes
  1762.         of handleName are used.
  1763.  
  1764.         Now a little technical note.  The XMS (extended memory)  specifi-
  1765.         cation does not provide for named handles.  QBXM implements  them
  1766.         internally and uses it's own routines to manipulate them.   Named
  1767.         handles are a feature of EMS (expanded memory) specification 4.0,
  1768.         and  QBXM uses the expanded memory manager to manage  the  handle
  1769.         names.   This  brings up two points.  One is that  attempting  to
  1770.         call GetNameXM or PutNameXM when running under EMS versions lower
  1771.         than  4  will cause an errCode return.  My feeling is  that  this
  1772.         should  not  be a problem, EMS 4.0 having been available  for  as
  1773.         long as it has.  However, when GetXM is called, it may be  advan-
  1774.         tageous  to  check the major% variable returned if flag%  is  re-
  1775.         turned  equal  to 1 (EMS), and your code uses  the  named  handle
  1776.         routines.   The  second thing is the rare  possibility  that  two
  1777.         different programs running under a multitasking system may employ
  1778.         the  same handle.  Slim chance, I agree, but I felt it should  be
  1779.         mentioned,  as your code may be running in tandem.  Again,  these
  1780.         are  only  situations that may arise when your  code  is  running
  1781.         under  EMS.  Under XMS, with QBXM handling the names, there  will
  1782.         be no conflict because the multiple sessions will each have their
  1783.         own, individual environments.
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.  
  1790.  
  1791.  
  1792.  
  1793.         SEE ALSO: GetNameXM
  1794.  
  1795.  
  1796.  
  1797.  
  1798.                                         29
  1799.  
  1800.  
  1801.                                                              QBXM ver 1.0
  1802.                                          Copyright 1991, Thomas J. Vought
  1803.  
  1804.  
  1805.         NAME:     PutRecXM
  1806.  
  1807.         SYNTAX:   CALL PutRecXM (hndle%, recNum&, vSeg%, vPtr%, errCode%)
  1808.  
  1809.         PASS:     hndle%    The integer extra memory handle returned
  1810.                             by OpenRecXM or LoadFileXM.
  1811.  
  1812.                   recNum&   A long integer indicating the record number,
  1813.                             the first record being 1.
  1814.  
  1815.                   vSeg%     The segment address of the variable that has
  1816.                             the data to move to extra memory.
  1817.  
  1818.                   vPtr%     The offset address of the variable that has
  1819.                             the data to move to extra memory.
  1820.  
  1821.         RETURNS:  errCode%  If there is a problem.
  1822.  
  1823.  
  1824.         PutRecXM takes a record variable in BASIC's data space and trans-
  1825.         fers it to extra memory, placing it in the position specified  by
  1826.         the record number you pass.  The length of the record in  BASIC's
  1827.         data space must be the same as the length you passed to OpenRecXM
  1828.         or  LoadFileXM when the extra memory was allocated.   The  record
  1829.         length for each extra memory handle opened for record type access
  1830.         is  stored  internally by QBXM, eliminating the need to  pass  it
  1831.         with every call to GetRecXM or PutRecXM.
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844.  
  1845.  
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.         SEE ALSO: GetRecXM, OpenRecXM
  1856.  
  1857.  
  1858.  
  1859.  
  1860.                                         30
  1861.  
  1862.  
  1863.                                                              QBXM ver 1.0
  1864.                                          Copyright 1991, Thomas J. Vought
  1865.  
  1866.  
  1867.         NAME:     RecCountXM& FUNCTION
  1868.  
  1869.         SYNTAX:   x& = RecCountXM& (handle%)
  1870.  
  1871.         PASS:     Memory handle of a 'record' orientated allocation.
  1872.  
  1873.         RETURNS:  A long integer indicating the number of records the
  1874.                   memory handle can hold.
  1875.  
  1876.  
  1877.         Remember  to  DECLARE  RecCountXM& as a  LONG  INTEGER  function,
  1878.         otherwise  BASIC will give you the old 'Array Not  Defined'  mes-
  1879.         sage.   If you fail to DECLARE it as a FUNCTION returning a  long
  1880.         integer, you'll get some pretty interesting results.   Forewarned
  1881.         is forearmed.
  1882.  
  1883.         RecCountXM&  is used to determine just how many records will  fit
  1884.         in  a specified extra memory handle.  The size of  the  allocated
  1885.         block of memory is divided by the record size that was  specified
  1886.         in the LoadFileXM or OpenRecXM call.
  1887.  
  1888.  
  1889.  
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.         SEE ALSO: LoadFileXM, OpenRecXM
  1918.  
  1919.  
  1920.  
  1921.  
  1922.                                         31
  1923.  
  1924.  
  1925.                                                              QBXM ver 1.0
  1926.                                          Copyright 1991, Thomas J. Vought
  1927.  
  1928.  
  1929.         NAME:     RestParamXM
  1930.  
  1931.         SYNTAX:   CALL RestParamXM (vSeg%, vOfs%, errCode%)
  1932.  
  1933.         PASS:     vSeg%     The segment address of a 530 byte buffer that
  1934.                             was filled in by a call to SaveParamXM
  1935.  
  1936.                   vOfs%     The offset address of the above buffer.
  1937.  
  1938.         RETURNS:  errCode%  If a problem is encountered.
  1939.  
  1940.  
  1941.         RestParamXM sets up the internal variables used by QBXM that were
  1942.         saved with SaveParamXM.  These two routines are intended for  use
  1943.         when  you  want to CHAIN or RUN another program that  will  share
  1944.         data  in the extra memory.  The buffer used must be at least  530
  1945.         bytes  long,  the  type can be anything  but  a  variable  length
  1946.         string.  So, all the following declarations will fit the bill:
  1947.  
  1948.              DIM buffer AS STRING * 530
  1949.              DIM buffer%(1 TO 265)
  1950.              DIM buffer&(1 TO 133)
  1951.              DIM buffer!(1 TO 133)
  1952.              DIM buffer#(1 TO 67)
  1953.  
  1954.         The fixed length string or integer array are best, as they  don't
  1955.         require any wasted bytes.
  1956.  
  1957.         If  you wish to CHAIN to another program that will use the  extra
  1958.         memory  allocated and initialized by a first program, the  buffer
  1959.         variable should be declared as COMMON SHARED in both programs.
  1960.  
  1961.         If you RUN a second program, then the only(?) method to pass  the
  1962.         buffer is via a disk file.  The receiving program should read  in
  1963.         the buffer, delete the file and call RestParamXM.
  1964.  
  1965.         Note that GetXM and CloseAllXM clear out all the internal  varia-
  1966.         bles  that QBXM uses, so care should be taken in cases  where   a
  1967.         chain of programs are going to be sharing extra memory.  Remember
  1968.         that  AutoCloseXM  will cause a call to CloseAllXM when  a  CHAIN
  1969.         statement  is encountered or a program terminates with an END  or
  1970.         RUN statement.
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.         SEE ALSO: SaveParamXM
  1980.  
  1981.  
  1982.  
  1983.  
  1984.                                         32
  1985.  
  1986.  
  1987.                                                              QBXM ver 1.0
  1988.                                          Copyright 1991, Thomas J. Vought
  1989.  
  1990.  
  1991.         NAME:     RestScreenXM
  1992.  
  1993.         SYNTAX:   CALL RestScreenXM (screenNum%, errCode%)
  1994.  
  1995.         PASS:     screenNum%    The desired screen number from extra
  1996.                                 memory.
  1997.  
  1998.         RETURNS:  errCode%      If there is a problem.
  1999.  
  2000.  
  2001.         RestScreenXM  copies  a specified screen (not  video  page)  from
  2002.         extra memory into the video adapter's memory for video page zero.
  2003.         The screen to be displayed can be placed into extra memory with a
  2004.         call to SaveScreenXM or LoadScrFileXM.
  2005.  
  2006.         Both  RestScreenXM  and  SaveScreenXM use  the  fastest  possible
  2007.         method to move screens back and forth in memory.  This will cause
  2008.         snow on some CGA adapters.  My feeling is that smaller code  size
  2009.         and  faster  execution are more important than making  sure  snow
  2010.         won't  appear  on  some  lower quality  CGA  adapters.   If  this
  2011.         presents  a  problem, let me know, and if there is  enough  of  a
  2012.         demand I may add CGA checking in future releases.
  2013.  
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.  
  2021.  
  2022.  
  2023.  
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.         SEE ALSO: OpenScreenXM, SaveScreenXM, LoadScrFileXM
  2042.  
  2043.  
  2044.  
  2045.  
  2046.                                         33
  2047.  
  2048.  
  2049.                                                              QBXM ver 1.0
  2050.                                          Copyright 1991, Thomas J. Vought
  2051.  
  2052.  
  2053.         NAME:     SaveFileXM
  2054.  
  2055.         SYNTAX:   CALL SaveFileXM (fileN$, handle%, records&, errCode%)
  2056.  
  2057.         PASS:     fileN$    The fully qualified file name to write.
  2058.  
  2059.                   handle%   The extra memory handle that has the data to
  2060.                             copy to the file.
  2061.  
  2062.                   records&  A long integer with the number of records to
  2063.                             write.
  2064.  
  2065.         RETURNS:  errCode%  An error code if a problem is encountered.
  2066.  
  2067.  
  2068.         SaveFileXM writes the data in extra memory to the file you speci-
  2069.         fy.   The  file name came include an optional drive and  path  if
  2070.         needed.  SaveFileXM starts at the first record in extra memory to
  2071.         save  the specified number of records.  If the file named is  not
  2072.         on disk, it is created, if it does exist on disk it is  truncated
  2073.         to zero bytes, then the extra memory data is written to the file.
  2074.         The operation is similar to BASIC's OPEN FOR OUTPUT file routine.
  2075.  
  2076.         My thinking in using an over-write file method is in keeping with
  2077.         my  idea that an entire file is being loaded in and  manipulated.
  2078.         If  an  APPEND method is desired, let me know, and  if  there  is
  2079.         demand, I will add it to any future updates.
  2080.  
  2081.         SaveFileXM will run slower when XMS is in use then when EMS is in
  2082.         use.  For details, see the documentation appendix file.
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.  
  2096.  
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.         SEE ALSO: LoadFileXM, OpenRecXM, GetRecXM, PutRecXM
  2104.  
  2105.  
  2106.  
  2107.  
  2108.                                         34
  2109.  
  2110.  
  2111.                                                              QBXM ver 1.0
  2112.                                          Copyright 1991, Thomas J. Vought
  2113.  
  2114.  
  2115.         NAME:     SaveParamXM
  2116.  
  2117.         SYNTAX:   CALL SaveParamXM (vSeg%, vOfs%, errCode%)
  2118.  
  2119.         PASS:     vSeg%     The segment address of a 530 byte buffer that
  2120.                             will be filled in by the routine.
  2121.  
  2122.                   vOfs%     The offset address of the above buffer.
  2123.  
  2124.         RETURNS:  errCode%  If a problem is encountered.
  2125.  
  2126.  
  2127.         SaveParamXM fills the specified buffer with the current values of
  2128.         the internal variables used by QBXM.  RestParamXM uses this  data
  2129.         to restore the extra memory state as it was when SaveParamXM  was
  2130.         called.  These two routines are intended for use when you want to
  2131.         CHAIN  or RUN another program that will share data in  the  extra
  2132.         memory.   The  buffer used must be at least 530 bytes  long,  the
  2133.         type  can be anything but a variable length string.  So, all  the
  2134.         following declarations will fit the bill:
  2135.  
  2136.              DIM buffer AS STRING * 530
  2137.              DIM buffer%(1 TO 265)
  2138.              DIM buffer&(1 TO 133)
  2139.              DIM buffer!(1 TO 133)
  2140.              DIM buffer#(1 TO 67)
  2141.  
  2142.         The fixed length string or integer array are best, as they  don't
  2143.         require any wasted bytes.
  2144.  
  2145.         If  you wish to CHAIN to another program that will use the  extra
  2146.         memory  allocated and initialized by a first program, the  buffer
  2147.         variable should be declared as COMMON SHARED in both programs.
  2148.  
  2149.         If you RUN a second program, then the only(?) method to pass  the
  2150.         buffer  is  via  a disk file.  The sending  program  should  call
  2151.         SaveParamXM,  open a disk file, write the buffer, close the  file
  2152.         and then run the subsequent program.
  2153.  
  2154.         Note that GetXM and CloseAllXM clear out all the internal  varia-
  2155.         bles  that QBXM uses, so care should be taken in cases  where   a
  2156.         chain of programs are going to be sharing extra memory.  Remember
  2157.         that  AutoCloseXM  will cause a call to CloseAllXM when  a  CHAIN
  2158.         statement  is encountered or a program terminates with an END  or
  2159.         RUN statement.
  2160.  
  2161.  
  2162.  
  2163.  
  2164.  
  2165.         SEE ALSO: RestParamXM
  2166.  
  2167.  
  2168.  
  2169.  
  2170.                                         35
  2171.  
  2172.  
  2173.                                                              QBXM ver 1.0
  2174.                                          Copyright 1991, Thomas J. Vought
  2175.  
  2176.  
  2177.         NAME:     SaveScreenXM
  2178.  
  2179.         SYNTAX:   CALL SaveScreenXM (screenNum%, errCode%)
  2180.  
  2181.         PASS:     screenNum%     Screen number to copy the current video
  2182.                                  page zero to.
  2183.  
  2184.         RETURNS:  errCode%       If there is a problem.
  2185.  
  2186.  
  2187.         SaveScreenXM  copies the contents of the current  display  (video
  2188.         page zero) to a specified screen in extra memory.  The screen  to
  2189.         be saved can be placed into extra memory at any location  (screen
  2190.         number) within the number of screens allocated via  LoadScrFileXM
  2191.         or  OpenScreenXM.  The screen can be displayed again with a  call
  2192.         to RestScreenXM.
  2193.  
  2194.         Both  RestScreenXM  and  SaveScreenXM use  the  fastest  possible
  2195.         method to move screens back and forth in memory.  This will cause
  2196.         snow on some CGA adapters.  My feeling is that smaller code  size
  2197.         and  faster  execution are more important than making  sure  snow
  2198.         won't  appear  on  some  lower quality  CGA  adapters.   If  this
  2199.         presents  a  problem, let me know, and if there is  enough  of  a
  2200.         demand I may add CGA checking in future releases.
  2201.  
  2202.  
  2203.  
  2204.  
  2205.  
  2206.  
  2207.  
  2208.  
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.  
  2215.  
  2216.  
  2217.  
  2218.  
  2219.  
  2220.  
  2221.  
  2222.  
  2223.  
  2224.  
  2225.  
  2226.  
  2227.         SEE ALSO: OpenScreenXM, RestScreenXM, SaveScrFileXM
  2228.  
  2229.  
  2230.  
  2231.  
  2232.                                         36
  2233.  
  2234.  
  2235.                                                              QBXM ver 1.0
  2236.                                          Copyright 1991, Thomas J. Vought
  2237.  
  2238.  
  2239.         NAME:     SaveScrFileXM
  2240.  
  2241.         SYNTAX:   CALL SaveScrFileXM (fileN$, scrCount%, errCode%)
  2242.  
  2243.         PASS:     fileN$    The fully qualified file name to write.
  2244.  
  2245.                   scrCount% The number of screens to write to the file.
  2246.  
  2247.         RETURNS:  errCode%  If there is a problem.
  2248.  
  2249.  
  2250.         SaveScrFileXM  saves a file onto disk from extra memory that  can
  2251.         be used later by the LoadScrFileXM routine.  The screens used  by
  2252.         all  the QBXM routines are full sized, 25 row by 80  column  text
  2253.         screens, and use video page 0 only.
  2254.  
  2255.         The  scrCount% variable passed to this routine is a count of  the
  2256.         screens  to be written to the file.  The first screen up  through
  2257.         scrCount%  will saved.  Each screen requires 4,000 bytes, so  the
  2258.         file size will be a multiple of 4,000.
  2259.  
  2260.         If  the  specified  file exists, it will  be  overwritten.   This
  2261.         routine behaves similar to BASIC's OPEN FOR OUTPUT file method.
  2262.  
  2263.  
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.  
  2270.  
  2271.  
  2272.  
  2273.  
  2274.  
  2275.  
  2276.  
  2277.  
  2278.  
  2279.  
  2280.  
  2281.  
  2282.  
  2283.  
  2284.  
  2285.  
  2286.  
  2287.  
  2288.  
  2289.         SEE ALSO: OpenScreenXM, CloseScreenXM
  2290.                   LoadScrFileXM, ScreenCountXM%
  2291.  
  2292.  
  2293.  
  2294.                                         37
  2295.  
  2296.  
  2297.                                                              QBXM ver 1.0
  2298.                                          Copyright 1991, Thomas J. Vought
  2299.  
  2300.  
  2301.         NAME:     ScreenCountXM%
  2302.  
  2303.         SYNTAX:   DECLARE FUNCTION ScreenCountXM% ()
  2304.                   screens% = ScreenCountXM%
  2305.  
  2306.         PASS:     Nothing.
  2307.  
  2308.         RETURNS:  Nothing.
  2309.  
  2310.  
  2311.         First,  always  remember to declare this routine  as  an  INTEGER
  2312.         function,  if you don't, you'll get an "Array Not Defined"  error
  2313.         message.  If you don't define it as an INTEGER function, when you
  2314.         call it, you may end up with a system hang.
  2315.  
  2316.         ScreenCountXM% returns the maximum number of screens that can  be
  2317.         stored  in  the extra memory screen buffer.  This should  not  be
  2318.         considered  as  a count of valid screens, because  there  may  be
  2319.         extra  screen  space  beyond  those actually  in  use.   See  the
  2320.         LoadScrFileXM and OpenScrXM routines for information on how extra
  2321.         memory is allocated for screen saving and restoring.
  2322.  
  2323.  
  2324.  
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.  
  2340.  
  2341.  
  2342.  
  2343.  
  2344.  
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.         SEE ALSO: LoadScrFileXM, OpenScreenXM
  2352.  
  2353.  
  2354.  
  2355.  
  2356.                                         38
  2357.  
  2358.  
  2359.                                                              QBXM ver 1.0
  2360.                                          Copyright 1991, Thomas J. Vought
  2361.  
  2362.  
  2363.         NAME:     XM2Conv
  2364.  
  2365.         SYNTAX:
  2366.  
  2367.            CALL XM2Conv (tSeg%, tOfs%, hndle%, bytes%, xmOfs&, errCode%)
  2368.  
  2369.         PASS:
  2370.              tSeg%     The segment address of the memory block you want
  2371.                        to fill from extra memory.  VARSEG(variable)
  2372.  
  2373.              tOfs%     The offset address of the memory block you want
  2374.                        to fill from extra memory.  VARPTR(variable)
  2375.  
  2376.              hndle%    The extra memory handle that was returned by a
  2377.                        previous OpenXM call.
  2378.  
  2379.              bytes%    The EVEN number of bytes to transfer, must be
  2380.                        less than or equal to 64k.
  2381.  
  2382.              xmOfs&    A long integer specifying where in extra memory
  2383.                        the data read is to start from.  First byte = 0.
  2384.  
  2385.         RETURNS:
  2386.              errCode%  If there is a problem.
  2387.  
  2388.         Right off I'm going to tell you to avoid passing variable  length
  2389.         strings.   That said, XM2Conv is a bulk memory move  type  opera-
  2390.         tion,  where you specify where the data space is in  the  conven-
  2391.         tional  BASIC data area.  The routine needs both the segment  and
  2392.         offset addresses of the target memory, and you must be sure  that
  2393.         the target memory is large enough to hold the byte count.  Source
  2394.         memory  consists  of both an extra memory handle  and  an  offset
  2395.         within that handle at which to start storing x number of bytes.
  2396.  
  2397.         This routine is intended for passing arrays into and out of extra
  2398.         memory, whether they are arrays of integers, longs, single preci-
  2399.         sion,  double  precision or a user defined type.  The key  is  to
  2400.         remember that the bytes to move should be an even number, and the
  2401.         only  place where an odd number of bytes may become a  factor  is
  2402.         with a user defined type with an odd number of subscripts.
  2403.  
  2404.         Calculating  the  number of bytes depends on the  type  of  array
  2405.         times  the number of elements.  Each integer element  requires  2
  2406.         bytes,  a long or single precision requires 4 and a  currency  or
  2407.         double  precision  requires  8 bytes.  A  user  defined  type  of
  2408.         course, can be variable.
  2409.  
  2410.  
  2411.  
  2412.  
  2413.         SEE ALSO:      Conv2XM
  2414.  
  2415.  
  2416.  
  2417.  
  2418.                                         39
  2419.  
  2420.  
  2421.                                                              QBXM ver 1.0
  2422.                                          Copyright 1991, Thomas J. Vought
  2423.  
  2424.                                   REGISTRATION
  2425.  
  2426.         QBXM is not public domain material, it is shareware.  As such you
  2427.         are  granted the right to use it for a 30 day evaluation  period,
  2428.         after  which you must register QBXM or discontinue it's use.   If
  2429.         you  received QBXM from a disk distribution service, any cost  to
  2430.         you  was for materials, shipping and handling.  Said  costs  were
  2431.         not  for the purposes of licensing the software on the disk,  the
  2432.         author  receives nothing from the fees you pay to a  distribution
  2433.         service.
  2434.  
  2435.         Under no circumstances is the right to distribute a program using
  2436.         the  QBXM  routines  granted, unless the QBXM  library  has  been
  2437.         registered.   Use QBXM for your personal uses during the  evalua-
  2438.         tion  period, and if you find it useful, please register it.   If
  2439.         you  wish to sell or distribute a program that uses QBXM,  regis-
  2440.         tration is mandatory.
  2441.  
  2442.         Registration cost is $25.00.  Registration allows you to use QBXM
  2443.         on one machine at a time.  Copy it to all the machines you devel-
  2444.         op  on if you'd like, but please realize that a licensed copy  of
  2445.         QBXM is intended for the licensee's use only.  Site licenses  are
  2446.         available at the following rates:
  2447.  
  2448.                   1 to 10 users:      $25.00 each
  2449.                  11 to 50 users:       20.00 each
  2450.                  51 and above:         15.00 each.
  2451.  
  2452.         Benefits for registering:
  2453.  
  2454.              1.   Your conscience will allow you to sleep at night.
  2455.  
  2456.              2.   Registered users receive a licensed copy of QBXM  suit-
  2457.         able for use in programs they distribute.
  2458.  
  2459.              3.   Your significant other won't think poorly of you.
  2460.  
  2461.              4.   Registered  users will receive a licensed copy  of  the
  2462.         next  upgrade  to the program, if any, delivered right  to  their
  2463.         door.
  2464.  
  2465.              5.  The  possibility of your being sucked up into a UFO  may
  2466.         be lessened.
  2467.  
  2468.              6.    If I get a 720/1.44 disk change problem  figured  out,
  2469.         I'll  throw in a copy of my personal disk copy program that  uses
  2470.         the QBXM routines to copy disks larger then 360k without swapping
  2471.         them  into  and out of the drive.  Don't know about you,  but  it
  2472.         drives  me  crazy when I have 4 megs of memory and have  to  swap
  2473.         disks into and out of the drive to copy them.
  2474.  
  2475.              7.   A BASIC 7.0 Far String Compatible library will be  sent
  2476.         to registered users.
  2477.         A registration form for your use is on the last page.
  2478.  
  2479.  
  2480.                                         40
  2481.  
  2482.  
  2483.                                                              QBXM ver 1.0
  2484.                                          Copyright 1991, Thomas J. Vought
  2485.  
  2486.                                     WARRANTY
  2487.  
  2488.         There isn't any.  QBXM is distributed as is, without any warranty
  2489.         of  any kind, express or implied, as to its fitness for any  par-
  2490.         ticular purpose.  Every attempt has been made to verify that QBXM
  2491.         works as described in this manual, and if there is a bug reported
  2492.         to  me, it will be corrected and distributed to registered  users
  2493.         as quickly as possible, with a description of any changes made to
  2494.         the library.
  2495.  
  2496.  
  2497.                                   CONTACTING ME
  2498.  
  2499.         I can be reached via US mail at:
  2500.  
  2501.              5 John Street
  2502.              Morganville, NJ  07751-9762
  2503.  
  2504.         On Compuserve via e-mail to Tom Vought, 70054,1367
  2505.  
  2506.         Or if you like to live dangerously, at:
  2507.  
  2508.              The Off-Hour Rockers BBS
  2509.              908-727-6785 or
  2510.              908-727-6917
  2511.  
  2512.         Both  nodes being 8N1 and 1200/2400/9600 (USR).  Join  the  BASIC
  2513.         conference at the main menu prompt (j;7), which I host and  leave
  2514.         a  message  to Tom Vought.  First time callers are  granted  full
  2515.         access, there is no upload-download ratio policy, and all in all,
  2516.         the  BBS  is there to just have fun on.  I will always  have  the
  2517.         latest  copy of QBXM on line for downloading from  conference  7,
  2518.         the BASIC conference.
  2519.  
  2520.         In  addition  to QBXM, the latest version of  123-Write  is  also
  2521.         always  available as 123Wnn.ZIP where nn is the  version  number.
  2522.         At  this time, 2.0 is the latest release, so a Z command  with  a
  2523.         filespec of 123W will find 123W20.ZIP.  123-Write is a  shareware
  2524.         library  for  QuickBASIC 4.0 and 4.5 and BASIC 6.0, 7.0  and  7.1
  2525.         that  allows you to write Lotus 123 compatible spreadsheet  files
  2526.         from  within  your  BASIC program.  Saves a lot  of  Lotus  Macro
  2527.         coding  and  related BASIC work  to  export/import  spreadsheets.
  2528.         Will  work  with any spreadsheet program that will  read  a  .WK?
  2529.         file.
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.  
  2537.  
  2538.  
  2539.  
  2540.  
  2541.  
  2542.                                         41
  2543.  
  2544.  
  2545.                                                              QBXM ver 1.0
  2546.                                          Copyright 1991, Thomas J. Vought
  2547.  
  2548.                                    Error Codes
  2549.  
  2550.         The EMS specifies error codes of one byte from 80 hex through  A4
  2551.         hex,  and  the  XMS specifies one byte error codes  from  80  hex
  2552.         through  B2 hex.  DOS will return error codes as one byte from  1
  2553.         through 5A.  Then of course, I want to be able to pass QBXM  spe-
  2554.         cific  errors  back to the calling procedure.  So, the  scheme  I
  2555.         came up with for the errCode integer returned by QBXM follows:
  2556.  
  2557.         Internal  errors  are negative, EMS and DOS errors  are  returned
  2558.         positive  with  the  error code byte unchanged,  and  XMS  errors
  2559.         (except  'Name not found' which is the same as the EMS code)  are
  2560.         positive,  but  the one byte error code is expanded to  two,  the
  2561.         prefix  byte being a 1, making them greater than 255.  The  codes
  2562.         returned are:
  2563.  
  2564.  
  2565.  
  2566.  
  2567.  
  2568.  
  2569.  
  2570.  
  2571.  
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.  
  2589.  
  2590.  
  2591.  
  2592.  
  2593.  
  2594.  
  2595.  
  2596.  
  2597.  
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.                                         42
  2605.  
  2606.  
  2607.                                                              QBXM ver 1.0
  2608.                                          Copyright 1991, Thomas J. Vought
  2609.  
  2610.         QBXM generated errors:
  2611.  
  2612.             Hex   Dec       Meaning:
  2613.  
  2614.            FFFF    -1       No extra memory installed, or not initialized
  2615.                             by GetXM.
  2616.  
  2617.            FFFE    -2       Out of range handle.  Must be between 1 and
  2618.                             127 inclusive.
  2619.  
  2620.            FFFD    -3       Page request out of range.  Must be between
  2621.                             1 and 512 inclusive.
  2622.  
  2623.            FFFC    -4       Record size not even.  All record lengths
  2624.                             must be a multiple of 2 bytes.
  2625.  
  2626.            FFFB    -5       A screen memory buffer is already open.  Only
  2627.                             one screen buffer can be open at a time.
  2628.  
  2629.            FFFA    -6       Screen number out of range.  Screens must be
  2630.                             between 1 and the maximum screen allocated,
  2631.                             inclusive.  The maximum screen number can be
  2632.                             determined with the ScreenCountXM% FUNCTION.
  2633.  
  2634.            FFF9    -7       No screen memory allocated.  OpenScreenXM or
  2635.                             LoadScrFileXM must be called before Put/Get
  2636.                             ScreenXM.
  2637.  
  2638.            FFF8    -8       Invalid record number.  The record number
  2639.                             passed to Get/Put RecXM is not within the
  2640.                             range of records allocated.  The maximum
  2641.                             value for the record number can be deter-
  2642.                             mined with the RecCountXM& FUNCTION.
  2643.  
  2644.            FFF7    -9       Invalid string passed.  Probably a null
  2645.                             string was passed to one of the QBXM
  2646.                             routines.
  2647.  
  2648.            FFEC   -20       These are codes I assigned for internal code
  2649.                             errors within QBXM.  In all my testing, I
  2650.            FFEB   -21       haven't encountered them.  If you should,
  2651.                             please contact me with as much detail as
  2652.                             possible about how the error was generated.
  2653.  
  2654.  
  2655.  
  2656.  
  2657.  
  2658.  
  2659.  
  2660.  
  2661.  
  2662.  
  2663.  
  2664.  
  2665.  
  2666.                                         43
  2667.  
  2668.  
  2669.                                                              QBXM ver 1.0
  2670.                                          Copyright 1991, Thomas J. Vought
  2671.  
  2672.         DOS Generated errors:
  2673.  
  2674.              (Some DOS critical errors  will be intercepted by BASIC, for
  2675.              example,  a  drive door being open.  Others should  only  be
  2676.              file related, and I limited this list to the likely ones.)
  2677.  
  2678.             Hex   Dec       Meaning (DOS generated):
  2679.  
  2680.               2     2       File not found.
  2681.  
  2682.               3     3       Path not found.
  2683.  
  2684.               4     4       Too many open files. (FILES= in CONFIG.SYS)
  2685.  
  2686.               5     5       Access denied.
  2687.  
  2688.               6     6       Handle invalid. (Please report.)
  2689.  
  2690.               F    15       Invalid drive.
  2691.  
  2692.              13    19       Write protected disk.
  2693.  
  2694.              15    21       Drive not ready.
  2695.  
  2696.              17    23       Data error on Read.
  2697.  
  2698.              19    25       Seek error.
  2699.  
  2700.              1B    27       Sector not found.
  2701.  
  2702.              Then there are a ton of network related errors.  A good  DOS
  2703.         reference should be handy for that kind of work!
  2704.  
  2705.  
  2706.  
  2707.  
  2708.  
  2709.  
  2710.  
  2711.  
  2712.  
  2713.  
  2714.  
  2715.  
  2716.  
  2717.  
  2718.  
  2719.  
  2720.  
  2721.  
  2722.  
  2723.  
  2724.  
  2725.  
  2726.  
  2727.  
  2728.                                         44
  2729.  
  2730.  
  2731.                                                              QBXM ver 1.0
  2732.                                          Copyright 1991, Thomas J. Vought
  2733.  
  2734.         EMS Generated errors:
  2735.  
  2736.             Hex   Dec       Meaning:
  2737.  
  2738.              80   128       Internal error in expanded memory manager
  2739.                             software.  (Might be the driver's memory was
  2740.                             corrupted.)
  2741.  
  2742.              81   129       Hardware malfunction.
  2743.  
  2744.              82   130       Memory manager busy.  (Multi-Task? Retry I
  2745.                             suppose.)
  2746.  
  2747.              83   131       Invalid handle.  (QBXM should catch this one)
  2748.  
  2749.              84   132       Function not defined.  (Put/Get name with EMS
  2750.                             3.0 or 3.2? Otherwise let me know.)
  2751.  
  2752.              85   133       Handles exhausted.
  2753.  
  2754.              86   134       Contact author.
  2755.  
  2756.              87   135       Request is for more pages than physically
  2757.                             installed in machine.
  2758.  
  2759.              88   136       Request is for more pages than are currently
  2760.                             free.
  2761.  
  2762.              89   137       Tried to allocate zero pages.
  2763.  
  2764.              8A   138       Please contact me with the specifics.
  2765.              through        QBXM does not use any EMS functions that
  2766.              9F   159       should cause these errors.
  2767.  
  2768.              A0   160       No handle found for the specified name.  QBXM
  2769.                             should return handle=0 with GetNameXM.
  2770.  
  2771.              A1   161       There is already a handle with the same name.
  2772.                             QBXM converts all handle names to uppercase.
  2773.                             May occur if multiple copies of your code are
  2774.                             running.
  2775.  
  2776.              A3   163       Contact author.
  2777.  
  2778.              A4   164       Access denied by operating system.  Shouldn't
  2779.                             happen with QBXM.  Contact me with specifics.
  2780.  
  2781.  
  2782.  
  2783.  
  2784.  
  2785.  
  2786.  
  2787.  
  2788.  
  2789.  
  2790.                                         45
  2791.  
  2792.  
  2793.                                                              QBXM ver 1.0
  2794.                                          Copyright 1991, Thomas J. Vought
  2795.  
  2796.         XMS Generated errors:
  2797.  
  2798.             Hex   Dec       Meaning:
  2799.  
  2800.              A0   160       No handle found for the specified name.  QBXM
  2801.                             should return handle=0 with GetNameXM.
  2802.  
  2803.             180   384       Function not implemented.  Shouldn't happen.
  2804.  
  2805.             181   385       VDISK type device driver was detected.  XMS
  2806.                             will not load if there is VDISK type device
  2807.                             driver using extended memory, and will abort
  2808.                             functions if one is loaded after the XMS
  2809.                             driver.  See the appendix file for more info
  2810.                             on XMS and allocation strategies.
  2811.  
  2812.             182   386       An A20 line error occurred.  (Hardware Error)
  2813.  
  2814.             18E   398       General driver error.  (Memory corrupted?)
  2815.  
  2816.             18F   399       Unrecoverable driver error.
  2817.  
  2818.             190   400       Errors returned by functions that are not
  2819.              through        used by QBXM.  Probable memory corruption.
  2820.             194   404
  2821.  
  2822.             1A0   416       All extended memory is allocated.
  2823.  
  2824.             1A1   417       All extended memory handles exhausted.  XMS
  2825.                             allows up to 128 handles.  HIMEM.SYS defaults
  2826.                             to 32.  The /NUMHANDLES=nn switch can be used
  2827.                             on the command line in CONFIG.SYS to increase
  2828.                             the number available.
  2829.  
  2830.             1A2   418       Invalid handle.  QBXM should catch this,
  2831.                             please contact me if encountered.
  2832.  
  2833.             1A3   419       Errors returned by variables used within
  2834.              through        QBXM.  Please contact me with details.
  2835.             1A6   422
  2836.  
  2837.             1A7   423       Invalid length.  QBXM should catch this and
  2838.                             return -4, if not please supply me with the
  2839.                             conditions that caused this error.
  2840.  
  2841.             1A8   424       Invalid overlap in a move request.
  2842.  
  2843.             1A9   425       Parity error detected.
  2844.  
  2845.             1AA   426       Again, errors that shouldn't be generated by
  2846.              & above        any QBXM routines.  If they occur, please let
  2847.                             me know the details.
  2848.  
  2849.  
  2850.  
  2851.  
  2852.                                         46
  2853.  
  2854.  
  2855.                                                              QBXM ver 1.0
  2856.                                          Copyright 1991, Thomas J. Vought
  2857.  
  2858.                                   Routine Index
  2859.  
  2860.         Routine name and parameters:                                Page
  2861.  
  2862.         AutoCloseXM ()                                                11
  2863.         ClearNamesXM ()                                               12
  2864.         CloseAllXM ()                                                 13
  2865.         CloseScreenXM ()                                              14
  2866.         CloseXM (handle%, errCode%)                                   15
  2867.         Conv2XM (fSeg%, fOfs%, hndle%, bytes%, xmOfs&, eCode%)        16
  2868.         GetNameXM (hName$, handle%, errCode%)                         19
  2869.         GetPagesXM (total%, pages%)                                   20
  2870.         GetRecXM (handle%, recNum&, vSeg%, vPtr%, errCode%)           21
  2871.         GetXM (major%, minor%, flag%)                                 22
  2872.         LoadFileXM (filename$, reclen%, handle%, records&, errCode%)  23
  2873.         LoadScrFileXM (filename$, screenCount%, errCode%)             24
  2874.         OpenRecXM (pages%, reclen%, handle%, errCode%)                25
  2875.         OpenScreenXM (screenCount%, errCode%)                         26
  2876.         OpenXM (pages%, handle%, errCode%)                            27
  2877.         PageCountXM% (handle%)   FUNCTION                             28
  2878.         PutNameXM (hName$, handle%, errCode%)                         29
  2879.         PutRecXM (handle%, recNum&, vSeg%, vPtr%, errCode%)           30
  2880.         RecCountXM& () FUNCTION                                       31
  2881.         RestParamXM (vSeg%, vOfs%, errCode%)                          32
  2882.         RestScreenXM (screenNum%, errCode%)                           33
  2883.         SaveFileXM (filename$, handle%, records&, errCode%)           34
  2884.         SaveParamXM (vSeg%, vOfs%, errCode%)                          35
  2885.         SaveScreenXM (screenNum%, errCode%)                           36
  2886.         SaveScrFileXM (filename$, screenCount%, errCode%)             37
  2887.         ScreenCountXM% ()  FUNCTION                                   38
  2888.         XM2Conv (toSeg%, toOfs%, handle%, bytes%, xmOfs&, errCode%)   39
  2889.  
  2890.  
  2891.  
  2892.  
  2893.  
  2894.  
  2895.  
  2896.  
  2897.  
  2898.  
  2899.  
  2900.  
  2901.  
  2902.  
  2903.  
  2904.  
  2905.  
  2906.  
  2907.  
  2908.  
  2909.  
  2910.  
  2911.  
  2912.  
  2913.  
  2914.                                         47
  2915.  
  2916.  
  2917.                                                              QBXM ver 1.0
  2918.                                          Copyright 1991, Thomas J. Vought
  2919.  
  2920.  
  2921.         Please complete and mail to:
  2922.  
  2923.         Thomas J. Vought
  2924.         5 John Street
  2925.         Morganville, NJ  07751-9762
  2926.  
  2927.  
  2928.              NAME:     ________________________________________________
  2929.  
  2930.              STREET:   ________________________________________________
  2931.  
  2932.              CITY:     ________________________________________________
  2933.  
  2934.              STATE & ZIP:   ___________           _____________________
  2935.  
  2936.  
  2937.         For registration of QBXM version 1.0:
  2938.  
  2939.              COPIES:   ________  at: $__________  each =  $____________
  2940.  
  2941.         Disk format for registered copy and first upgrade:
  2942.  
  2943.              3.5" ______              5.25" ______
  2944.  
  2945.  
  2946.         Just curious, where did you get QBXM from?
  2947.  
  2948.              __________________________________________________________
  2949.  
  2950.              __________________________________________________________
  2951.  
  2952.  
  2953.         Comments?   I'd  love  to hear them, here, on the back  or  on  a
  2954.         separate page.  (Is the documentation clear etc?)
  2955.  
  2956.  
  2957.  
  2958.  
  2959.  
  2960.  
  2961.  
  2962.  
  2963.  
  2964.  
  2965.  
  2966.  
  2967.  
  2968.  
  2969.  
  2970.  
  2971.         Please  make  checks payable to Thomas J. Vought, and  mark  them
  2972.         "REG: QBXM 1.0".  Thank you.
  2973.  
  2974.  
  2975.  
  2976.                                         48
  2977.  
  2978.  
  2979.