[comp.sys.handhelds] HP-48SX Q&A&Useful tidbits

darrylo@hpnmdla.hp.com (Darryl Okahata) (04/15/91)

     With all the FAQ-type questions being asked here, I thought that
I'd post this long document that I'm working on.  I originally wrote it
for posting on CompuServe, but people here will also be interested in
it.

     I also sent an older copy to the maintainer of the real FAQ list,
but I haven't heard a peep.

     -- Darryl Okahata
	UUCP: {hplabs!, hpcea!, hpfcla!} hpnmd!darrylo
	Internet: darrylo%hpnmd@relay.hp.com

DISCLAIMER: this message is the author's personal opinion and does not
constitute the support, opinion or policy of Hewlett-Packard or of the
little green men that have been following him all day.
===============================================================================
-*- outline -*-

		 HP-48SX Questions, Answers, & Useful Tidbits


     This list contains information which has not necessarily been
verified, and is not guaranteed to be correct, or even reflecting
reality.  It was compiled from various postings in comp.sys.handhelds,
as well as other sources.  Also note that, while the maintainer is an
employee of Hewlett-Packard, this list is not officially sanctioned by
Hewlett-Packard (the maintainer is doing this on his own time, and has
absolutely no connections with the HP division that makes calculators).

Please send any comments or suggestions to:

	Darryl Okahata
	Internet: darrylo%hpnmd@relay.hp.com
	CompuServe: 75206,3074

Summary of questions:

  * I'm a novice, and I have some questions.  Where should I start?
  * How can I tell what ROM revision I have?
  * What bugs exist in the various versions of the HP-48SX?
  * What is \->ASC or ASC\->?
  * How can I get \->ASC and \->ASC?
  * Why does my HP-48SX occasionally "freeze" for a moment?
  * Why does (1/3)*3 equal 0.999999999999?
  * I want `pi' to be a numeric value, not a symbol.  What's happening?
  * If I add two temperatures like 34 deg.F and 11 deg.F, I get 504.67 deg.F. 
    Why don't I get 45 deg.F?
  * Why do I get corrupted binary files with kermit?
  * My RAM card was plugged into the calculator when I changed the RAM
    card battery, yet I lost all the information on the card.  What
    happened?
  * Why do I get an "Invalid card data" error when I merge a RAM card?
  * My HP-48SX seems to take longer to turn on and off.	 What's going on?
  * I can't account for some of the RAM in the HP-48SX (I can't tell where
    it's being used).  What's going on?
  * How do I get rid of the HYDE library?
  * How can I transfer programs/data from my HP-28S to my HP-48SX?
  * I could speed up my HP-28S.	 How can I speed up my HP-48SX?
  * Why does the HP-48SX display flicker slightly?
  * I've heard that other manufacturer's RAM cards will work with the
    HP-48SX.  Is this true?  Will it work?
  * What library ID numbers have already been used?
  * What do the funny symbols \->, \GS+, etc., mean?
  * What tricks are there for manipulating matrices?
  * How do I store fields of variable length string data in a compact,
    rapidly accessible manner that does not require the overhead of
    storing strings in lists?
  * What is "Vectored Enter", and how do I use it?
  * How can I tell, from within a program, if the battery is low?
  * I've heard the names "RPL", "Saturn", "STAR", "Voyager", etc..  What
    do they mean?
  * Appendix A: ASC\-> and \->ASC functions:
  * Appendix B: Using non-HP RAM cards in your HP-48SX:
  * Appendix C: Compact Data Storage:
  * Appendix D: Various useful functions

===============================================================================

* I'm a novice, and I have some questions.  Where should I start?

  Start by perusing the HP-48SX manuals.

  Also, look over the section "Answers to Common Questions", in Appendix
  A (Volume II) of the manual.


* How can I tell what ROM revision I have?

  Do the following:

  1. Turn the calculator on (press ON and then release).
  
  2. Press ON again, and while holding it down, hit the "D"
     key (the fourth white key in the top row) and then release
     the ON key.  You should get three vertical lines in the
     display, one down the middle.
  
  3. Hit the backspace key (it says DROP and CLR over it).
     You should get some meaningless hexadecimal in the first
     line of the display.  (Mine says 705D9:1B8D...).
  
  4. Press and hold down the EVAL key.	It should say:
  
	Version HP48-*
	Copyright HP 1989
  
     where the * is an uppercase letter (A, B, etc.) indicating
     the ROM version.
  
  5. Release the EVAL key.  Hold down ON and hit "C" (the third
     white key in the top row.	This is a general reset
     operation that returns the calculator to normal from the
     diagnostic stuff (which is where ON-D puts you).

  (The above was mostly taken from a posting by Mark Adler --
  madler@tybalt.caltech.edu)


* What bugs exist in the various versions of the HP-48SX?

   Version(s)	Bug
  ----------------------------------------------------------------------
      A		DEFINE rounds numbers in user-defined functions if STD
		is not the current display mode.

      A		KGET on a zero length file from another machine will
		cause the calculator memory to be cleared.

      A		NXEQ from the Graphics Environment with flag -3 set (SYM
		off in Modes) can overwrite the current equation with a
		number.

      A		Displaying the clock in 24-hour format causes the
		one-digits for minutes to be incorrect in the alarm
		catalog.

    A,B,C	INV returns an incorrect result if used on an 8x8 or
		larger matrix.	To get around this problem, divide the
		identity matrix with the matrix to invert.

   A,B,C,D	Entering a symbolic complex number in polar form like
		'(A,<B)' (where < is really the funny little angle
		symbol), gives an expression in A and B that is wrong
		(the A and B are interchanged so A is the angle and B is
		the magnitude).

   A,B,C,D	If the clock is displayed during an ARCHIVE via RS-232,
		there is a chance (not 100%) that calculator memory will
		be cleared, after the transfer.	 The workaround is to
		turn the clock display off before doing the transfer.

   A,B,C,D	TRNC and RND allow for an array in level 2 and a
		symbolic in level 1 of the stack. This allows you to put
		an array in a symbolic.	 Example:

				[ 2 3 ]
				'7/8'
				RND
		
		returns 'RND(UNKNOWN,7/8)'   

  (The above was mostly copied from postings by Mark Adler
  (madler@tybalt.caltech.edu) or Jurjen NE Bos (jurjen@cwi.nl).)


* What is \->ASC or ASC\->?

  These functions were written by William Wickes to facilitate
  transferring HP-48SX binary objects in an ASCII format (useful when
  transferring objects via electronic mail).  Some HP-48SX objects, like
  libraries, cannot normally be converted into ASCII, unlike program
  objects, and these functions make it possible to do so.

  The \->ASC function converts the object in level 1 into an ASCII
  string, which can then be uploaded to a computer for mailing.

  The ASC\-> function converts the string object in level 1 back into an
  object.  A checksum is used to insure that the decoding is correct.


* How can I get \->ASC and \->ASC?

  A copy of these programs are given in Appendix A, near the end of this
  file.


* Why does my HP-48SX occasionally "freeze" for a moment?

  The HP-48SX must occasionally do "garbage collection" to free up
  unused memory, and it is this garbage collection that is causing the
  momentary "freeze".  "Garbage collection" is where the HP-48SX scans
  through memory, looking for objects that are no longer used.

  Using less stack supposedly makes garbage collection go faster.


* Why does (1/3)*3 equal 0.999999999999?

  This is due to the way numbers are typically represented by computers
  and calculators.  There are some numbers, like `1/3' and `pi', that
  cannot be exactly represented internally.  As a result, any
  calculations that use these numbers are bound to be off.


