Operating Tools for the HP49G and HP49G+

Aims at making the life on the 49 more easy. Serves both, the normal user and the expert. It offers library-, menu-, programming- and compression-tools and allows to recall menus, standard or user key assignments, and to toggle fonts, flags and other items. If you learn using at least some OT49 commands, your calculator will become much more powerful. Some options should be assigned to keys, e.g. DType, 3tog, S?UK and perhaps some togglers from page 2. Particularly interesting is DL for creating and splitting libraries. It is the primary tool for customizing the HP49 HELP engine for self-made libraries (since ROM 19-6). Hence, your 49 ROM should not be older than 19-6. The library for the 49 is OT49, the one for the 49+ is OT49Plus (internally OT49+). Tested in ROM 19-6, 1.22 and 1.23.

Store the library in a port. Any warmstart (ON_hold F3) attaches OT49(+) and the built-in libraries 256 and 257. For using the full calculator power, we recommend to load the library extable (e.g., from the Emacs package). The old Display-Off command  is not anymore supported by ROM 1.23. This is the main reason for different libs.  has been replaced by the command INFO in OT49+. Also header size toggling has been removed in OT49+ because this doesn't make sense on the 49+. A user of  the 49 should update to version 1.2004 of OT49, a user of the 49+ to OT49+ to 4.2004.

What is NEW?

Version 4.2004 (only OT49+). S?UK displays nicely in the header also if the clock is on.

Version 3.2004 (only OT49+). Sys~ improved. Handles asm code now independently on flag -92.  

Version 2.2004 (only OT49+). BZ-compression not interruptable anymore (compressor revised).

Version 1.2004 (only OT49+).  ~HEAD  and   replaced by ~MINI,  INFO, resp. BZ compressor simplified.

Version 9.2003 (only OT49). Very hidden bug in DType fixed.

Version 8.2003. The flashpointer recaller in DType rewritten. Some other small improvements. OT49+ added for the HP49+.

Version 7.2003. XLIB 360 25 is a system flag toggler. Its former functionality is now a visible command in the library Hide.

Version 6.2003. html-document added, a revised version of OT49.txt. As in a web-site, putting the Cursor on a picture yields additional information. LMN slightly modified.

Version 5.2003. Toggler on page 2 and BZDIR improved.

Version 4.2003. Small bug in Flg~ fixed. Header update correct also if toggling flag -67.

Version 3.2003. In future one can hide files also with the filer (Filer1 or Filer2, version 3.2003). Therefore, the OT49 hiding tools are replaced by system parameter togglers. Who likes slighly more comfortable hiding tools may use the HIDE library 273. Purge moved to the last page. Hence, people who used this command in own programs must reprogram these.

Version 9.2002. BZ-toggler ~ decodes now compressed self-evaluating code, see below.

Version 8.2002. BZDir now compatible with the filers from the tool Filers. Existing compressed directories are not affected.

Version 7.2002. DL made still more user-friendly. DType shows also the Dispatch Type of an object. S?UK now displays both, Usr and Sys key numbering.

Version 2.2002. A new option $HELP is added to the dialog box in DL for creating a library. You may add HELPs for own library commands shown when browsing CAT.

