[comp.sys.handhelds] HP48SX, Archiving of libraries.

cmeyer@forty2.physik.unizh.ch (Curtis A. Meyer) (03/17/91)

    As I make an ARCHIVE of my HP48 RAM once a week, I was aware 
of the fact that library objects in PORT 0 do not get put into
the ARCHIVEd copy. In order to get around this, I was simply 
making copies of these libraries before the ARCHIVE, and then
deleting the copies afterward. However, after having purchased and
installed J. Donnelly's "Programmer's Toolkit", this method was no
longer pratical due to memory limitaions, ( I have what appears to
be the "standard" configuration of a 128K RAM card and the HP SOLVE
ROM card). As such, I stopped making copies of my libraries for my
weekly ARCHIVE. Then, naturally, I had a "system crash", and needed
to RESTORE memory. Then go back through and find all the copies
of my libraries, and restore those too. Needless to say, it took
awhile.

  As such, I wrote a pair of routines which I call ARCHLIB and 
RESTLIB which allow me to easily have copies of my LIBRARIES
in every ARCHIVE. Perhaps someone has already written similar
routines; If so, then I was unable to find them any where.

  The routines are pretty well documented internally, so I will
provide only a brief description here:

ARCHLIB : Makes a local copy of every library in PORT 0 in your
          HOME directory, and DETACHES and PURGES the library
          copy. Checks are made to make sure that there is 
          sufficient memory to make the copy, and warning
          messages are returned if there is not. Also, libraries
          which are "in use" will be DETACHED, but not PURGED.
          CHECKSUM # 55295d
          SIZE:         346

RESTLIB:  Is basically the inverse of ARCHLIB. It takes all the
          library variables stored in your HOME directory, stores
          them in PORT 0, and deletes the copy in the HOME
          directory. After all have been stored, the calculator
          is turned OFF. Libraries which were "in use" in
          ARCHLIB, (the library copy was not deleted), and
          are still "in use" in RESTLIB will not be stored
          in PORT 0, and the copy in the HOME directory will
          not be PURGEd. (This happens a lot with Bill Wickes
          JEKYLL and HYDE library).
          CHECKSUM # 34289d
          SIZE:       179.5

  There are still a few things which might be improved. Libraries
which do not automatically attach themselves to a directory need
to be attached by hand. It would be nice to remember the directory
to which every library was attached, and reattach them there, but
as all of my libraries are attached to the HOME directory, this
wasn't so important for me. I hope that these routines are useful
for other people, and comments and suggestions on improving them
would always be welcome.

==========================================================================
!   Curtis A. Meyer   ! Snail:            ! Email:                       !
!                     ! Physik Institut   ! cmeyer@vogon.physik.unizh.ch !
! Voice:+41-1-2572925 ! Schoenberggasse 9 ! cmeyer@physik.unizh.ch       !
! Fax:  +41-1-2612911 ! CH-8050 Zuerich   !                              !
==========================================================================

==========================CUT HERE==============================
%%HP: T(3)A(D)F(.);
DIR
ARCHLIB
@
@  Program:       ARCHLIB
@  Author:        Curtis A. Meyer
@  Creation Date: 01 March, 1991
@  References:    HP 48 Programmer's Reference Manual
@
@  Description:   Recall all the libraries stored in port
@                 0 and store them in "directory" variables,
@                 LIBxxxx so they will be archived. See the
@                 RECLIB routine for information on restoring
@                 the libraries.
@
@                 In order to try and minimize the ammount
@                 of memory used, this routine will DETACH
@                 and PURGE the libraries in PORT 0. Before
@                 each libray is handled, a check is made to
@                 see if there is sufficient free memory
@                 to contain a copy of the library. If not, then
@                 the offending library is left "untouched"
@                 and an error message is generated of the
@                 form:
@                   "LIBRARY xxxx ,INSUFFCIENT MEMORY."
@                 Otherwis a local variable in the HOME
@                 directory, LIBxxxx, will be created which
@                 contains a copy of the library. Then the
@                 library will be DETACHED. Next an attempt
@                 to PURGE the library will be made. If this
@                 fails, the error message:
@                   " LIBRARY xxxx ,IN USE."
@                 will be generated, and the library will not
@                 be PURGEd. It will however remain DETACHed,
@                 and the local copy will exist.
@
@                 After all libraries have be processed, a LIST
@                 will be created from all error messages. If there
@                 were no error messages, then NO error list
@                 will be returned.
@
@  Warnings/Bugs: You need sufficient free memory to contain 
@                 your largest library. I could not find a way to
@                 temporarily making a duplicate of each library.
@
\<<
@
@  Get a list of all libraries attached to port 0. Note that
@  PVARS returns the list in level 2, and the free memory in
@  level 1. Stack after operation is:
@  Lev2] { library list }
@  Lev1] length of list
@
HOME
0 PVARS
DROP
DUP
SIZE
@
@  Check to make sure that there are elements in the
@  list. If not, then do nothing.
@
DUP
IF 0 == 
THEN
@
@  There are no libraries, clean up and exit.
@
  2
  DROPN