* I want `pi' to be a numeric value, not a symbol.  What's happening?

  You are using "Symbolic Results Mode".  To turn this mode on or off,
  go to the MODES menu (press orange/left-shift MODES), and press the
  "SYM" softkey.


* If I add two temperatures like 34 deg.F and 11 deg.F, I get 504.67 deg.F. 
  Why don't I get 45 deg.F?

  If the units attached to the number consists only of a temperature and
  nothing else, operations are done using an absolute temperature scale
  (relative to absolute zero).  If the units consists of a temperature
  and something else, such as degrees/minute, the operation will not be
  done using an absolute temperature scale.

  It also does not make any physical sense to add two temperatures.  You
  can't add a cup of water at 20 degrees C to a cup of water at 30
  degrees C and end up with two cups of water at 50 degrees C.


* Why do I get corrupted binary files with kermit?

  Some versions of kermit distinguish between ASCII and binary files,
  and so you have to worry about the transfer modes at *BOTH* ends of
  the connection (the HP-48SX end and the computer end).  For example,
  when receiving ASCII files, Unix kermit must translate CR/LF pairs
  into LF.  If the HP-48SX is transmitting a binary file, but the Unix
  kermit is expecting ASCII, any CR/LF pairs in the binary file will get
  translated to LF, corrupting the binary file.	 Unfortunately, you
  cannot "uncorrupt" the corrupted binary file by simply reversing the
  transfer and expecting kermit to translate LF to CR/LF.  This is
  because the binary file may contain occurrences of LF that were not
  originally part of a CR/LF sequence.

  Kermit running on IBM PC clones do not have to translate any incoming
  CR/LF pairs, which is why you do not see this problem there.


* My RAM card was plugged into the calculator when I changed the RAM
  card battery, yet I lost all the information on the card.  What
  happened?

  You forgot to turn ON the calculator before changing the battery.  The
  HP-48SX only supplies power to the RAM card while the HP-48SX is
  turned on.  While the calculator is turned off, no power is supplied
  by the calculator, and all power comes from the RAM card battery.  If
  you then take out the battery from the RAM card while the calculator
  is turned OFF, the RAM card has no source of power, and you will lose
  all of the contents in the RAM card.


* Why do I get an "Invalid card data" error when I merge a RAM card?

  This message is usually seen when you plug a brand-new RAM card into
  an HP-48SX.  In this case, this message is normal and is harmless.  It
  just means that there was no (valid) data on the card.

  If you see this message under any other conditions, it could be one of
  the following:

     1. You took the battery out of the RAM card while the card was out
	of the calculator.

     2. You took the battery out of the RAM card while the card was in
	the calculator *BUT* the calculator was turned off.

     3. The RAM card battery is dead.

     4. There is a problem with either the calculator, the RAM card, or
	both.


* My HP-48SX seems to take longer to turn on and off.  What's going on?

  The usual causes for this are RAM/ROM cards and libraries.  When you
  turn the calculator on, it checks RAM (the more you have, the longer
  it takes), and checks to see if any libraries need initializing.

  Also, having a lot of alarms can supposedly also cause this.


* I can't account for some of the RAM in the HP-48SX (I can't tell where
  it's being used).  What's going on?

  It can be any one of a number of things:

    ---------------------------------------------------------------------------
    Enabling the use of LAST STACK, LAST ARG, LAST CMD, etc., uses up
    extra RAM, as the calculator has to keep track of the last stack,
    arguments, command, etc..  This is particularly important with LAST
    STACK if you have a large/complex stack, as the HP-48SX has to keep
    enough information around to recreate the stack after each
    operation.	You can clear out these variables by pressing ON-C (but
    also note that this will clear out the stack, the graphics PICT, etc.).
    ---------------------------------------------------------------------------
    From billw@hpcvra.CV.HP.COM Fri Mar	 1 17:00:00 1991
    From: billw@hpcvra.CV.HP.COM (William C Wickes)
    Date: Wed, 1 Aug 1990 19:51:37 GMT
    Subject: DOERR: An HP48SX memory eater
    Organization: Hewlett-Packard Co., Corvallis, OR, USA
    Newsgroups: comp.sys.handhelds
    
    Here's a candidate for "most obscure way to use up memory on the HP 48SX."
    When a program executes DOERR with a string argument, the string and hence
    the program too if the string is embedded in the program are referenced
    for the sake of the ERRM command.  Thus if you purge the program, the
    memory used by the program is not reclaimed until the ERRM reference is
    updated to a new string.  If the string is in a port, you will get
    the Object In Use error if you try to purge the library or backup object
    containing the string.
    
    A system halt prior to a PURGE will not help unless the object is in
    port 1 or port 2 (it will reclaim memory held by a successfully purged
    but still referenced object).  For port 0 objects, the only way to
    break the reference is to execute DOERR again with a new string.
    ---------------------------------------------------------------------------


* How do I get rid of the HYDE library?

  Getting rid of the HYDE library can be fun.  Here's how to do it:

  1. Go the HOME directory.

  2. Press left-shift (orange) LIBRARY.	 The calculator is now
     displaying a menu of libraries attached to the HOME directory.

  3. Press the menu key that says "STRA".  You are now accessing the
     HYDE library.

  4. Press the menu key that says "JEKY".  You have now disabled the
     HYDE library and restored the old (standard) set of messages.

  5. Make sure that a pointer to the library is not on the stack.  The
     easiest way to do this is to clear the stack using CLR.

  6. Detach the library using:

       :0:998 DETACH

  7. Purge the library using:

       :0:998 PURGE

     When you execute the PURGE, the screen will "jump"/"be messed up"
     for a brief moment.  Don't worry about it -- it doesn't hurt.


* How can I transfer programs/data from my HP-28S to my HP-48SX?

  You use a program called "INPRT", which is available from various
  archives, and is also included in the IBM-version of the HP-48SX
  serial cable kit and in the Program Development Library.

  INPRT sends a program to the I/R output of the HP-28S, and the HP-48SX
  receives it via its I/R input.


* I could speed up my HP-28S.  How can I speed up my HP-48SX?

  You can't.  Unlike the HP-28S, the clock speed in the HP-48SX is
  hardwired to 2 MHz.


* Why does the HP-48SX display flicker slightly?

  Display flicker is usually caused by fluorescent lights (the rapid
  pulsing of the fluorescent lights, which is normally unnoticeable,
  interacts with the rapid pulsing/scanning of the HP-48SX LCD display,
  which is also normally unnoticeable).	 It's normal and harmless.


* I've heard that other manufacturer's RAM cards will work with the
  HP-48SX.  Is this true?  Will it work?

  While some cards may work, there is a chance that you may severely
  damage your HP-48SX.

  For more information, see Appendix B, "Using non-HP RAM cards in your
  HP-48SX", near the end of this file.


* What library ID numbers have already been used?

	 766	-- HP EPSPRINT.LIB library
	 767	-- HP PCLPRINT.LIB library
	 768	-- HP Stopwatch library
	 777	-- "TenK" library (anyone know what this is?)
	 998	-- "HYDE" library
	1092	-- MLDL library (Jan Brittenson -- bson@erice.ai.mit.edu)
		   (In development -- not officially released)
	1644	-- SWING ("VMS" graphical directory browser)
	1791	-- TOOLs library
	1793	-- New IFERR library


* What do the funny symbols \->, \GS+, etc., mean?

  These are the ASCII representation of the special HP-48SX graphical
  characters.  See the section "Character Translations" in Chapter 33
  (Volume II) of the manual for a table of symbols <--> ASCII
  representations.


* What tricks are there for manipulating matrices?

  You can build up a matrix by rows using \GS+

  You can take a matrix apart by rows using \GS-


* How do I store fields of variable length string data in a compact,
  rapidly accessible manner that does not require the overhead of
  storing strings in lists?

  See Appendix C, "Compact Data Storage", near the end of this file.


* What is "Vectored Enter", and how do I use it?

  From billw@hpcvra.CV.HP.COM Fri Mar  1 17:00:00 1991
  From: billw@hpcvra.CV.HP.COM (William C Wickes)
  Date: Mon, 12 Mar 1990 21:21:55 GMT
  Subject: HP-48SX Vectored Enter
  Organization: Hewlett-Packard Co., Corvallis, OR, USA
  Newsgroups: comp.sys.handhelds
  
  The HP-48SX manuals do not document a very powerful feature that we call
  "Vectored ENTER," that allows you in effect to redefine or bypass the
  command line parser and to have a shot at the stack etc. after the command
  line has been executed.
  
  Keys that execute an automatic ENTER perform a two-step process:
  
  1.  The command line is parsed and evaluated.
  2.  The key definition is executed.
  
  When flags -62 and -63 are both set, the system extends this process as
  follows:
  
  1.  The current path is searched for a global variable named *aENTER
  (here "*a" is the Greek alpha character--character 140).  If present,
  the command line is entered as a string object and *aENTER is
  executed.  If absent, the command line is parsed and evaluated
  normally.
  
  2.  The key definition is executed.
  
  3.  The current path is searched for a global variable named *bENTER
  ("*b" is Greek beta--character 223).
  If present, then a string representing the key definition is put on the
  stack, and *bENTER is executed.  The string is the key definition
  object's name if it is a command, XLIB name, global or local name, or
  an empty string for other object types; its primary purpose is to implement
  things like the TRACE mode on other calcs, where you can print a running
  record of what you do.
  
  A simple example of the use of *aENTER is to create a more convenient
  binary calculator, where *aENTER slaps a "#" on the front of the command
  line so you don't have to bother when entering numbers.


* How can I tell, from within a program, if the battery is low?

  Preston Brown (prestonb@hpcvra.CV.HP.COM) posted the following:

  The following 48SX program reports the status of the ALERT annunciator.
  The ALERT annunciator is activated by alarms or low battery. 

  This program is provided free of charge "as is" and has no warranty.	No one
  is liable for any consequential damages.
  Preston

%%HP:T(3)A(D)F(.);
\<< 
RCLF 
8 STWS #FFh #0h + 
#10Bh
#6595Ah SYSEVAL
#8h AND #0h >
SWAP STOF
\>>


* I've heard the names "RPL", "Saturn", "STAR", "Voyager", etc..  What
  do they mean?

    ASAP
	This is a simple Saturn assembler, written in the perl language
	(and is therefore usable mostly on Unix machines).

    Chip8
	This is a machine-code program that was inspired by the chip8
	video game interpreter for the CDP1802 microprocessor several
	years back.  Chip8 allows you to write a simple graphics-based
	video game for the HP-48SX.  Among the games written are
	"clones" of breakout, pacman, and pong, to name a few (about
	half?).

    HYDE
	This is the "HYDE" library, whose only purpose is to change the
	error messages in the HP-48SX to make it "user unfriendly".

    ML
	Machine Language.  This is usually used in reference to HP-48SX
	assembly language programming.

    MLDL
	Machine Language Development Library.  This is a library, which
	is still under development, that allows you to debug machine
	language programs with only an HP-48SX.

    PDL
	"Program Development Link".  This is an MSDOS program, sold by
	Hewlett-Packard, that allows you to write and develop HP-48SX
	applications from your IBM PC clone.  Programs are written on
	your PC, transferred to the HP-48SX, and tested from your *PC*
	(and *not* the HP-48SX).

    RPL
	RPL is the name of the language used to program the HP-48SX and
	HP-28 series calculators.  While many people consider RPL to
	stand for "Reverse Polish Lisp", an HP Journal article described
	RPL as "ROM-based Procedural Language".	 To muddy the waters,
	it's also interesting to note that the HP-48SX development team
	considers RPL to mean "Reverse Polish Lisp", and not what was
	mentioned in the HP Journal.

    SASS
	SASS is a simple Saturn assembler, written in C/yacc (BSD Unix &
	Bison).	 It uses Alonzo Gariepy's mnemonics.

    Saturn
	"Saturn" is the internal code name for the processor used in the
	HP-48SX, HP-28 series, and the HP-75/71B calculators.

    STAR
	This is the "Saturn Macro Assembler" (how "STAR" comes from this,
	I don't know), an assembler that mostly uses Alonzo Gariepy's
	mnemonics.  It's written in C and runs on many different
	machines (PCs, Amigas, Unices, etc.).  STAR is available via
	anonymous ftp from ftp.ai.mit.edu in "/pub/star-1.04.4.tar.Z".
	It's also available from various bulletin boards (the HP forum
	in CompuServe also has a copy).	 The latest version is "1.04.4".

    SWING
	SWING is a library program that displays a graphical tree
	structure of the directory hierarchy in your HP-48SX, and allows
	you to move from directory to directory using the arrow keys (it
	is supposedly based upon an old PD VMS utility).

    Voyager
	Voyager is an "interactive disassembler" for IBM PC clones that
	disassembles HP-48SX RPL and machine code.  You download a copy
	of the RAM *and* ROM in your HP-48SX to your PC, and run
	Voyager.  Using Voyager, you can then view the disassembled or
	unthreaded code.  Unfortunately (or fortunately), Voyager uses
	the HP mnemonics, and not Alonzo Gariepy's mnemonics.  Voyager
	is available from the HP BBS (I think), via anonymous ftp from
	the HP BBS (hpcvbbs.cv.hp.com), and from various bulletin boards
	(the HP forum in CompuServe also has a copy).  The latest
	version is "1.07".



* Appendix A: ASC\-> and \->ASC functions:

From billw@hpcvra.CV.HP.COM Fri Mar  1 17:00:00 1991
From: billw@hpcvra.CV.HP.COM (William C Wickes)
Date: Fri, 17 Aug 1990 22:27:42 GMT
Subject: HP 48 Object Encoding
Organization: Hewlett-Packard Co., Corvallis, OR, USA


		      ASCII Encoding HP 48SX Objects

Sending an HP 48SX object via electronic mail can be difficult if the
object does not have an ASCII form, such as is the case for library
objects.  There are various encoding schemes available on different
computer systems, but these require that the sender and receiver have
similar computers, or at least compatible encode/decode schemes.  The
programs listed below perform the encoding and decoding on the HP 48SX itself,
which has the advantage of being completely independent of any computer.

The programs are nominally called \->ASC and ASC\->.  The former takes an
object from the stack and converts it to a string, in which each nibble of the
object and its checksum is converted to a character 0-9 or A-F.	 (The object
must be in RAM, otherwise a "ROM Object" error is returned.)  For sake of easy
inclusion in email letters, the string is broken up by linefeed characters
after every 64 characters.

ASC\-> is the inverse of \->ASC: it takes a string created by \->ASC and
converts it back into an object.  When you transmit the encoded strings,
be sure not to change the string; ASC\-> uses the checksum encoded in the
string to verify that the decoding is correct.	An "Invalid String" error
is returned if the result object does not match the original object
encoded by \->ASC.  When you upload a string to your computer, use HP 48
translate mode 3 so that the HP 48 will convert any CR/LF's back to LF's
when the string is later downloaded.

Two versions of ASC\-> are included here.  The first (P1) is in HP 48 user
language, using SYSEVALs to execute system objects.  P2 is a
string that the setup program uses P1 to decode into an executable
ASC\->--then P1 is discarded.  The second version is more
compact than the first, and also uneditable and therefore safer (but it can't
be transmitted in ASCII form, which helps to make the point of this exercise).

Here are the programs, contained in a directory:

(start)
%%HP: T(3)A(D)F(.);
DIR
P1		@ ASC\-> Version 1.
\<<
  IF DUP TYPE 2 \=/
  THEN "Not A String" DOERR
  END RCWS \-> ws
  \<< 16 STWS
    #0 NEWOB SWAP DUP SIZE
    IF DUP 4 <
    THEN DROP SWAP DROP "Invalid String" DOERR
    END 
    DUP 65 / IP - 4 - # 18CEAh SYSEVAL 
    "" OVER # 61C1Ch SYSEVAL
    SWAP # 6641F8000AF02DCCh
    # 130480679BF8CC0h # 518Ah SYSEVAL
    # 19610313418D7EA4h # 518Ah SYSEVAL
    # 7134147114103123h # 518Ah SYSEVAL
    # 5F6A971131607414h # 518Ah SYSEVAL
    # 12EA1717EA3F130Ch # 518Ah SYSEVAL
    # 280826B3012808F4h # 518Ah SYSEVAL
    # 6B7028080BEE9091h # 518Ah SYSEVAL
    # BE5DC1710610C512h # 518Ah SYSEVAL
    # 705D00003431A078h # 518Ah SYSEVAL
    # 3D8FA26058961431h # 518Ah SYSEVAL
    # 312B0514h # 518Ah SYSEVAL 
    # 18F23h SYSEVAL 
    DUP BYTES DROP 4 ROLL
    IF ==
    THEN SWAP DROP
    ELSE DROP "Invalid String" DOERR
    END ws STWS
  \>>
\>>

P2	@ ASC\->  Version 2.  To be converted by ASC\-> version 1.

"D9D20D29512BF81D0040D9D20E4A209000000007566074726636508813011920
140007FE30B9F060ED3071040CA1304EC3039916D9D2085230B9F06C2A201200
094E66716C696460235472796E676933A1B21300ED30FD5502C230C1C1632230
CCD20FA0008F14660CC8FB97608403104AE7D814313016913213014117414317
414706131179A6F5C031F3AE7171AE214F8082103B6280821909EEB0808207B6
215C0160171CD5EB870A13430000D50713416985062AF8D341508813044950B9
F06BBF06EFC36B9F0644230C2A201200094E66716C696460235472796E676933
A1B2130B21300373"


P3	@\->ASC.     To be converted by ASC\->.
"D9D20D2951881304495032230FD5502C230A752688130ADB467FE30322306AC3
0CB916E0E30CBD30F6E30C1C1632230CCD20DC0008F14660CC8FB97608403104
AE7D8143130169174147061741431311534AC6B4415141534946908D9B026155
4A6F53131F3AE731A014C161AE215F08082103A6280821939EEC08082170A621
4C161170CD56B870A18503430000D5071351796A9F8D2D02639916D9D2085230
C2A209100025F4D402F426A6563647933A1B2130A2116B213033C0"

SETUP	@Automatic setup program
\<< P2 P1 'ASC\->' STO
    P3 ASC\-> '\->ASC' STO
    { P1 P2 P3 SETUP } PURGE
\>>

END
(end)


Installation instructions:

1.  Edit the above text between (start) and (end) into a text file named
CONV (for example).  
Be sure that you leave the strings exactly as entered above,
with no extra spaces or other invisible characters at the beginnings or
ends of the lines.
2.  Set the HP 48SX into ASCII transfer mode.
3.  Using Kermit, download CONV text file to the 48, verify its checksum
(6C8Ah).
4.  Execute CONV to make it the current directory.
5.  Execute SETUP.
6.  The directory CONV now contains ASC\-> and \->ASC, ready to use.

To archive the decoded versions of ASC\-> and \->ASC back on your computer,
be sure to set the HP 48SX in binary transfer mode before uploading.

Disclaimers:

+ Use the programs at your own risk.  Any time you delve into the SYSEVAL
world, there are increased dangers.  Archive your 48 memory before 
experimenting with these programs!  Also, verify the checksums of objects
defined above to make sure they have been downloaded correctly, before
executing ASC\->.

+ I will not answer questions about how the programs work.  This is not
because of any great secrecy, but rather because it's hard to give
any answer that doesn't lead to more questions, and more, and more...

+ 48 hackers are welcome to mine any nuggets they can from the programs,
and from the fact that \->ASC is a convenient way to decompile an object.


* Appendix B: Using non-HP RAM cards in your HP-48SX:

  If you use RAM cards that are NOT designed for the HP-48SX, it is
  possible to severely damage your HP-48SX.  If you want to be safe, you
  should only use RAM cards designed for the HP-48SX.

  Here is an edited discussion from comp.sys.handhelds.

  From steveh@hpcvra.CV.HP.COM Fri Mar	1 17:00:00 1991
  From: steveh@hpcvra.CV.HP.COM (Steve Harper)
  Date: Thu, 10 May 1990 22:46:09 GMT
  Subject: RE: HP48SX Memory Card Pricing
  Organization: Hewlett-Packard Co., Corvallis, OR, USA

  There has been a substantial	amount	of  comment  regarding	the
  memory cards for the HP48SX and their prices.	 My purpose in this
  response is not to attempt to justify any particular	price,	but
  rather   to	present	 the  technical	 reasons  why  there  is  a
  substantial price difference between the memory cards	 and  other
  types of expansion memory for PC's, for example, with which users
  are probably more familiar.
  
  Some users have correctly pointed out	 that  the  memory  in	the
  cards	 is  static  RAM  rather  than dynamic RAM commonly used in
  PC's.	 Dynamic RAM uses one transistor and a capacitor  for  each
  bit of memory whereas static RAM requires either four transistors
  and two resistors, or six transistors.  The net result is that an
  equivalent amount of static RAM is much larger and therefore much
  more expensive than dynamic RAM.  The advantage  is  that  static
  RAM  doesn't	need  to continually be running and drawing current
  (refresh cycles) to retain the contents of memory.
  
  In addition, the static memory used in the cards is not just	any
  static  memory,  but	is  specially processed and/or selected for
  very low standby current.  This allows the backup battery in	the
  card	to  keep  memory  alive	 for  a very long time, rather than
  requiring the user to replace it every few months.   The  special
  processing  and/or  special  testing	to select low current parts
  adds to the already higher cost of the static RAM chips.
  
  The standard molded plastic DIP package used for most	 integrated
  circuits,  including	memory	chips,	is  relatively	inexpensive
  because of its simplicity and the huge  volumes.   Unfortunately,
  these	 packages  are	too  large  to	put  into  a  memory  card.
  Therefore, the card manufacturer mounts  the	individual  silicon
  memory  chips	 directly  on a special thin PC board together with
  the memory support  chips.   Because	multiple  chips	 are  being
  placed  in a single hybrid package in a special process which has
  lower volume, yields are lower and this again causes the cost	 to
  be  higher.  Indeed, the yield becomes exponentially worse as the
  number  of  chips  and  interconnections  increases  in  such	  a
  packaging process.
  
  In addition to the memory chips themselves, two  more	 integrated
  circuits  and	 several discrete components are required for power
  and logic control.  A bipolar technology chip senses the external
  voltage  and	switches  the  power to the chips from the internal
  keep-alive battery as needed.	 A CMOS gate  array  chip  protects
  the memory address and data lines from glitches/ESD when the card
  is not plugged in.  This chip also generates the proper  enabling
  signals  when	 there are multiple memory chips in the card, as is
  presently the case with the 128 Kbyte RAM card.  These chips must
  be  designed	for extremely low current, just as the memory chips
  are.
  
  In addition to the battery and  the  battery	holder,	 the  other
  mechanical  parts  are  important, too.  The molded plastic frame
  holds the PC board and provides  the	foundation  for	 the  metal
  overlays  and the shutter-and-springs assembly which protects the
  contacts from	 ESD  and  from	 contaminants.	 The  write-protect
  switch  is  also an important feature.  It is quite expensive for
  the manufacturer to make the tools necessary to fabricate each of
  these	 parts	as  well  as  the  tools  to  assemble and test the
  complete card.  While the volume of memory  cards  is	 relatively
  low  this  tooling cost represents a significant part of the cost
  of each card.
  
  Admittedly, there are other alternatives, such as those presently
  used	in  PC's,  to  provide	a  memory expansion capability.	 To
  provide that kind of expansion would require the calculator to be
  much	larger	than  it  is  and possibly more expensive.  This is
  clearly very undesirable.
  
  Other features that were felt to be essential were the ability to
  distribute  software applications and to share and archive/backup
  user-created programs and data.  Other expansion alternatives	 do
  not provide these important benefits.	 The IO capabilities of the
  calculator provide these features only to a limited degree.
  
  One other item bears repeating here: Memory cards for use in	the
  calculator  will  clearly indicate that they are for use with the
  HP48SX.   Other  memory  cards  exist	 which	 are   mechanically
  compatible  with the HP48S, but these cards cannot be relied upon
  to work electrically in the calculator.   The	 HP48SX	 cards	are
  designed  for	 a  lower  supply  voltage range.  Use of the other
  cards may cause memory loss, and under certain circumstances	may
  even damage your calculator electrically.
  
  From steveh@hpcvra.CV.HP.COM Fri Mar	1 17:00:00 1991
  From: steveh@hpcvra.CV.HP.COM (Steve Harper)
  Date: Fri, 11 May 1990 16:52:07 GMT
  Subject: Re: Memory Card: Give Us *True* Facts!
  Organization: Hewlett-Packard Co., Corvallis, OR, USA
  
  My previous statement that under certain circumstances the
  calculator may even be damaged electrically is not a ploy.
  If the calculator's internal power supply voltage happens to
  be near the low end of the range, say 4.1 V, and the voltage
  at which the card's voltage control chip shuts it down
  happens to be near the high end of its range, say 4.2 V (this
  can and does occasionally occur for the non-HP48SX cards),
  then the calculator will start to drive the memory address
  lines and the card will still have these clamped to ground
  (that's what it does to protect itself when there is not
  sufficient system voltage to run).  This unfortunate situation
  may simply trash your memory, or if the calculator tries
  to drive enough of the lines high at the same time, several
  hundred milliamps may flow...for awhile that is, until something
  gives up...  On the other hand, your calculator and a particular
  non-HP48SX card may work just fine if those voltages happen
  to be at the other end of their ranges.  These voltages are
  also slightly temperature sensitive.	It may work in the
  classroom or office and not at the beach, or vice versa.
  The voltage trip point of the HP48SX cards has been set
  lower (a different voltage control chip) so that this cannot
  occur, regardless of part and temperature variations.
  
  One other item was brought to my attention yesterday by
  Preston Brown that I should have included in my original
  posting here.	 While most of us recognize that comparing
  ram cards to a handful of dynamic ram chips to plug into
  your PC is apples and oranges, it may be more interesting
  to compare the HP48SX cards with cards for other products,
  like the Atari Portfolio, the Poquet, the NEC Ultralite,
  etc.	I believe you will find that the prices on the
  HP48SX cards are not at all out of line.
  
  Steve 
  "I claim all disclaimers..."
  
  the non-HP48SX cards
  
  From prestonb@hpcvra.CV.HP.COM Fri Mar  1 17:00:00 1991
  From: prestonb@hpcvra.CV.HP.COM (Preston Brown)
  Date: Thu, 17 May 1990 17:26:53 GMT
  Subject: Re: Memory Card: Give Us *True* Facts!
  Organization: Hewlett-Packard Co., Corvallis, OR, USA
  
  When the RAM cards detect that voltage is to low to operate they 
  clamp the address lines to ground.  This clamping is done by turning 
  on the output drivers of a custom chip included on the card.	The 
  clamping current is speced at 2mA min at the Vol output level.  Since 
  the 48 can be trying to drive the line all the way high even more 
  current is typical.  10mA per fight is not uncommon with totals of 
  several hundred mAs.
  
  The VDD power supply is regulated at 4.1 - 4.9 with typical 
  parts at the low end (4.3).  The power to the cards is switched
  thru a transistor, creating up to a 0.1V drop.  Standard Epson
  cards have a significant chance of seeing this voltage as 
  to low and shutting down.  We have seen cards do this in the lab.
  When it occurs the calculator locks up with VDD pulled down
  to about 2.5V and 250mA being drawn from the batteries.  This
  current drain greatly exceeds the ratings for the power supply
  and can damage your calc.  The least that will happen is a loss
  of memory.
  
  Now, why didn't we regulate VDD higher?
  The 48 has two power supplies VDD at 4.3 and VH at 8.5.  VH
  cannot be regulated higher without exceeding the spec for
  our CMOS IC process.	VH is used as the + voltage for the I/O.
  In order to meet a +3V output level VH must be more then 3.6V
  above VDD.  (VDD is used as I/O ground). Our power supply
  system increase the battery life and reduces the cost greatly
  for the wired I/O.
  
  Preston


* Appendix C: Compact Data Storage:

  From Jim Donnelly (jimd@cv.hp.com):

	A simple length-encoding technique can be put to use for a
	free-format, very compact multi-field data storage system.
	Two tiny programs, SUBNUM and STRCON are here to help the
	process, and are listed near the end of this note.  At the
	end of the note is a directory that may be downloaded into
	the HP 48 that contains the examples.

	The principle is to store starting indices in the beginning
	of a string that point to fields stored subsequently in the
	string.	 The indices are stored in field order, with an
	additional index at the end to accommodate the last field.
	There are several small points worth mentioning:

	1) Fields may be 0-length using this technique.
	2) The execution time is uniform across all fields.
	3) This technique saves about 4 bytes per field after
	   the first field, because the string prolog and length
	   are omitted for fields 2 -> n.


	EXAMPLE:
	--------

			 Indices  |	     Fields
	  Character		  |	1 11111111 12222222222
	  Position :   1  2  3	4 |567890 12345678 90123456789
		      +--+--+--+--+------+--------+-----------+
	  String :    | 5|11|19|30|Field1| Field2 |  Field 3  |
		      +--+--+--+--+------+--------+-----------+

	This is a string that contains 3 fields, and therefore 4
	index entries.	The first field begins at character 5, the
	second field begins at character 11, and the third field
	begins at character 19. To keep the pattern consistent,
	notice that the index for field 4 is 30, which is one more
	than the length of the 29 character data string.

	To extract the second field, place the string on the stack,
	use SUBNUM on character 2 to extract the starting position,
	use SUBNUM on character 3 to extract the (ending position +1),
	subtract 1 from the (ending position+1), then do a SUB to
	get the field data.  NOTE: The index for field 1 is stored
	as character code 5, NOT "5"!  To place the field index for
	field 1 in the string, you would execute "data" 1 5 CHR REPL.


	PROGRAM:
	--------

	The following program accepts an encoded data string in
	level 2 and a field number in level 1:

	DECODE	 "data"	 field#	 -->  "field"

	<<  --> f
	  <<
	    DUP f SUBNUM		; "data" start -->
	    OVER f 1 + SUBNUM		; "data" start end+1 -->
	    1 -				; "data" start end -->
	    SUB				; "field" -->
	  >>
	>>


	DATA ENCODING
	-------------

	The following program expects a series of 'n' strings on
	the stack and encodes them into a data string suitable
	for reading by the first example above.

	The programs SUBNUM and STRCON are used to assemble the
	indices.

	ENCODE	    field n  ...  field 1   n	-->  "data"

	<< DUP 2 + DUP 1 - STRCON --> n	 data
	  <<
	    1 n
	    FOR i
	      data i SUBNUM OVER SIZE	; ... field index fieldsize
	      + data SWAP		; ... field "data" index'
	      i 1 + i + SWAP CHR REPL	; ... field "data"'
	      SWAP + 'data' STO		; ...
	    NEXT
	    data			; "data"
	  >>
	>>

	In this example, four strings are encoded:

	Input:	5: "String"
		4: "Str"
		3: "STR"
		2: "STRING"
		1:	   4

	Output: "xxxxxSTRINGSTRStrString"      (23 character string)
	(The first five characters have codes 6, 12, 15, 18, and 24)



	VARIATION:
	----------

	The technique above has a practical limit of storing
	up to 254 characters of data in a string.  To overcome
	this, just allocate two bytes for each field position.
	The code to extract the starting index for becomes a
	little more busy.  In this case, the index is stored as
	two characters in hex.

		      Indices  |	  Fields
       Character	       | 11111 11111222 22222223333
       Position :   12 34 56 78|901234 56789012 34567890123
		   +--+--+--+--+------+--------+-----------+
       String :	   |09|0F|17|21|Field1| Field2 |  Field 3  |
		   +--+--+--+--+------+--------+-----------+

	   <<  --> f
	     <<
		DUP f 2 * 1 -		; "data" "data" indx1 -->
		SUBNUM 16 *		; "data" 16*start_left_byte  -->
		OVER f 2 * SUBNUM +	; "data" start
		OVER f 2 * 1 + SUBNUM	; "data" start end_left_byte -->
		16 * 3PICK f 1 + 2 *
		SUBNUM + 1 -		; "data" start end -->
		SUB			; "field"  -->
	     >>
	   >>



	TWO VERY TINY HELPFUL PROGRAMS
	------------------------------

	SUBNUM		"string"  position  -->	 code

	<< DUP SUB NUM >>



	STRCON		code  count  -->  "repeated string"

	<< -->	code count
	  << "" code CHR 'code' STO
	     1 count START code + NEXT
	  >>
	>>


	A DIRECTORY YOU CAN DOWNLOAD
	----------------------------

	This is a directory object.  Cut after the === to the end of
	the file and download to your HP 48 using the ASCII transfer.

========================================================================
%%HP: T(3)A(D)F(.);
DIR
  DECODE
    \<< \-> f
      \<< DUP f
SUBNUM OVER f 1 +
SUBNUM 1 - SUB
      \>>
    \>>
  ENCODE
    \<< DUP 2 + DUP 1
- STRCON \-> n data
      \<< 1 n
	FOR i data
i SUBNUM OVER SIZE
+ data SWAP i 1 +
SWAP CHR REPL SWAP
+ 'data' STO
	NEXT data
      \>>
    \>>
  STRCON
    \<< \-> code count
      \<< "" code CHR
'code' STO 1 count
	START code
+
	NEXT
      \>>
    \>>
  SUBNUM
    \<< DUP SUB NUM
    \>>
END


* Appendix D: Various useful functions

     (Shamelessly lifted from the HP-41C manual:)

     The LASTX function is useful in calculations where a number occurs
     more than once.  By recovering a number using LASTX, you do not
     have to key that number into the calculator again.

     For example, calculate:

		96.704 + 52.394706
	       --------------------
		     52.394706

	Keystrokes:			Stack:
       ------------------	       --------------------
	96.704 ENTER			96.704

	52.304706 +			149.098706

	LASTX				149.098706
					52.304706

	/				2.84568265351

@
@ This is a version of LASTX for the HP-48SX
@
%%HP: T(3)A(D)F(.);
\<< DEPTH \-> n
  \<< LASTARG DEPTH n
- DUP \-> s
    \<< ROLLD s 1 -
DROPN
    \>>
  \>>
\>>