Version 1.2002.  BZDir replaces the former SFD since ROM 19-6 introduced a new slightly more general command DISPXY. Already in earlier versions the BZ-toggler has become a powerful additional feature: Self-decompression and self-evalution can be done inside a small code object. The following unnamed rompointers are stable from now on, hence may trustfully be used as long as OT49 is present on your calculator (you get e.g. the first one on the stack with 360. 26. XLIB~, with XLIB~ from library 256):
XLIB 360 26 - a very small and fast BZ-decompressor. Warning:  no argument checking!
XLIB 360 27 - argument protected BZstring fi (lter. Errors if the argument is not a BZstring (string made with BZ-compressor).

Below, Alg, dir, lib, Lst, Prg, Str, zint, meta denote any algebraic object, directory, library, list, program, string, integer, or metaobject, resp. A metaobject is a collection of arbitrary stack-objects with a count in level 1 (a zint or real at the user level). All explanations below refer to RPN-mode only.

Page 1 - Menu and Library Tools - Menu look:  Menu page 2

CrM (Create Menu)           Stack:  Lst    MLst (a menu-list accepted by MENU or TMENU)
  Expand the menu-building facilities by creating a menu-list MLst from any argument list Lst. The output MLst sets a menu which always ends up with EXIT on key F6. This option returns to the previous menu. If Lst is empty then EXIT will be the only menu option. If Lst is already a standard argument for MENU or TMENU, nothing changes. The interesting case is that Lst contains a member, L say, which is itself a list of size > 2. In this case, the head of L serves as the menu-name of a program automatically made from L's tail. CrM allows a very economic writing of complex menus. In plain UsrRPL a name cannot be quoted inside a list. This is no problem anymore. In OT49, names and other objects inside lists can be quoted with a special quoter symbol, see below. 

Example. The standard argument for TMENU

creates a menu with the single entry Time displaying the running time. The list argument can shorter be written without any program delimiters as
Processing this with CrM sets unvisible program delimiters at the right places. And the displayed menu has option EXIT at the end.

LMN (List Menu Names)     Stack:  zint/real  list (or errors)
  Recalls essentially the list of menu names of a menu which can be set with the same argument number by TMENU. At the user level, one may set various existing menus but there is no way to recall a menu for easily building own application menus. To get the number of a built-in menu run RCLMENU (should be key-assigned) on the current menu which then may serve as an argument for LMN. Also the three ports are included into the scheme, numbered by 0,-1,-2. Here some examples: -2 LMN returns the list of files in Port 2, 1 LMN recalls the complete CST list, 2 LMN does VARS, 3 LMN returns the directory listing under MTH,  4 LMN recalls a list of vector-related commands, 11 LMN and 34 LMN the two menus containing list-related commands, 81 LMN a list of PLOT commands, 104 LMN the list of transfer commands, 110 LMN a list of port related commands, 111 LMN the list of all lib-titles, 360 LMN the list of OT49 commands, 2270 LMN a list of commands new in the HP49, 788 LMN a list of the CAS commands, etc. There is a similar command in Libman which even recalls the command list of all internal libraries such as library 2.

Note that the output list may contain unnamed rompointers (seen as XLIB xxx yy or ROMPTR uuu vv, depending on flag -85) at places where subdirectories occur in the corresponding menu. For instance, 3 LMN yields a list containing unnamed rompointers only, since all options in the MTH menu on 44.2 are directories. Press leftshift-hold NXT (previous menu) to look at the menu and to see what these rompointers mean. The previous menu is just a copy of the list obtained with LMN. In other words, pressing TMENU on the list would yield the same menu. If unnamed rompointers in the output list cannot directly be read, the previous menu shows what they mean. Hence, you may use them to build your own complex menus containing subdirectories. This gives the user who is not familiar with SysRPL unlimited freedom in building own application menus which cannot be made with traditional CST menus. Let us illustrate this in the following 

Example. We want to collect all commands related to lists which are scattered around in various menus in a single menu. This is realized by the following small program which should be attached to a key, e.g., leftshift-hold PRG. From now on you'll have all list related commands on a single key in a nice 3-page menu. We recommend to add a TakeOver to the program below to make the assignment work also in edit mode (see Keyman.htm for an explanation of TakeOver). This example shows clearly the power of LMN in manipulating menus and creating own ones, even with embedded directories.  

34 LMN 1 6 SUB 
11 LMN 
@ Recall the LIST-commands from the PRG-menu as a
@ sublist which includes the subdirectories ELEM and PROC. 
@ Recall the set of LIST-commands from the MTH-menu. 
@ Concatenate these two lists.
@ Set the resulting list as a single 3-page menu.

Hint (a). 1 LMN yields the actual CST menu list also if the reserved variable CST stores a program or name of it which evaluates to a valid menu list for CST (extended use of CST).

Hint (b). A small program which does 0 LMN, 1 LMN,... sequentially. Press CONT to continue with the next number: 

   -  (List difference)          Stack:  Lst2 Lst1  Lst
  Yields the relative complement Lst2 - Lst1 of arbitary lists, i.e. the list of all members of Lst2 not in Lst1. With -, other set operations are readily defined. For instance, OVER SWAP - - , applied to Lst2  Lst1  computesLst2-(Lst1-Lst2) which is just the intersection of Lst2 and Lst1. With intersection and complementation all other set-theoretical operations can readily be defined and programmed.
DoL (DoList)                       Stack:  Lst Obj   Lst*
  A very fast list processor and the only command which has a HELP option in CAT. Obj is often a program or a command but can actually be any object, evaluated for each member of Lst. The output is collected in a list Lst*. This one may be empty, e.g., if all members of Lst are displayed, or if Lst itself is empty. Important: if Obj is a list, it is evaluated as if it were a program. This saves bytes for quoting. 

Example: IP((log n)/(log 2))+1 is the number of binary digits of an integer n > 0. To compute these for n=1,...,16, put { 1 ... 16 } and LOG 2 LOG / IP 1 + on the stack and press DoL. Instead of the program, the list { LOG 2 LOG / IP 1 + } or 'IP((log n)/(log 2))+1' does the same but is slower. From the latter you get the above program or list by applying 3tog. 

Hint for experts: DoL can be used in any temporary environment created by own nulllams which may even occur in the arguments of DoL.. This is impossible with DOLIST or DOSUB. 

DL Toggles library splitting/creation. If Level 1 contains a real or a zint n and an external library with number n exist in a port, its source directory is regained and stored in 's<n>' (s for source) in which you automatically drive into. If no real or zint is on the stack, DL launches a dialog box to aid in library creation provided you are not in HOME but in the intended source directory not yet containing the reserved variable $ROMID. The dialog box is asking for the library name ($TITLE), library number ($ROMID), the list of visible names in the lib menu ($VISIBLE) and its hiddens ($HIDDEN) and creates these reserved variables in the source directory. The dialog also includes a field $HELP for adding HELP for some of your commands in the CAT listing and elsewhere.

Make the $VISIBLE entry as follows: Press leftshift + to edit {}. Then hit VAR and put into the list all names from the current directory you want to see lateron in the library. Similarly, fill in $HIDDEN - it will contain the unvisible files used by your library Also these variables must occur in the source directory, otherwise DL will error. Note that a list field entry may be the empty list. The field $HELP may be skipped. To get HELP on the CAT key for the commands Cmd1,...,Cmdk (names from the source dir), fill in $HELP with a list as follows: { {Cmd1 "Tex1"} ... {Cmdk "Textk"} }. "Text1" will be displayed if Cmd1 is selected in CAT, and so on. For instance, OT49 yields HELP for the command (DispOff, found at the very end of the CAT listing) and OT49+ has HELP on the command Dol. A HELP-text is scrolling if the text is too large for one screen.

Important remark: $HELP realizes the only feature of $EXTPRG which can be managed only from inside a library. All other features of $EXTPRG can easily and should be realized by the user not familiar with SysRPL by means of APPSman. As a matter of fact, the normal user need not precisely know what $EXTPRG does but yet use its full power. 

After pressing OK, DL creates additional $-variables: $CONFIG (to attach the library at warmstarts), $HELP, $$ and $EXTPRG (the latter only if $HELP wasn't skipped) at the end of your source directory. Of all these $-variables, $CONFIG, $HIDDEN, $VISIBLE, $ROMID, $TITLE and $HELP are modifiable for a second run. In particular, the text parts in $HELP can be improved as often as want. But only experienced SysRPL programmers may modify $$ which appends itself to the list in $HIDDEN.

Whenever $ROMID is present in the source directory, the dialog box is skipped. Useful for modifying the $-variables or for adding new ones, $MESSAGE say, in a second DL run. Just delete the library from the stack for a second run which will be fast fast since the dialog box is skipped. Important: The command order in the library is fixed by their order in $VISIBLE and $HIDDEN, not by any order in the source directory. Only files occurring in these two lists will belong to the library and only these files will reappear if the resulting library is split lateron.

Example. Assume we want HELP for the command A?D of Keyman. First split this library by doing 1200 DL. We are now in the directory s1200.D<->L with a source dir of Keyman Run DL again, still being in s1200. Next fill in the dialog box with the obvious as in the screen-shot. You may slightly alter the  entry in $TITLE for a better distinction of the versions. The HELP text for A?D should describe the command, hence fill in $HELP as follows, say: { { A?D "Short: Assign Long: Delete" } }. Press OK and store the new Keyman in Port 0, with the old Keyman still in port 1 or 2. The OS prefers the Keyman from the port with the smallest index. Now hit CAT and choose A?D - and you'll see the HELP option of this command. Clearly, the same can be done with any of your own libraries. 

InL (Input List). Displays a message from Level 1 and waits for input into a list (mostly global variables) which will be the output. InL is very useful for an elegant treatment of ORDER, Purge and other list-accepting commands. Aborting InL with CANCEL aborts silently, without a "Interrupted" message.

Examples. "ORDER" InL ORDER assigned to a key is a nice ordering tool. The message need not be a string; the program may simply be ' ORDER InL ORDER (use XU to create such a program). This reduces the above program from 28 to 18 bytes). Similarly, "Purge" InL Purge is a fast and convenient PURGE tool which purges from ports as well. Faster than the Filer is also the following renaming tool: ' RENAME InL OBJ DROP SWAP RENAME . These examples show that it is sometimes better first to choose the command and then the argument.  

Page 2 - Toggling system parameter
- Menu look:  Menu page 2
~ANG Toggle RAD/DEG as will be noticed in the Header.
~COOR Toggle the three builtin coordinate system. With Keyman, you can assign this and the related command ~ANG to a single key. Just assign If longhold do ~COOR else ~ANG with a TakeOver on top to the dispensable leftshift-hold , say.
~BASE Toggle HEX/DEC/OCT/BIN, noticed in the Header. A suitable key for assigning this toggler is the rightshift-hold BASE key. If you like BASE switch with the same key in edit mode, put a TakeOver on top (consult Keyman.htm).
~FONT Cycle through the three standard fonts, FONT8, FONT7, FONT6. Best observed if something is in the stack. 


(head toggler ~HEAD in OT49). Toggle Minifont with the current font, We recommend to assign rightshift-hold NXT (33.31, PASTE) by means of Keyman with  If double clicked then ~FONT else ~MINI which actually is the ~FONT functionality in OT49. Put a TakeOver on top  so that fonts or minifont can also be toggled in Edit mode.  
~LANG Toggle the 3 builtin languages with a message in the Header as in the last screen. In ROM versions following 19-6 not only error messages but also other messages and menus names will be language-sensitive.
Page 3 - Info- and Programming Tools - Menu look:  DType pressed on the root command
Dtype Displays type number, type name and Dispatch number of a Level 1 object (the latter is important only for SysRPL programmers). If Level 1 contains a rompointer or a flashpointer, its content is recalled. The content's type is displayed in this case and an asterix is appended to the type, to remind you that type information refers to the content. A main reason for using DType is that an object's stack appearance does not always provide reliable type information. A flashpointer is extracted only if its extension in the rom is well-defined at the very beginning. Otherwise "Undefined Result" will be displayed.

Example. The standard assignment of the root key (recalled with S?UK) shows up as the root symbol . Applying DType seemingly duplicates it. But the display says Function* as shown in the last screen-shot. Hence, we may infer that Level 2 which shows the standard assignment of root key , is a named rompointer. It contains a named program in Level 1. The latter has 2.5, the other 5.5 bytes. Just confirm this with INFO below. If flag -85 is set the two levels differ also in the stack display in our example, but not in all cases. That √ in level 1 is really a program can be verified by applying 3tog twice, flag -85 set. The name is then replaced by its content. Stack view of a level 1 object may depend also on flag -79 (textbook). 

S?UK Recall a key's actual functionality - either its standard assignment or user assignment whenever the key is assigned and USR is on. Choose the key after S?UK. The main use of S?UK for a beginner is that it displays the location of a pressed key; it informs on the key code rc.p (row, column, plane). For instance, it displays 42.31 if pressed on rightshift-hold CAT. Also the system keycode { #key #plane } is shown, { 18 9 } in our example. The system keycode is basic in advanced programming. Note that this command differs in several details from Keyman's command K&SA. 
3tog                 Stack:  Alg   Prg   meta   Lst   Prg  ...
Cycle through three representations of a program: its original, its metaobject and its list form. A test with some program on the stack will tell you more than lengthy explanation. The list form is convenient to modify a UsrRPL program with stripped program delimiters, the metaobject form to modify a SysRPL-program whenever MASD fails to recompile a decompiled program to its original. Applied to an algebraic object, 3tog toggles its list, program and metaobject equivalents. Try with '1+2=3' or any other algebraic object.
Flg~ Comfortable Flag-toggler for System and User flags. Needs a positive or negative real or zint < 129. Zints should be prefered as these need less memory. Toggles a flag and displays what has just been done in the Header. The 10 flags listed below directly affect the Header look. In these cases no extra information is displayed (watch the header). The same holds true for the corresponding user flags, hence you have 10 "tacidly" toggling user-flags to your disposal. Toggling flags -15 and -18 may or may not change the Header look, depending on other flags. Hence, these flags indicate their toggling. 

flag -11 :  toggles HEX and OCT (if flag -12 is clear) 
flag -12 :  toggles DEC and BIN (if flag -11 is clear) 
flag -16 :  toggles XYZ and RZ (if flag -15 is clear) 
flag -17 :  toggles DEG and RAD (if flag -18 is clear) 
flag -40 :  toggles the system clock 
flag -62 :  toggles USR mode, also on leftshift ALPHA 
flag -67 :  toggles digital/analog clock display 
flag -95 :  toggles ALG and RPN mode 
flag -103 : toggles Real/Complex mode, also on leftshift-hold TOOL 
flag -105 : toggles exact/appr mode, also on rightshift-hold ENTER 

Sys~ The only OT49-command assuming some familiarity with SysRPL. Toggles disassembling and reassembling of an input object. When the input is not a string,  Sys~ tries to disassemble and cares itself on flag -92. To read the disassembled source string, library extable should be present. Disassembled asm code will be included into CODE...ENDCODE delimiters. Applied again after having made some change in the source string, Sys~ tries to recompile the object. This may not successfully be ended at the present state of MASD. Recommendation: set flag -92 (SysRPL mode) and flag -71 (no addresses) as your default.
XU (to "Xtended" UsrRPL). Strip the user program delimiters of a UsrRPL program recursively, also inside a list. Local environement delimiters are preserved. In PRG-mode, XU prints the quoter (symbol 180) which, after a program is processed with XU, is replaced by the system quoter ' (symbol 39) which is visible in normal stack display as well. With XU one can quote commands like Purge as is seen from example below, impossible in plain UsrRPL. But the main advantage of XU in UsrRPL programming is that names and other objects can also be quoted inside a list while in UsrRPL evaluating a list means evaluating all its members. Thus, the command XU is very powerful and makes UsrRPL much stronger. It expands, in a sense, the built-in compiler. The resulting program is mostly much smaller and faster. But it cannot be edited and recompiled anymore with ENTER. Use 3tog or Sys~ instead. Only programs, lists and the name '' are affected by XU. To use XU efficiently, assign XU  with a TakeOver on top to 43.31 which is dispensable in RPN mode. This assignment is easily made with Keyman, see Keyman.htm.

Example. "Purge" InL Purge may be programmed as  Purge InL Purge . Processing this with XU results in the program  '  Purge InL Purge. This saves not only 7.5 bytes but makes execution faster

Page 4 - Compression tools and Miscellaneous - Menu look:  Menu page 4 of OT49
~ Toggles BZ-compressing and decompressing. ~ need not be searched in the library menu, it is executed also by pressing alpha-rightshift 1 (92.5) and ENTER on the symbol ~. The compression rate is displayed, hence you always know whether compression pays. Compression cannot be interrupted and ends always up with a powerful application menu for processing the obtained BZstring as shown by the screen below. Important: On the 49+, Objects smaller 20 bytes are not compressed because this never pays. Warning: Do not use other perhaps instable compressors (like TNT). BZ deflates large objects very efficiently and decompression is superfast. 
The BZ-toggler's menu
UBZi append the BZ-decompressor XLIB 360 26 (= ROMPTR 4B0 1A) to the BZ-string, turning it into a self-decompressing object.  For use on your own 49(+) as long as OT49(+) is present. 
UBZe append the content of XLIB 360 26 to the BZ-string,  for external use, e.g., if a compressed object is sent to hpcalc.org. This is readable by every 49(+) and independent on the presence of OT49(+).
+EVL append EVAL to a program. For instance, applied to   "BZ..." XLIB 360 26 , +EVL yields the self-decompressing and self-evaluating program
"BZ..." XLIB 360 26 EVAL
BZC make a code object from a BZstring. Its execution decompresses only,  independently on the presence of OT49(+), without evaluating the decompressed object.
BZCE is like [BZC], but also evals the decompressed object. The BZC and BZCE code objects are readable by any 49(+) without OT49(+). Such codes are identified and decoded by ~. Any other code objerct will be compressed as usual provided it is not too small (has at least 27 nibbles).
EXIT Exit this menu. Can be used, for instance, for toggling with the OT49 menu.
BZDir Compress the scanned directory with all its subdirectories (except HOME). Leaves a single file in the directory whose name coincides with the directory name. Its execution immediately restores the original files of this directory.
(was  )
Since a DispOff doesn't make sense anymore on the 49+, the command from earlier versions has been replaced by INFO. It displays size and CRC of an arbitrary object in level 1 in a box scanned on the object which remains in the stack. Similar to INFO from the interactive stack menu, but our INFO can also be used in programs.
ObFx If loading something from the HP48 or with XMODEM from hpcalc.org one sometimes gets a corrupted string: the received object was not fully "understood" by the HP49. Put it on the stack and run ObFx. This leaves the right object on the stack provided the object isn't corrupt itself.
Purge Purge everything very fast, including directories (except the internal Hidden directory). Input: Any global or port name or a list such. The fast purging of directories should be used with some care: No stack object should reference to objects from a directory to be purged. Best to have only a name or list of such on the stack when applying Purge and nothing should be suspended.
EXIT Leave the current menu and set the last one. EXIT appends itself to any temporary menu created with CrM, but may also be appended to any other menu. No input or output.

Remark for experts: Options of the application menu set by the BZ-toggler ~ can be used in programs with some well-known SysRPL commands. For instance,
CK1NOLASTWD   x~   5  GETPROC  EVAL  %0  InitMenu   ?DispStatus  ;
yields the BZCE-code of a level 1 object because BZCE has menu position 5.

Credits. Thanks to joint work with Peter Geelhoed the library extractor in DL could be made faster and more comprehensive. DoL uses an idea of Werner Huysegoms, S?UK a code of Jonathan Busby and a hint of Carsten Dominik. Embedding decompression and self-evaluation in asm code is due to Jurjen Bos. Arnaud Amiel and Jonathan Busby eliminated the DispOff and other dispensable code from Mika Heiskanen's BZ-compressor, to make it fit for the HP49G+. Thanks also to Joe Horn, Heiko Arnemann and Otto Praxl for beta-testing.

Wolfgang Rautenberg
raut@math.fu-berlin.de - http://www.math.fu-berlin.de/~raut/ - ftp://ftp.math.fu-berlin.de/pub/usr/raut/