@
ELSE
@
@  There are libraries to be recalled.
@
  \-> list n
  \<<
@
@  Put the error count on the stack.
@
    0
@
@  Loop over the n libraries:
@
    1 n FOR i
@
@  Get the library number of the i'th library. After the
@  operation, the stack is:
@     Lev4] possible error messages.
@     Lev3] Error Count
@     Lev2] 0:xxx
@     Lev1] 0:xxx
@
      list i GET
      DUP 
@
@  Check to make sure that there is enough memory to make
@  a copy of the library. After the test, the stack is just:
@     Lev3] possible error messages.
@     Lev2] Error Count
@     Lev1] 0:xxx
@
        RCL
        BYTES
        SWAP
        DROP
        IF MEM > THEN
@
@  There is insufficient memory for this library. 
@  Create an error message, increment the error
@  counter, and then push the message onto the stack.
@    Lev2] error message
@    Lev1] error count
@
          OBJ\->
          DROP
          "LIBRARY "
          SWAP +
          " ,INSUFFICIENT MEMORY."
          +
          SWAP
          1 +
@
        ELSE
@
@  There is sufficient memory to copy this variable.
@  Put it on the stack:
@     Lev5] Possible error messages.
@     Lev4] error count
@     Lev3] 0:xxx
@     Lev2] 0:xxx
@     Lev1] 0:xxx
@
          DUP
          DUP
@
@  Get the library number, xxx, and create a variable
@  name LIBxxx. After these operations, the stack is:
@     Lev5] Possible error messages.
@     Lev4] error count
@     Lev3] 0:xxx
@     Lev2] 'LIBxxx'
@     Lev1] 0:xxx
@
        OBJ\->
        DROP
        \->STR
        "LIB"
        SWAP +
        OBJ\->
        SWAP
@
@  Recall the library to the stack, and then store it in the
@  variable LIBxxx. After these operations, the stack is:
@     Lev3] Possible error messages.
@     Lev2] error count
@     Lev1] 0:xxx
@
        RCL
        SWAP
        STO
@
@  Now detach the library. At the end of this operation,
@  the stack is:
@     Lev3] Possible error messages.
@     Lev2] error count
@     Lev1] 0:xxx
@
        DUP
        DETACH
@
@  Now we want to PURGE the library. However, if the library is 
@  in use, then this will not be possible. As such we need to
@  trap the error on the PURGE command.
@
        IFERR
          PURGE
        THEN
@
@  Here the library was probably in use. As such, we want to add
@  a new warning message to the stack, and increment the count.
@
          OBJ\->
          DROP
          "LIBRARY"
          SWAP +
          " ,IN USE."
          +
          SWAP
          1 +
@
        END
    
@
      END
@
@  The stack is again "pristine", except for possible
@  error messages and their count. Get the next library.
@
    NEXT
@
  \>>
@
@  Create a list out of all the returned error messages. If there
@  are no messages, then return the stack as empty.
@
  DUP
  IF 0 == 
    THEN
      DROP
    ELSE
      \->LIST
  END
@
END
\>>

RESTLIB
@
@  Program:       RESTLIB
@  Author:        Curtis A. Meyer
@  Creation Date: 14 March, 1991
@  References:    HP 48 Programmer's Reference Manual.
@
@  Description:   This routine performs the inverse operation
@                 of ARCLIB. It recalls all library variables
@                 which have been stored in the HOME directory,
@                 and stores them in PORT 0. The calculator is
@                 then turned off so that a SYSTEM RESET can
@                 be performed when the calculator is turned
@                 back on.
@
@                 If a library is in USE, and a "backup" copy
@                 from ARCLIB exists, then the "backup" copy
@                 will not be stored in PORT 0, and the local
@                 copy will not be deleted. The one case where
@                 I know this happens is if one has Bill Wickes
@                 HYDE library (998) installed, and running.
@                 
@  Warnings/Bugs: Libraries which do not automatically ATTACH
@                 themselves to a directory will NOT be attached
@                 by this routine. The user will need to attach 
@                 them personally.
@
\<<
@
@  Get a list of all library variables. At the end of this
@  sequence, the stack will be:
@  Lev2] list of type-library variables.
@  Lev1] Length of the list.
@
HOME
16 TVARS
DUP
SIZE
@
@  Make sure that there are some elements in the list.
@
DUP
IF 0 == 
THEN
@
@  There are no libraries, clean up and exit.
@
  2
  DROPN
@
ELSE
@
@  There are libraries to be recalled.
@
  \-> list n
  \<<
@
@  Loop over the n libraries:
@
    1 n FOR i
@
@  Get the name of the i'th library. Then recall it to the stack,
@  PURGE to local copy, and store the library in PORT 0. If an error
@  occurs during the store, (say that the library is there, and is busy,
@  then the local copy is restored.
@
      list i GET
      DUP
      RCL
      SWAP
      PURGE
      IFERR
        0
        STO
      THEN
        DROP
        list i GET
        STO
      END
@
@  Get the next library:
@
    NEXT
@
  \>>
@
@  Turn off the calculator so when it is turned back on, a
@  system reset will be given.
@
  OFF
@
END
\>>
END