Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.kodak.com!news-nysernet-16.sprintlink.net!news-east1.sprintlink.net!news-peer1.sprintlink.net!news-in-east1.sprintlink.net!news.sprintlink.net!news1.bellglobal.com!torn!cyclone.bc.net!news.UVic.CA!aschoorl
From: [email protected] (Andre Schoorl)
Newsgroups: comp.sys.hp48,comp.sources.hp48,comp.answers,news.answers
Subject: comp.sys.hp48 FAQ : 3 of 4 - Appendices
Followup-To: comp.sys.hp48
Date: 16 May 1999 22:00:03 GMT
Organization: University of Victoria, Victoria, BC, Canada
Lines: 2451
Approved: [email protected]
Expires: 13 June 1999 22:00:03 GMT
Message-ID: <[email protected]>
Reply-To: [email protected]
NNTP-Posting-Host: cognac.uvic.ca
X-Trace: uvaix7e1.comp.UVic.CA 926888485 192296 142.104.113.129 (16 May 1999 21:01:25 GMT)
X-Complaints-To: [email protected]
NNTP-Posting-Date: 16 May 1999 21:01:25 GMT
Summary: Answers to Frequently Asked Questions about HP48 calculators
Keywords: FAQ, HP48
X-Url: http://www.engr.uvic.ca/~aschoorl/faq/
User-Agent: slrn/0.9.5.4 (UNIX)
Xref: senator-bedfellow.mit.edu comp.sys.hp48:90217 comp.sources.hp48:727 comp.answers:36187 news.answers:158059

Archive-name: hp/hp48-faq/part3
Last-modified: 5/16/1999
Version: 4.59
Posting-Frequency: Every 14 days or so

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

post72
 9.1.  ASC Functions

 Note: Although this document mentions SX only, ASC\-> and \->ASC work
 on both the SX and GX.

 From: Bill Wickes

 ASCII Encoding HP48 SX Objects

 Sending an HP48 SX 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 HP48 SX
 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 e-mail 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 HP48 translate mode 3 so that the HP48 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 HP48
 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 (if you have problems
 with this and you are using the HTML version of the FAQ, you may wish
 to try the plain text version or download a binary copy of the
 program):


 %%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


 Installation instructions:

 1. Save the above text 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 HP48 SX 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 HP48 SX in binary transfer mode before
 uploading.

 Disclaimers:

 o  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\->.

 o  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...

 o  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.


 9.2.  OBJFIX

 When a binary object received by Kermit on the HP-48 is left as a
 string beginning with HPHP48, OBJFIX will extract the HP-48 object if
 the only problem is that extra bytes got appended to the end.

 OBJFIX takes a variable name in stack level 1 and modifies the
 contents of the variable if no other problems are detected.

 Note: This is like FIXIT by Horn and Heiskanen on Goodies Disk 8, but
 this one is by HP and so I suppose it's more reliable.  Although it
 fails the test cases included with FIXIT, that may be because they
 were artificially contrived cases.  Try both on real-world downloads
 that need fixing.  Which do you like better?

 OBJFIX.ASC


      %%HP: T(3)A(D)F(.);
      "D9D202BA81D9F81B2040D9D20F2A26DA91629C8145126489162C23072C80CCD2
      0BD0008FB9760147108134164142C2818F24D534501008B2F41643150D73B840
      58405438314A161966D2BF6BF6A6F5BE16314213114334CF8208A6F58F235A04
      55136D7D4EA494D231A1CA101110131CA130DBE284F8FC0760D41198F29960D4
      130142119EA1408F5E0108D341503223072D70B2130B21301460"


 9.3.  FIXIT

 From: Joe Horn and Mika Heiskanen


    PURPOSE:
       Converts a badly uploaded string into the original object.

    THEORY:
       A lot of folks upload HP48 objects poorly, such that when you
       download them, you just get strings full of garbage that look
       something like this:


         "HPHP48-E#c&r$a%p@!*!..."     [looks familiar, eh?]


    That's because they uploaded it using XMODEM, or managed to screw
    it up some other way.  The following FIXIT program takes such a
    string and extracts the actual HP48 object that they originally
    intended to upload (if at all possible).

    Such object extraction can be done by hand, but it's too dangerous.
    FIXIT minimizes the danger of Memory Clear.  It checks whether the
    extracted object is a valid one, and if not, drops it from the
    stack before the HP48 attempts to display it.  All of the many bad
    downloads I've archived over the years are fixed by FIXIT, whereas
    about half of them cause a Memory Clear when extracted manually.
    No guarantees, however.  Use at your own risk.

    The actual extraction is done by a "Code object" written by Mika
    Heiskanen.  The User RPL "shell" around this code object is what
    minimizes the danger of Memory Clear; it was written by Joe Horn.

    INSTRUCTIONS:
       BACKUP YOUR MEMORY, just in case the string contains a logic
       bomb.

       Place the bad download on the stack (see "HPHP48-...") and run
       FIXIT.

       Possible results:

    o  No error: the object was extracted successfully and is on level
       1.

    o  "Bad Argument Type" error: you didn't have a string on level 1.

    o  "Bad Argument Value" error: the string wasn't of the proper
       form; it must be an "HPHP48-..." downloaded string.

    o  "Invalid Definition" error: the object was mangled in
       transmission so badly that its end was lost; the object cannot
       be extracted.

    o  "Undefined Result" error: there is no HP48 object in the string.

    o  "Recover Memory? YES/NO": the string contained a bomb, and FIXIT
       detonated it.  Press YES to sift through the shrapnel and rubble
       in a feeble attempt to resurrect the dead.  Press NO to bury
       them.

    EXAMPLES:
       To do the following examples, download the FIXIT directory to
       your HP48 and get into it.

    o  Press HI.  See "HPHP48-E...", a badly uploaded download.  Before
       pressing FIXIT to fix it, try doing what we all used to do:
       press EDIT to see if we can recognize anything (usually a futile
       attempt).  We see:

       "HPHP48-E...  << Melancholy Baby >>"

       But looks can be deceiving; press ON to exit the editor, and
       then press FIXIT to extract the intended upload:

       << Happy Camper >>

    o  Press WTAV; see another garbage download.  But EDIT refuses; the
       string contains null characters.  Press FIXIT; see successfully
       extracted directory.

    o  Press BAD1.  Notice that it looks exactly like WTAV.  (Press
       WTAV, compare, then DROP).  But its ending is all messed up;
       manually extracting WTAV from BAD1 can cause Memory Clear.
       Press FIXIT and see "Error: Invalid Definition" indicating that
       the object inside BAD1 is so mangled that its end cannot be
       located.

    o  Press BAD2.  Looks like WTAV again.  But its body is messed up;
       manually extracting it would create an External object that
       could cause Memory Clear if evaluated.  Press FIXIT and see
       "Error: Undefined Result" indicating that there is nothing
       recognizable inside BAD2.

 FIXIT.ASC


      %%HP: T(3)A(D)F(.);
      "69A20FF7CE20000000402414442340C2A203B000840584054383D25403A20FF7
      2500000000403535947440D9D20E16329C2A2DBBF13013216DF1406A1C42328D
      BF193632B213034000407545146540D9D20E163292CF1EFFB1DBBF1EBFB150FA
      193632B2130003030303034C000402414441340C2A203B000840584054383D25
      469A20FF72500000000403535947440D9D20E16329C2A2DBBF13013216DF1406
      A1C42328DBF193632B213034000407545146540D9D20E163292CF1EFFB1DBBF1
      EBFB150FA193632B2131313131313134C000407545146540C2A203B000840584
      054383D25469A20FF72500000000403535947440D9D20E16329C2A2DBBF13013
      216DF1406A1C42328DBF193632B213034000407545146540D9D20E163292CF1E
      FFB1DBBF1EBFB150FA193632B2130003030303034C00020849420C2A20570008
      40584054383D254D9D20E163284E2050841607079784E20603416D6075627936
      32B2130A0BA02D456C616E63686F6C697022416269702BB28000506494859445
      50D9D20E16323CE2278BF168BC1ED2A2167E1AFE22D9D203CE2278BF19C2A274
      3A2C58C1C2A2031000840584054383D2167E1AFE22D9D2078BF18B9C1DBBF1AA
      F028DBF1CCD201200014713717917F137145142164808C5BF22D9D2033920200
      0000000005150933A1B21305DF22B21305BF22D9D20339202000000000004150
      933A1B21305DF223CE2278BF168BC1D8DC1167E1AFE22D9D203FBF1339202000
      000000002770933A1B21305DF223CE2278BF19D1A1DBBF18DBF1E0CF1D5CE1AF
      E22D9D208DBF1339202000000000000030933A1B21305DF22CB2A193632B2130
      B21303D4F"


 9.4.  LASTX

 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.  Note however that LASTX
 uses the built in last argument feature, so if you use LASTX you will
 lose the contents of your LASTARG.

 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 HP48
      @
      %%HP: T(3)A(D)F(.);
      \<< DEPTH \-> n
        \<< LASTARG DEPTH n
      - DUP \-> s
          \<< ROLLD s 1 -
      DROPN
          \>>
        \>>
      \>>


 9.5.  Compact Data Storage

 From: Jim Donnelly

 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 HP48 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:


 o  Fields may be 0-length using this technique.

 o  The execution time is uniform across all fields.

 o  This technique saves about 4 bytes per field after the first field,
    because the string prologue 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 char. data 5, NOT the
    string "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 + 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
           >>
         >>


    Alternative Solution to the Problem:
       From: Matjaz Vencelj <[email protected]>

       Jim allocates two bytes for each index entry (to handle longer
       strings), but on the other side obviously only uses values
       00...FF for index dublets, which just doesn't make sense.  He's
       at a 16*16 = 255 chars limit again!

       I have put together a working set of commands which support up
       to 65K strings, using two-byte indexing.

       The encoder (Encode) is User-RPL program which calls the binary
       N2C which converts the level 1 real into a 2 character string:


         @*** Encode ***
         %%HP: T(3)A(R)F(.);
         \<<
           IF DUP TYPE 0 = THEN 514 DOERR END
           \-> N
             \<<
             N 1 + 2 * #18CEAh SYSEVAL #45676h SYSEVAL
             1 N FOR I I 2 * 1 - OVER SIZE 1 + N2C REPL SWAP + NEXT
             N 2 * 1 + OVER SIZE 1 + N2C REPL
             \>>
         \>>


         @*** N2C, cksum=#8919h ***
         %%HP: T(3)A(R)F(.);
         "D9D202BA812BF819FF30D9D20AEC8111920001007FE3057A50C57463223057A5
         0EE250B2130B21307206"


    ASCII download them with translate code 3, then call program
    'Encode' with data strings in levels 2..n+1 and a real n in level 1
    indicating the number of strings.

    The string decoder (Decode), which is usually speed-critical, is
    the following \->ASC encoded binary:


         @*** Decode, cksum=#38E1h ***
         %%HP: T(3)A(R)F(.);
         "D9D20D8A81D9F811192013000D9D20AEC8113D26CA130F6E30CA130E0E305080
         311920001002CE30CAF0650803CBD30CAF06FED30F6E30CA130E0E3050803119
         20001002CE30CAF0650803CBD30E0E3033750B2130B21309534"


    It takes a `database' string on level 2 and a real (record
    position) on level 1, then comes back with the appropriate
    substring (record).


 9.6.  HP82240B Printer Codes

 From: Jarno Peschier


    Size of physical row
       One printed row is either 24 normal characters, 12 expanded
       characters or 168 pixels wide.  This means that one normal
       character has a width of 7 pixels. Any printed data "falling off
       the row" will be truncated and ignored by the printer.


    Reset


         ESC 255d


    This resets the printer to the following state: Roman8 character
    set (watch out: the power-up character set is ECMA94), both
    expanded and underline printing off, buffer cleared.


    Self test


         ESC 254d


    This causes the printer to print a selftest pattern.  This mainly
    consists of a printout of the Roman8 character set.


    Expanded printing


         ESC 253d


    This turns expanded printing on.  This means that from this code on
    all characters that are printed will be printed at twice the normal
    character width because each column of pixels is printed twice.
    Has no effect if expanded printing is already on.


         ESC 252d


    This turns expanded printing off.  This means that from this code
    on all characters that are printed at normal character width again.
    Has no effect if expanded printing is already off.


    Underlined printing


         ESC 251d


    This turns underlined printing on.  This means that from this code
    on all characters that are printed will be underlined because the
    bottom-most pixel in each columns of pixels is now always on. Has
    no effect if underlined printing is already on.


         ESC 250d


    This turns underlined printing off.  This means that from this code
    on all characters that are printed will not be underlined anymore.
    The bottom-most pixel in each columns of pixels is printed as it is
    defined for the printed character.  Has no effect if underlined
    printing is already off.


    Character sets


         ESC 249d


    This switches the printer to use the ECMA94 character set.  This
    set is 100% identical to the character set used in HP48 calcula-
    tors.  This is the power up default of the printer.  Has no effect
    if ECMA94 is the current character set already.


         ESC 248d


    This switches the printer to use the Roman8 character set.  This
    set is different than the character set used in HP48 calculators in
    the 128 last characters.  As far as I know this set is used by
    older printers like the HP82240A and by HP28 calculators (hence the
    need for the OLDPRT command in HP48 calculators if you are printing
    to a HP82240A).  This character set is turned on if you reset the
    printer with the reset code.  Has no effect if Roman8 is the cur-
    rent character set already.


    Graphics


         ESC n data (with n between 1 and 247)


    This causes the printer to print graphics specified by the speci-
    fied data (one byte per pixel column).  The value n specifies the
    number of bytes of data that follow the printer code that will be
    interpreted as graphics data.  Any data after pixel column 168 will
    be truncated and ignored.


 10.  Appendix B: GX Specific Information

 10.1.  What's new in the HP48 G/GX?

 From: Joe Horn


    AUTOMATIC LIST PROCESSING
       Almost all commands that did not accept list(s) as their
       arguments can do so now.  Here are just a few examples:


         { 1 2 3 } SF sets flags 1, 2, and 3
         { 1 2 3 } SQ  -->  { 1 4 9 }
         { 2 4 } 10 /  -->  { .2 .4 }
         10 { 2 4 } /  -->  { 5 2.5 }
         { 10 12 } { 2 4 } /  -->  { 5 3 }
         { .1 .2 .5 } ->Q  -->  { '1/10' '1/5' '1/2' }
         { freq freq ...} { dur dur ... } BEEP can play a song with no
           audible hiccup between tones.


    Since + has always been used to concatenate lists, a new ADD func-
    tion exists to add the elements of two lists, like this:


         { 1 2 3 } { 4 5 6 } ADD returns { 5 7 9 }, whereas
         { 1 2 3 } { 4 5 6 }  +  returns { 1 2 3 4 5 6 } as it did
           before.


    The only commands which do not have automatic list processing are:

    o  those which never get a Bad Argument Type error (like DUP),

    o  meta-object commands (like ROLL),

    o  program branch structures (like FOR), and

    o  commands that specifically work on lists (like GET).

       Sometimes the results are non-obvious, for example:


         5  { A B C }  STO           -->  A=5, B=5, C=5
         { 5 6 7 }  'A'  STO         -->  A={ 5 6 7 }  (same as on SX)
         { 5 6 7 }  { A B C }  STO   -->  A=5, B=6, C=7


    List processing is only recursive for ->Q and ->Qpi.

    PORTS AND MEMORY
       The HP48 G, like the 48 S, only has 32K RAM.  The GX, unlike the
       SX, has 128K RAM built-in.  Card slot 1 can contain another 128K
       (maximum), but card slot 2 can contain up to 4 megabytes of RAM.

       Only port 1 can be merged in the GX.  Card slot 2, which is
       intended for large-capacity RAM cards, is permanently "free",
       and is automatically divided up into 128K "ports", each of which
       becomes Port 2, Port 3, Port 4, etc.  Up to 4 Megabytes can be
       plugged into slot 2, which would then become Port 2 through Port
       33. (Although the FREE and MERGE commands were kept for HP48 SX
       compatibility, GX users will prefer the new FREE1 and MERGE1
       commands).  Therefore the maximum amount of merged main memory
       is 256K (unlike the SX which allowed up to 288K) after MERGE1;
       the maximum amount of fully online free independent memory is
       4224K after FREE1.

    LOCAL VARIABLES
       Variable names prefixed with a <- (backarrow character) are
       compiled as local (temporary) variable name objects even if
       they're not explicitly after FOR or ->.  This allows programs to
       share values through local variables, which is much faster than
       sharing values through global variables, and they get purged
       automatically.

    SPEED
       CPU clock speed is double the S/SX's, but throughput is
       estimated to be only 40% faster, primarily due to the fact that
       all RAM & ROM is now bankswitched (on the S/SX only a 32K
       portion of the ROM required bank switching), and it still has
       the same 4-bit bus bottleneck.

    IMPROVED COMMANDS:

    o  AXES can now also specify the spacing of the tick marks.

    o  DEPND can now also specify the initial values and tolerance for
       the new DIFFEQ plot type.

    o  REPL and SUB now work on arrays.

    HP SOLVE EQUATION LIBRARY CARD COMMANDS:

    o  AMORT, amortization calculations

    o  CONLIB, starts Constants Library catalog

    o  CONST, returns value of a named CONLIB constant

    o  DARCY, calculates Darcy friction factor


    o  EQNLIB, starts Equation Library catalog

    o  F0lambda, calculates black-body power fraction

    o  FANNING, calculates Fanning friction factor

    o  LIBEVAL is a generalized form of the EQ card's ELSYSEVAL; it
       executes any XLIB by its library number

    o  MCALC, marks an MSOLVR variable as "not user-defined"

    o  MINEHUNT, starts the "Minehunt" video game

    o  MINIT, initializes Mpar from 'EQ' for MSOLVR

    o  MITM, customizes title & menu of MSOLVR's screen

    o  MROOT, solve for variable(s) in MSOLVR

    o  MSOLVR, shows Multiple Equation Solver menu

    o  MUSER, marks an MSOLVR variable as "user-defined"

    o  SIDENS, density of silicon as function of temperature

    o  SOLVEQN, starts solver for specified EqLib equation(s)

    o  TDELTA, subtracts temperatures like "-" ought to but doesn't

    o  TINC, adds temperatures like "+" ought to but doesn't

    o  TVM, shows the financial calculator (Time Value of Money) menu

    o  TVMBEG, sets payments-at-beginning-of-periods mode

    o  TVMEND, sets payments-at-end-of-periods mode

    o  TVMROOT, solves for a TVM variable

    o  ZFACTOR, calculates gas compressibility factor Z

       Note: The EQ Card's Periodic Table and Tetris game are not in
       the HP48 G/GX, but the EQ Card can be used in the GX if those
       applications are needed. Tetris was not included because no
       agreement on royalty was reached.  The Periodic Table is
       available separately as freeware on HPCVBBS.

    NEW ARRAY COMMANDS:

    o  COL+, inserts a column vector into a matrix or a number into a
       vector (like INSCOL/PUTCOL in Donnelly's Tool Library)

    o  COL-, deletes a column from a matrix or number from a vector
       (identical to DELCOL in Donnelly's Tool Library)

    o  COL->, combines multiple column vectors into a matrix

    o  ->COL, breaks a matrix into multiple column vectors (like
       repeated GETCOL in Donnelly's Tool Library)

    o  COND, column norm condition number of a square matrix

    o  CSWP, swaps two columns in a matrix (like EXCOL in Donnelly's
       Tool Library)


    o  ->DIAG, returns vector of major diagonal elements of a matrix

    o  DIAG->, creates matrix with specified diagonal elements

    o  EGV, eigenvalues and right eigenvectors of a square matrix

    o  EGVL, eigenvalues of a square matrix

    o  FFT, discrete Fourier transform

    o  IFFT, inverse discrete Fourier transform

    o  LQ, returns the LQ factorization of a matrix

    o  LSQ, minimum norm least-squares solution to an ill-determined
       system of linear equations

    o  LU, returns the Crout LU decomposition of a square matrix

    o  PCOEF, returns polynomial with given roots (inverse of PROOT)

    o  PEVAL, evaluates polynomial at x

    o  PROOT, finds all roots of polynomial (inverse of PCOEF)

    o  QR, returns QR factorization of a matrix

    o  RANK, rank of a rectangular matrix (uses flag -54)

    o  RANM, creates matrix with random elements

    o  RCI, multiplies elements in one row of a matrix by a scalar

    o  RCIJ, does RCI then adds the result to a row

    o  ROW+, inserts a row vector into a matrix or a number into a
       vector (like INSROW/PUTROW in Donnelly's Tool Library)

    o  ROW-, deletes a row from a matrix or number from a vector
       (identical to DELROW in Donnelly's Tool Library)

    o  ROW->, combines multiple row vectors into a matrix

    o  ->ROW, breaks a matrix into multiple row vectors (like repeated
       GETROW in Donnelly's Tool Library)

    o  RSWP, swaps two rows in a matrix (identical to EXROW in
       Donnelly's Tool Library)

    o  SCHUR, computes the Schur decomposition of a square matrix

    o  SNRM, spectral norm of an array

    o  SRAD, spectral radius of a square matrix

    o  SVD, singular value decomposition of a matrix

    o  SVL, computes the singular values of a matrix

    o  TRACE, sum of diagonal elements of a square matrix

    GRAPHICS and PLOTTING COMMANDS:

    o  ANIMATE, displays grobs on the stack sequentially.  You can use
       the defaults, or specify your own delay between frames (can be
       very fast), the number of times to repeat the sequence, and even
       the pixel coordinates.  It's just like a ROLL REPL loop...
       except very fast.  Note: Charlie Patton converted 17 seconds of
       the Apollo moon-walk video into HP48 GROBs and ran them with
       ANIMATE, and it looked very good!

    o  ATICK, specifies tick spacing on plot axes

    o  EYEPT, specifies the eye-point coordinates in a perspective plot

    o  GRIDMAP, selects the new "gridmap" plot type

    o  PARSURFACE, selects the new "parametric surface" plot type

    o  PCONTOUR, selects the new "pcontour" plot type

    o  PICTURE, same as GRAPH command

    o  SLOPEFIELD, selects the new "slopefield" plot type

    o  WIREFRAME, selects the new "wireframe" plot type

    o  XVOL, sets the width of the 3D plotting volume

    o  XXRNG, sets the width of the 3D target mapping range for gridmap
       and parametric surface plots

    o  YSLICE, selects the new "yslice" plot type

    o  YVOL, sets the depth of the 3D plotting volume

    o  YYRNG, sets the depth of the 3D target mapping range for gridmap
       and parametric surface plots

    o  ZVOL, sets the height of the 3D plotting volume

    USER-INTERFACE COMMANDS:

    o  CHOOSE, displays a point-and-click menu "dialog box"

    o  INFORM, formatted multi-line input with named fields (nice!!)

    o  MSGBOX, displays text in a centred box with shadow, then WAITs

    o  NOVAL, placeholder for unspecified values in INFORM argument
       list

    LIST PROCESSING COMMANDS:

    o  ADD, adds lists element-wise (see section above)

    o  DOLIST, evals an object on multiple lists

    o  DOSUBS, evals a program or command taking arguments from a list

    o  ENDSUBS, returns the number of loops the current DOSUBS will do

    o  HEAD, first element in a list or first char in a string
       (identical to CAR in Donnelly's Tool Library)

    o  DeltaLIST, list of first finite differences of list objects

    o  SigmaLIST, sum of the elements in a list

    o  PiLIST, product of the elements in a list


    o  NSUB, returns the current list pointer value during a DOSUBS

    o  REVLIST, reverses the order of the objects in a list (like
       REVERSE in Donnelly's Tool Library)

    o  SEQ, list of results from repeated execution of an object (like
       a FOR/STEP loop but the results go into a list)

    o  SORT, sorts elements in a list into ascending order, or sorts a
       list of lists using each list's first element as the key (can be
       done with LSORT/QSORT in Donnelly's Tool Library)

    o  STREAM, executes an object on first two elements of a list, then
       again on the result and the 3rd element, etc.  Allows easy
       creation of things similar to SigmaLIST and PiList.

    o  TAIL, returns a decapitated list or string (see HEAD above)
       (identical to CDR in Donnelly's Tool Library)

    SYSTEM COMMANDS:

    o  CLTEACH, clears the 'EXAMPLES' directory created by TEACH

    o  CYLIN, sets polar/cylindrical coordinate mode

    o  FREE1, like 1 FREE (see section above)

    o  MERGE1, like 1 MERGE (see section above)

    o  PINIT, port initialize, esp. important for 4-Meg RAM card users

    o  RECT, sets rectangular coordinate mode

    o  SPHERE, sets polar/spherical coordinate mode

    o  TEACH, loads the Owner's Manual examples into a dir in HOME

    o  VERSION, returns the operating system ROM version string and a
       copyright notice, like this:


         2: "Version HP48-R"      <-- means version "R"
         1: "Copyright HP 1993"


    o  XRECV, X-Modem protocol receive (binary mode only)

    o  XSEND, X-Modem protocol send (binary mode only)

    MATH COMMANDS:

    o  LININ, tests whether an equation is linear in a given variable

    o  NDIST, normal probability density

    o  PCOV, population covariance of SigmaDAT

    o  PSDEV, population standard deviation of SigmaDAT

    o  PVAR, population variance of SigmaDAT

    o  RKF, solves initial value problem using Runge-Kutta-Fehlberg


    o  RKFERR, change in solution and absolute error using RKF

    o  RKFSTEP, next solution step with given error tolerance using RKF

    o  RRK, solves initial value problem using Rosenbrock & RKF

    o  RRKSTEP, next solution step with given error tolerance using RRK

    o  RSBERR, change in solution and absolute error using Rosenbrock

    MENU NUMBERS and KEY CODES
       Many menu numbers have changed, so software that uses # MENU or
       # TMENU may not work the same as in the HP48 S/SX.
       (Specifically, only menu numbers 0-3, 28, 30, and 42-59 are the
       same). Likewise, almost all of the shifted keycodes correspond
       to new commands and menus, which programmers must take into
       account; for example, the "RAD" key on the S/SX had the keycode
       82.2, but it's 21.2 on the G/GX.  The left-shift key, which was
       orange on the S/SX, is now purple [officially "lavender"], and
       the right-shift key which was blue on the S/SX is now green
       [officially "teal"] on the G/GX.  Also, the digit-key menus can
       be activated by both shift keys; left-shift gives the softkey
       menus like in the S/SX, but the right-shift gives the new user-
       friendly full-screen menus.  The unshifted keys remain identical
       to the S/SX, except for a cosmetic colour change to match the
       very dark green of the calculator case.

    MANUALS
       The G/GX comes with two manuals, a "Quick Start Guide" for
       beginners, and a cost-cutting, slimmer owner's manual called the
       "User's Guide" which has only 21 pages about programming, since
       HP figures that the huge majority of all 48 owners never program
       it anyway.  The power users can buy the optional "Advanced Users
       Reference Manual" (similar to the S/SX's "Programmer's Reference
       Manual") which covers programming and the many commands that are
       not mentioned in the User's Guide.  There is no "Quick Reference
       Guide" like the S/SX came with, although the case still has a
       pocket for one.

       Jim Donnelly has marketed a nice pocket guide, but it's too wide
       to fit in the case's pocket.  The User's Guide is not spiral
       bound, but is made to open fully and last a long time, since
       it's not just glued but has sewn signatures like real books, and
       is printed on quality paper.

       Another possibility is "The HP 48G/GX Pocket Guide" by Chris
       Coffin and Thomas Dick (Grapevine Publications).  It's 80 pages
       long, contains a complete command reference (with input/output
       stack diagrams), alpha keyboard description, system flag
       description, as well as examples of how to use various
       calculator features.  This guide is designed to fit nicely in
       the pocket of the HP case.

    FLAGS
       Some previously "unused" flags are now used.  They are:


    -14 Clear = end-of-period payment mode (for TVM calculations)
        Set   = beginning-of-period payment mode

    -27 Clear = display symbolic complex numbers in coordinate form
                e.g. '(X,Y)'
        Set   = display symbolic complex numbers using 'i'
                e.g. 'X+Y*i'

    -28 Clear = plot multiple equations like the S/SX does (serially)
        Set   = plot multiple equations simultaneously

    -29 Clear = include axes in plots (like the S/SX does)
        Set   = omit axes from 2D and statistics plots

    -30 is no longer used (it never did anything useful anyhow)

    -54 Clear = tiny matrix elements get rounded to zero
        Set   = leaves matrix elements alone


    The default setting of all these flags is Clear (as in the S/SX).

    FLAG BROWSER
       There is a System Flag browser which shows the flag number,
       shows whether it's set or clear, lets you toggle it, and shows
       in English what the current setting means.

    CHARACTER BROWSER
       While programming, if you want to type any character at all,
       press CHARS and a screenful of ASCII characters is displayed
       that you can browse with the arrow keys, and not only does the
       screen also show the ASCII code (NUM value) and even the
       shortcut keyboard key sequence (if any) for each character, but
       if you press ECHO, it will be "typed" into your program.
       There's no need any more for the alpha keyboard table.

    DIRECTORY MAINTENANCE
       Press right-shift VAR to launch a Variable Browser which is a
       complete memory manager.  You can tag multiple objects and copy,
       move, or delete them all with a single keystroke; there's even a
       Mark All and an Unmark All, like a real computer.  It's slow,
       however, and has been obsoleted by the very fast PCT library.

    FRACTIONAL UNIT POWERS
       The S/SX only handled integer powers of units correctly, but the
       G/GX can use any real number as a unit power.

    NAME PLATE
       The case has a rectangular indentation in the back like the HP
       95LX and 100LX, and it comes with an adhesive metal nameplate
       that you can get engraved with your name.

    XLIB NAMES
       All of the new commands in the GX are XLIB names, and therefore
       take 5.5 bytes in programs.  The commands common to the SX and
       GX take 2.5 bytes each, as they did in the SX.

    INPUT FORMS and CHOOSE BOXES
       Many operations have two menu types: the old SX style, and a new
       "drop-down" menu and "input forms" that have the feel of
       computer dialog boxes.  Especially useful for the HP48 beginner.

    ENHANCED PRECISION
       The internal precision of at least some of the matrix routines
       has been improved; INV gets better answers on square matrices
       than the SX did.  HP has not released information about which
       routines were improved, how, and by how much.

    IMPROVED DISPLAY
       The LCD introduced with revision M of the G/GX is easier to read
       since it has higher contrast between on/off pixels.  It has a
       slower cycle response time, however, making it difficult to use
       for rapid-motion video games or any other rapid animation.


 10.2.  Examples of INFORM, CHOOSE, and MSGBOX

 From: Jarno Peschier

 Some examples of INFORM, CHOOSE and MSGBOX on the HP48 GX. Just
 download the entire directory to your calculator and try the programs,
 change them, modify them and do everything else with them you can
 think of.

    SIMPLE:
       This program will demonstrate a simple INFORM input screen with
       3 fields (one without type restrictions, one for real or complex
       numbers and one for strings) with some additional layout. MSGBOX
       and CHOOSE (with the third parameter equal 0) are used to show
       what the results of the INFORM command are. The list the INFORM
       command returns is left on stack so you can see what it looks
       like.

    ANGLE:
       This program will demonstrate the use of CHOOSE. It lets you
       choose between the three possible angle modes (DEG, RAD, GRAD)
       and when you choose one of them, the corresponding mode is set
       by evaluating a tiny program containing the right command.

    ISOLATE:
       This program will demonstrate the use of INFORM in ways that it
       is used in the calculator itself. It is a very simple shell
       around the ISOL command (isolation of a variable from an
       algebraic). It remembers it's settings in a variable called IPAR
       and the next time the program is run this will be the default
       values of the INFORM command, so you can isolate for a different
       variable using the same algebraic you used before, without
       retyping it. MSGBOX is used for error messages.

    TYPELIST:
       This program will again demonstrate the use of CHOOSE. It
       extracts the names of all the internal types of the HP48 GX from
       ROM and shows them in a CHOOSE-box (alphabetically sorted by
       name). If you choose one of them, its TYPE number is shown in a
       MSGBOX.

    MATHQUIZ:
       This final program will demonstrate the use of INFORM with
       variable field descriptions and default/reset values. It's will
       show you 8 fields that are simple math questions for you to
       solve (addition and subtraction).  You can enter all the results
       and then you will see if your answers were correct (in a
       MSGBOX). You must fill all the fields. Hint: you can cheat by
       resetting a field (or all fields).


    %%HP: T(3)A(D)F(.);
    DIR
      SIMPLE
        \<<
          IF
    "AN EXAMPLE OF INFORM"
    { { } { } { } {
    "OBJECT:"
    "ALL OBJECTS ARE ALLOWED HERE"
    } { } { "NUM:"
    "ENTER A (COMPLEX) NUMBER"
    0 1 } { "NAME:"
    "ENTER YOUR FULL NAME"
    2 } { } { } } { 3 1
    } {
            \<< 440 1
    BEEP
            \>> (0,1)
    "JARNO PESCHIER" }
    { NOVAL 0 "N.N." }
    INFORM
          THEN DUP
    "YOU ENTERED:" SWAP
    0 CHOOSE DROP
    "The list that INFORM produced is still on the stack."
          ELSE
    "You cancelled the INFORM."
          END MSGBOX
        \>>
      ANGLE
        \<<
          IF
    "ANGLE MEASURE" { {
    "Degrees" DEG } {
    "Radians" RAD } {
    "Grads" GRAD } } 1
    CHOOSE
          THEN EVAL
          END
        \>>
      ISOLATE
        \<<
          IF
    "A VERY SIMPLE VARIABLE ISOLATOR"
    { { } { "EXPR:"
    "ENTER THE EXPRESSION"
    9 } { "VARIABLE:"
    "ENTER VARIABLE TO ISOLATE"
    6 } } { } { }
            IF 'IPAR'
    VTYPE 5 \=/
            THEN { }
            ELSE 'IPAR'
    RCL
            END INFORM
          THEN DUP 'IPAR' STO
            IF DUP
    NOVAL POS
            THEN DROP
    "You must enter an expression and a variable!"
    MSGBOX
            ELSE OBJ\->
    DROP
              IFERR
    ISOL
              THEN
    DROP2 "Error: "
    ERRM + MSGBOX
              END
            END
          END
        \>>
      TYPELIST
        \<<
          IF
    "ALL HP48 TYPES (IN ROM)"
    0 27
            FOR msg
              IFERR msg
    263 + DOERR
              THEN ERRM
              END msg 2
    \->LIST
            NEXT 28
    \->LIST SORT 1 CHOOSE
          THEN
    "That one has type number "
    SWAP + "." + MSGBOX
          END
        \>>
      MATHQUIZ
        \<<
          IF
    "A SIMPLE MATH QUIZ"
    1 8
            FOR i "'"
    RAND 100 * IP +
              IF RAND
    0.75 <
              THEN "+"
              ELSE "-"
              END +
    RAND 100 * IP + "'"
    + "ENTER RESULT #"
    i + 0 3 \->LIST
            NEXT 8
    \->LIST DUP
            \<< \-> X
              \<< X HEAD
    2 OVER SIZE 1 - SUB
    "=" + X 1 ROT PUT
              \>>
            \>> DOLIST
    SWAP
            \<< \-> X
              \<< X HEAD
    OBJ\-> EVAL
              \>>
            \>> DOLIST 3
    ROLLD { 2 5 } 4
    PICK { } INFORM
          THEN
            IF DUP
    NOVAL POS
            THEN DROP2
    "You didn't fill all the blanks."
            ELSE
              IF SAME
              THEN
    "All answers were correct!"
              ELSE
    "Not all answers were correct."
              END
            END MSGBOX
          ELSE DROP
          END
        \>>
    END


 10.3.  Some useful LIBEVALs

 From: Joe Horn

 Note well: backup memory before using any of the following!  LIBEVAL
 can clear memory if used incorrectly.  Warning to the clueless:
 LIBEVAL, NOT SYSEVAL!!!  If you don't know what a "bint" is, don't use
 the ones that mention bints.

 Example usage: "OUT OF RANGE Try Again" #B0091h LIBEVAL.  Try it!


      -----------------------------------------------------+----------
      Function                                             | LIBEVAL
      -----------------------------------------------------+----------
      Displays message box with grob                       | #B1000h
      CMD  last command window                             | #B2000h
      CHARS application                                    | #B2001h
      MODES application input form                         | #B41C1h
      flag browser  (returns t/f to level 1, just drop it) | #B41CFh
      MEMORY application  (aka variable browser)           | #B41D7h
      SOLVE application choose box                         | #B4000h
      solve equation input form                            | #B4001h
      solve difeq input form                               | #B4017h
      solve polynomial input form                          | #B402Ch
      solve linear systems of equations input form         | #B4033h
      solve TVM input form                                 | #B4038h
      PLOT input form                                      | #B4045h
      SYMBOLIC application choose box                      | #B4113h
      integrate input form                                 | #B4114h
      differentiate input form                             | #B4122h
      Taylor polynomial expansion input form               | #B412Bh
      Isolate a variable input form                        | #B412Dh
      solve quadratic input form                           | #B4130h
      manipulate expression input form                     | #B4131h
      TIME application choose box                          | #B4137h
      Set alarm input form                                 | #B4138h
      Set time and date input form                         | #B415Bh
      Alarm browser   (aka alarm catalog)                  | #B416Eh
      STAT application choose box                          | #B4175h
      single-var stat input form                           | #B4176h
      frequencies input form                               | #B417Dh
      fit data input form                                  | #B417Fh
      summary stat input form                              | #B418Fh
      I/O application choose box                           | #B4192h
      Send to HP48 input form                              | #B4193h
      Print input form                                     | #B4197h
      Transfer input form                                  | #B41A8h
      Get from HP48  (immediate)                           | #B50FFh
      recalls the contents of the reserve variable Mpar    | #E4012h
      -----------------------------------------------------+----------


      LIBEVAL : stack diagram / what it does
      -------   -----------------------------------------------------------
      #B0091h : $ --> makes a message box with an alert symbol in it
      #E0044h : $ --> displays a title line, top center (follow with
                1 FREEZE if you want it to stay there after program ends)
      #B2000h : launches the Last Command choose-box
      #B2001h : launches the CHARS application; returns nothing if user does
                not press ECHO
      #B2002h : launches the CHARS application; returns "" if user does not
                press ECHO
      #B41CFh : launches Flag Browser; leaves a True or False on stack, so
                follow this LIBEVAL with a DROP.
      #B50A3h : --> current time as hour, min, sec separately, plus an XLIB
                that represents AM/PM/24-hr (just DROP it)
      #B50A4h : hh.mmss --> hh mm ss xlib (the xlib represents AM,PM, or
                24-hr mode; just DROP it)
      #B50A6h : --> current date as month, day, year (always that order, and
                a two-digit year)
      #B50A7h : mm.ddyyyy (or dd.mmyyyy) --> month, day, yr
      #B50A9h : #month #yr --> #days_in_that_month (inputs and output are
                bints; year is two digits, interpreted as between 1991 &
                2090 only)
      #B50AAh : #yr --> %0.00yyyy (input is two-digit bint interpreted as
                between 1991 and 2090; output is a real number)
      #B50ABh : #mon #day #yr --> #day_of_week (inputs & output are bints;
                year is two digits interpreted as between 1991 & 2090;
                Sunday is #7; if you're in DMY mode, then the input order is
                #day #mon #yr)
      #B50B2h : --> { 1 2 3 ... 59 } (not very fast)
      #B50B3h : --> { 1 2 3 ... 10 } (very fast)
      #B50B4h : --> { 0 1 2 ... 23 } (very fast)
      #B50B9h : --> { " 1 January" " 2 February" ... "12 December" }
      #B50D5h : --> number of alarms currently set (as a bint)
      #E3063h : hxs --> grob (this is an RLL packed-grob uncompressor, used
                by EQ LIB and MINEHUNT; for example, try this:
                #E202Bh LIBEVAL 3 GET #E3063h LIBEVAL PICT STO PICTURE)
      #E202Bh : the first of the packed EQ LIB grobs (see above)
      #E2069h : the last of the packed EQ LIB grobs (see above)
      #E7039h : MINEHUNT packed grob (left screen border)
      #E703Ah : MINEHUNT packed grob (right screen border)
      #E801Eh : obj --> obj T/F (tests whether object is in temporary memory
                or not; returns System-RPL True or False)


 11.  Appendix C: Details of Bugs

 11.1.  The EquationWriter Bug

 From: Joe Horn


    Rev E Behaviour
       Clear flag -53 first (the Precedence Flag).

       On a Rev E, put '((1+2)/(3+4))^5' on the stack and press down-
       arrow.  You'll see:


                5
         / 1+2 \
         | --- |                         (A)
         \ 3+4 /

    which is as it should be.  But now press [orange-shift] [+]; see
    the message "Implicit () off" momentarily; press [left-arrow] (not
    backspace), then press the [EXIT] softkey.  The expression gets
    mangled into this:


             1+2
         -----------                       (B)
               (5)
          (3+4)


    which is not equal to expression (A) above!  Bug, yes?  Press ON to
    abort the process.

    Now set flag -53, then repeat the above procedure.  First you see:


                5
         / 1+2 \
         | --- |                         (C)
         \ 3+4 /


    which is the same as (A) above; but continuing as before, you see:


                  (5)
         /  1+2  \
         | ----- |                       (D)
         \ (3+4) /


    which is equal to the original.  Thus the bug can be worked around
    by keeping flag -53 set (not a pleasant solution).

    Rev J Behaviour
       Major difference: after pressing down-arrow, Rev J goes directly
       into graphic mode, so you have to press ON and then EXIT to get
       into the equation editor (which Rev E goes directly into).  But
       that's petty cash compared to the following big change.

       The same sequence of operations, first with flag -53 clear, then
       set, exactly as detailed above, yields these four displays in a
       Rev J:


                  5
         / (1+2) \
         | ----- |                       (A')
         \  3+4  /


    (notice the extra parentheses?) and then:


             5
    / (1+2) \
    | ----- |                       (B')
    \ (3+4) /


    which is equal to (A'); nothing at all like expression (B) above!
    and then:


                  5
         / (1+2) \
         | ----- |                       (C')
         \  3+4  /


    which is the same as (A') above; and then:


                  5
         / (1+2) \
         | ----- |                       (D')
         \ (3+4) /


    which is also equal to (A').  No bug in Rev J.

 SUMMARY: Rev A-E have a bug in the EquationWriter that can mangle
 expressions if flag -53 is clear (the default) and if "Explicit Paren-
 theses" mode is toggled.  This bug has been fixed in Rev J.

 Unfortunately (as you can see above) Rev J always puts parentheses
 around polynomial numerators.  It is therefore impossible to use the
 ->GROB command on a Rev J to create a GROB that looks like expression
 (A) above; the simplest that can be had is expression (A').

 Another minor change, while I'm at it: Rev A-E don't change the menu
 when you press REPL; Rev J automatically flips to the appropriate
 RULES menu.


 11.2.  Rotation Rate to Angular Frequency Conversion Bug


    About the Bug:
       From: Wlodek Mier-Jedrzejowicz <[email protected]>

       There is a rotation rate conversion bug in the HP48 G/GX which I
       have not seen reported here before, so after discussion with the
       folks at Corvallis I am posting this description. Warning: it is
       159 lines long!

       First - an example. Put the unit object 60_rpm in level 2 and
       the unit object 1_r/s in level 1, then execute the command
       CONVERT.  You are asking the HP48 to convert a rotation rate of
       60 revolutions per minute into an angular frequency in radians
       per second. 60 rpm is 1 revolution per second, or 2pi radians
       per second.  No HP48 G/GX will give this answer!  Not everyone
       uses rpm or is even aware of the existence of this unit - it is
       one of the extra units in the UTILS menu of the Equation Library
       - so here is a second example - add 2pi radians per second to
       one Hertz.  Put 6.2832_r/s in level 1, 1_Hz in level 1, and add.
       You are adding an angular frequency of two pi (one cycle) per
       second to a rotation rate of one per second, so the result
       should be a frequency of two Hertz.  On an HP48 S/SX that is the
       answer.  On an HP48 G/GX it is not.

       When units are converted, by CONVERT, or during arithmetic on
       unit objects, the level 2 object is first turned into "base
       units", and then the result is converted into the units of the
       level 1 object.  On the HP48 S/SX, the "base unit" of angles is
       one rotation (or a "unit circle" or a revolution or a cycle).
       So, the angle unit of rpm (a revolution) or of Hz (a cycle if Hz
       is treated as a rotation rate) is already in base units -
       conversions to angles involving rpm and Hz automatically work
       correctly.  On the HP48 G/GX, the "base unit" of angles is the
       current angle mode (DEG, RAD or GRAD) - so any conversion from
       rpm or Hz (or any formula which works in cycles, rotations,
       revolutions, unit circles) to angles should be preceeded by a
       conversion from the unit circle to the current angle.
       Apparently no-one noticed this would be necessary, because it
       all worked automatically on the HP48 S/SX.

       So, when you convert 60_rpm to units of _r/s, an HP48 G/GX
       converts not 60 rotations but 60 "base angle units" per minute
       to radians/second. In RAD mode, you get 1 radian per second. In
       DEG mode you get 1 degree per second, and in GRAD mode you get 1
       grad per second (in each case expressed in radians). That's
       three different answers, none of which is correct! Exactly the
       same happens if you convert 1_Hz to angles per second, and the
       inverse mistake is made if you convert angles per time to cycles
       or rotations divided by time.

       I first learned of this bug from a member of HPCC (the British
       club for users of HP handhelds), Peter Embrey. He describes his
       troubles in articles in the first two 1994 issues of our club
       journal, DATAFILE (in Volume 13 number 1 pages 12 to 14 and
       V13n2p6). He was calculating the energy stored by a flywheel -
       given by the formula (1/2)*I*omega^2 and after a time he decided
       the answers had to be much too big when he CONVERTed from
       kg*m^2*(r/s)^2 to W*h on an HP48 GX.  It turns out that (r/s)
       are the correct units to get the right answer, but the GX was
       converting to degrees per second as it was in DEG mode, so his
       answer was too large by a factor of (360/2pi)^2 - a factor of
       about 3,300. In this case, his HP48 SX was not much better,
       since it converted from radians to unit circles. The way to get
       the correct answer is to use an HP48 G or GX in RAD mode - or to
       divide out the radians from the formula before using CONVERT.
       This is not yet a bug, but needs as much care as does use of
       temperature units on the HP48. But when Peter tried to deal with
       the problem by working in rpm, he came upon the bug described
       above. My thanks to Peter for putting me on the trail!

       Apparently this bug not been reported before - at least my
       friends in HP tell me that it was not on their list of known
       problems until I told them of it. (This means it is not fixed in
       the new revision R.) Why not - does everyone know about it and
       work around it without thinking to tell anyone else? Or does no-
       one use their HP48 to do calculations on rotating bodies - or do
       most people do calculations with rotating bodies in such a way
       that they do not encounter this problem? Could there be hundreds
       of students and engineers out there calculating and designing
       things on their HP48 G/GX and getting wildly inaccurate results?
       Has anyone built a disk drive or a jet engine which rotates far
       too fast and will disintegrate because of this? No, of course
       not, all engineers know that any design calculation absolutely
       must be repeated on two entirely separate calculators or
       computer programs! :-| Maybe some students have lost marks in
       exams because of this though - but please, this is not intended
       to restart the discussion as to whether calculators should be
       allowed in exams!

       I want to underline again that apparently no-one has reported
       this before - which must mean that few people have been affected
       by it. It is therefore not a good reason to throw away your HP48
       G/GX or get on a high horse and demand that HP replace your HP48
       G/GX - but I think it is important that people be warned so they
       can take appropriate avoiding action. The rest of this message
       goes into more detail - if you never worry about rotation
       calculations then you can safely ignore the rest - though you
       might find it interesting, so don't stop yet :-)

       One way to avoid this would be to add a new unit to the HP48 -
       call it what you like - the "cycle" or "rotation" or
       "revolution" or "unit circle". As I wrote above, this is already
       implied in the HP48 S/SX; to see this on an HP48 S/SX, put 360
       degrees in level 1 and execute UBASE - the result is 1, meaning
       that 360 degrees are equivalent to one base unit of angle
       measurement, but that there is no named HP48 unit corresponding
       to this. In contrast, UBASE on an HP48 G/GX considers the base
       unit of angle measurement to be the radian, even though CONVERT
       behaves as though the base unit is the current angle mode. There
       appear to be two different norms for base angle units on the
       HP48 G/GX!

       The whole subject gets very little mention in HP's manuals. In
       the original HP48 SX manual (two volumes, spiral bound), the
       section on "Dimensionless Units of Angle" in chapter 13, on page
       198, warns the reader about the danger of using dimensionless
       units and states how angle units and scalars are treated. In the
       later HP48 S and HP48 SX manual (one volume), the same warning
       is given in "Converting Dimensionless Units of Angle", on page
       13-12. The HP48 G Series User's Manual, in "Converting Angular
       Units" on page 10-7, says that conversion will interpret a
       scalar according to the current angle mode setting. (A scalar is
       a pure number with no units.)

       For a detailed description, look in the HP48 S/SX edition of
       "HP48 Insights Vol II", section 21.4.3. This book is written by
       Dr Bill Wickes, who was the design team leader of the HP48 SX,
       and who wrote the "Insights" books largely to provide the sort
       of explanations and details that get left out of manuals. A good
       explanation of angle units is exactly the sort of thing one can
       find there! He explains the pitfalls and unavoidable
       contradictions of working with angles in the HP48 units system
       and points out that the HP48 S/SX make the somewhat arbitrary
       choice of using 2pi as the base unit of angles, thereby making
       conversions between angles per time and Hertz work correctly.

       Maybe no-one on the HP48 G/GX team read this while they were
       making changes from the HP48 S/SX! Why did they change the base
       unit at all?  Most likely they were trying to deal with another
       contradiction: the units system lets you add pure numbers to
       angles, since both are dimensionless. If you add the number 1 in
       level 2 to the unit object 0_r in level 1 on an HP48 S/SX, the
       number 1 is treated as 1 base unit, or 2pi radians, and the
       result is 6.2832_r - but if you take the SIN of the number 1
       instead, it is not treated as 2pi, but as 1 unit of the current
       angle mode. The change made on the HP48 G/GX does resolve this
       contradiction, but at the cost of introducing the bug described
       above.

       As mentioned, a way to resolve the problems involved would be to
       add the angle unit "cycle" explicitly to the HP48 units system.
       Hz would then be treated as cycles per second when used in
       calculations involving rotations - rpm would be treated as
       cycles per minute, and conversions would go from cycles to the
       appropriate angle units. This suggestion was made by Peter
       Embrey in his articles, and the folks at HP accept that this is
       a good solution - but they have not implemented it yet. In the
       meantime, be very, very careful when converting between units of
       rotation rate and units of angular frequency. I would urge
       everyone who does not yet have a copy of Insights II to buy one
       and read the relevant section - maybe that will even entice Bill
       Wickes into publishing his long-awaited HP48 G/GX version of the
       book!

       I have not yet mentioned solid angles. In principle there should
       be no problem - on both the HP48 S/SX and the HP48 G/GX the base
       unit of solid angle is a "unit sphere", or 4pi steradians. On
       the HP48 S/SX you can add the pure number 1 to 0_sr and get
       12.5664_sr (4pi steradians). The HP48 G/GX manuals imply that
       exactly the same should happen, but on my (version L) HP48 GX
       this gives the error message "Inconsistent Units".  This is yet
       another undocumented difference between the Series S and Series
       G but at least it is no bug!

       Apologies for making this description so long, I hope most
       people will agree that a subject like this deserves a careful
       description! For my next trick - some details on the HP48 Random
       Number Generator.


    Addition Insight:
       From: Eric Haas <[email protected]>

       Note: The < symbol below is actually the angle character.

       The angular conversion bug is actually in the definition of the
       rpm unit.  If you put 1_rpm on the stack, and type UBASE, you
       get 1.66666666667E-2_1/s.  Notice that there is no angular unit
       in the definition. If the rpm unit is instead defined as 6_</s,
       all conversions to and from rpms will work just fine. As an easy
       work-around, define the unit RPM as 6_</s and use that instead
       of the built-in unit.

       If desired, one could also define the unit HZ as 60_rpm or
       360_</s.  However, as Hz is sometimes used to describe things
       other than rotation rates, such a definition would not be
       appropriate for all circumstances.


 12.  Appendix D: Hardware Additions

 12.1.  How to Make a Serial Cable

 From: Frank Vorstenbosch <[email protected]> Revised by: Andrew Chen

 Now that you have your HP, you probably want to tap the tremendous
 amount of programs out there.  But how do you do this?  You need an HP
 to PC link.  You can buy one, but they tend to be fairly costly.  Or
 you can build your own.  The process requires the following parts:

 Required Parts:


 o  Soldering iron and flux

 o  RS232-9 or RS232-25 shield (serial port shield)

 o  RS232-9 or RS232-25 female connector (serial port connector)

 o  4 pin HP connector, with sockets spaced 2 mm (NOT 0.1") apart

 o  Some copper wire

 Of the above list of parts, most are pretty easy to acquire, and you
 should be able to find them at your local electronics store.  However,
 the 4 pin (i.e. male) HP connector can be a bit harder to find.

 If you happen to have a broken floppy drive, hard drive, or CD-ROM
 audio cable lying around, look inside and see if you can find a
 connector there that will fit the HP48.  Do not use a 0.1" connector,
 as this will damage the pins on your calculator.


    HP Connector
       The HP connector part of the cable will be the most frustrating
       part of the link.  The reason is that you will probably not be
       able to find these at your local electronics store, but you
       should you should find everything else there.  Instead, you can
       either find the connector at used computer stores or you can
       create the link yourself.


       Easy Way
          Because the former is much easier, I will give you some tips
          on where one can find the connecter.  First, check your
          yellow pages and look under "computer".  You will find a lot
          of stores, but look specifically for "computer repair" or
          "computer parts".  Call these stores asking for a "CD-ROM
          audio cable".  If the store carries these cables, go to the
          store and ask to see the requested cable.

          What you should see is a cable with two ends, each with a 4
          socket connector.  One end should be spaced a bit larger than
          the other, and this one will not fit into the HP's pins
          (don't press too hard, or else you will bend the connector
          pins).  The other side should fit like a charm.  Don't be
          worried about that there are only 3 sockets.  This is fine
          because the empty one is a ground.  Once you have this cable,
          cut off the unusable end, and go to the PC connector section.


       Hard Way
          If are unable to find a place that carries CD-ROM audio
          cables, or you prefer to make your make, it is possible to
          build the connector yourself.  What you can do is buy IC
          sockets from a local electronics store.  You can usually find
          them in packs of 8 or more.  These IC sockets will be bound
          together in a hard plastic shell, which also places at
          unusable intervals.  Therefore, it is necessary to strip the
          IC sockets out of the hard plastic shell (don't worry too
          much about damaging them, the IC sockets are fairly durable
          and you have 8 of them).

          Next, solder a 'fork' from thin rigid metal wires, to hold
          the four IC pins spaced at exactly 2 mm while you glue them
          together with superglue.  Glue a plastic 'handle' to the four
          IC pins to be able to remove the connector from the HP48.
          You can also indicate the top side of the connector on this
          handle.

          Note that the hole in the HP48 in which the connector should
          go is not symmetrical; the pins are nearer to the top of the
          calculator than the bottom, and you can use this to make it
          difficult to insert the connector the wrong way up.

          With that done, you can proceed on to the PC side of the
          connector.


    PC Connector
       The PC side of the connector is much simpler than the HP side.
       All you have to do is make a standard serial connector with the
       parts you bought.  However, don't do it yet because you need to
       solder the wires from the HP connector into the back of the
       serial connector first.


    Making the Connections
       Now that you have the two sections done, you can begin making
       the connections for the actual link.  Starting with the HP side,
       put in the connector and mark the top as "UP".  If you have a
       CD-ROM audio cable with one socket missing, make sure that the
       empty socket connects to pin 1:


          Connector on HP48         Connector to HP48
               ______                     ______
               |....|                     |oooo|  <-- First is
               \____/                     \____/       null
           pin 1   pin 4              pin 4   pin 1


    If you made the HP connector the hard way, you have to solder the
    ends of the IC sockets to long pieces of wire, which will
    eventually connect to the serial connector on the PC side of the
    cable.

    With these wires done, you must solder the individual wires into
    the proper places on the PC side.  Use this table of pin
    connections:


         HP to PC cable

         HP48 | RS232-9 | RS232-25
         -----+---------+----------
           1  | shield  |  shield
           2  |    2    |    3
           3  |    3    |    2
           4  |    5    |    7


    You can use either a 9 or a 25 pin female sub-D socket for the PC-
    side of the cable:


       9-pin RS232                 25-pin RS232
      connector (F)                connector (F)

    pin 5       pin 1    pin 13                     pin 1
      -------------         ---------------------------
      | o o o o o |         | o o o o o o o o o o o o |
       \ o o o o /           \ o o o o o o o o o o o /
        ---------             -----------------------
     pin 9     pin 6      pin 25                   pin 14


    Use flexible 4-wire cable to connect the four contacts of your HP48
    connector to the PC connector.  Pin 1 of the HP48 should be
    connected to the metal shield of the RS232 connector.  Usually it
    is not easy to solder this shield; first scratching the shield bare
    (it has some kind of coating) using a screwdriver or a file will
    help.  If this doesn't work, simply leave pin 1 of the HP48
    disconnected.  Note that pins 2 and 3 of the RS232 connector must
    be swapped when you use a 25-pin connector.

    Before connecting the completed cable to your HP48, check for
    short-circuits using an ohmmeter or multimeter set to ohms or
    "diode test".  The HP48 has a built in serial loop back test that
    can be used to test the serial cable (see the question regarding
    the ON-KEY combinations).

    After you are done, close the shield and connector, and put in all
    the screws.  You should now have a HP<-->PC link, which functions
    on COM (serial) ports.


    Using the Link
       With the link finished, it is now ready to be tested.  Download
       some programs (such as those in the Best Program List) that you
       wish to try.  At some point you should go to
       <http://www.columbia.edu/kermit/> to obtain the version of
       Kermit that suits you best.

       However, if you have an alternate communications program (for
       example, Windows 95 comes with HyperTerminal which you can use)
       you can delay downloading Kermit.  However, it is a highly
       recommended to obtain because certain programs for the HP48 use
       special features in Kermit (such as server mode) not available
       in other communications programs.

       With this done, you can begin the actual transfers.  Start your
       communications program, and set the port to COM1 (or whatever
       your link is plugged into).  In Kermit, you would type "SET PORT
       COM1" and in HyperTerminal you would set the dialog box with the
       choice of what modem you want to use to "Direct to COM1".

       Then change the speeds of the ports to 9600.  In Kermit, type
       "SET SPEED 9600" and in Hyperterminal click on Advanced.

       On the HP, go to I/O, and go to Transfer.  Set the calculator to
       Wire, 9600 baud, and Kermit (or X-Modem, if you using it
       instead). Then, get ready for to receive a file.  Note that X-
       Modem is much faster than Kermit in most situations, especially
       in long transfers.  However, it is not available built-in on the
       S/SX.

       On the PC start sending, and on the HP, start receiving.  You
       should see the transfer arrow on the upper right of the screen
       on the HP, and it should be flashing.  On the PC, you should see
       a progress indicator to show how much of the file has been
       transferred.

       When the transfer is finished, check that you received what you
       expected.  If it what you expected, your HP<-->PC link works!


    HP to HP Cable
       If you want to use 9600 bps communication between two HP48s,
       then make two HP48 connectors and simply connect the two,
       swapping pins two and three.


         HP to HP cable

         HP#1 | HP#2
         -----+-----
           1  |  1
           2  |  3
           3  |  2
           4  |  4


    Warranty, Disclaimer, etc...
       Although the serial interface of the HP48 is protected
       internally, it is possible to damage the calculator when a wrong
       connection is made.  I am not responsible for any errors in this
       file, or for any mistakes you may make.

 From: Deborah Lynn Williams

 I made an HP48 link out of four pieces of speaker wire and serial port
 plug.  The wiring of the plug is available above.  The connection to
 the HP plug is the difficult part.

 I took 4 pieces of stranded speaker wire and cut them so that the wire
 and the insulation were even.  I then took a paper clip and pushed it
 into the this open end, making a space between the wire and the
 insulation.  I then had to trim some of the strands that were sticking
 out.  I then just pushed this onto the pins in the HP48 port.  It
 isn't a very strong connection, but it works fine if you don't jostle
 it.

 The other ends of these speaker wires I connected to the serial plug.
 Just remember to label which wires go to which pin, or make them all
 different lengths.

 From: John Cutter

 Another cheap source for cables is the common serial mouse for PC-
 compatibles.  I had a cheap one on which the button gave out after 2
 weeks of use, so I opened it up.  It had a serial 9 pin cable that
 disappeared into the mouse.  Once open, there was a 4 pin 2 mm
 connector plugged into the mouse's circuit board.  All I had to do was
 reverse two pins inside the connector, and it's been working fine
 since.  I also noticed that Logitech mice have 6 pin 2 mm connectors,
 which could also be adapted.  No soldering or crimping here!


 12.2.  Using a modem with the HP48

 From: Diego Berge

 My purpose here is to explain in some detail the steps you need to
 follow to be able to transmit data via modem with the HP48.  Another
 related document is
 <http://www.freeweb.org/freeweb/enrico/hp2modem.htm> by Enrico Carta.

 In order to successfully connect your HP48 calculator to a modem, the
 first thing you need is a 'Null Modem Cable'.  A null modem cable is
 like a regular serial cable, except that two of its lines are crossed.

 You might wonder: So why is it different connecting to a PC than
 connecting to a modem?  Well, data communication devices can be
 classified in two groups: Devices which GENERATE or RECEIVE
 information, and devices which merely TRANSMIT information.  The
 former are called Data Terminal Equipment (DTE), PCs are an example of
 DTE; the later is called Data Communication Equipment (DCE), and are
 primarily modems.  Now, when PCs were designed, it seems like they
 didn't think somebody would ever want to hook two DTEs directly, as a
 result, in a typical PC all we have (besides the parallel printer
 port) is an RS-232 port, which is intended for connecting a DCE.  So
 when a machine wants to connect to a PC, its port must be that of a
 DCE, even if it otherwise acts as a DTE.  Within that class of hybrids
 fall HP48s, Psions, some (or most?) serial printers, mice, and a long
 etcetera.

 Remember, the RS-232 communication scheme is:


      DTE <--- DCE === DCE ---> DTE


 If you want to  link two DTE together, you must 'simulate' a DCE;
 that's what a Null Modem Cable is for.  It's called 'Null' because it
 (the modem) does not actually exist, and 'Modem' because it acts like
 if there was one.  To build a Null Modem Cable for the 48, assuming
 that you already have a regular cable, you'll need two MALE RS-232C
 connectors, at least one of which must be a DB-9 (9-pin), and a short
 piece of mouse cable or similar (some 3 inches should do) (If you
 don't have a regular cable, I recommend that you get one).  The wiring
 must be as shown here:


               CONNECTOR 'A'                             CONNECTOR 'B'
                                                pin#:      3   2   7     (DB-25)
      pin#:      2   3   5                      pin#:      2   3   5     (DB-9)
      name:     TX  RX  GND                     name:     TX  RX  GND
                 |   |   |                                 |   |   |
                 |   |   |                                 |   |   |
                 |   |   +---------------------------------|---|---+
                 |   |                                     |   |     ( <<< and
                 |   +------------------>>>----------------+   |      >>> show
                 |                                             |  direction of
                 +----------------------<<<--------------------+          data )


 The pin number should be embossed near the pin itself in the
 connector.

 Once the physical part is done, which in most cases will be the most
 critical, you're ready to try out your brand-new, state-of-the-art,
 $2.25 null modem cable.  Plug it between your regular HP48 cable and
 your modem, turn the modem on (please don't forget this part :), and
 on the 48 type in:


      [RightShift]+[""] [alpha] [alpha] AT [ENTER]
      13 [LeftShift]+[CHARS] [CHR] [+]


 In stack level 1 you should have (# is a little black square):


      1: "AT#"


 Now type:


      [LeftShift]+[I/O] [NXT] [SERIAL] [XMIT] [BUFLEN] [DROP] [SRECV]


 you should get:


      2: "AT###OK##"
      1: 1


 If this test goes wrong, try two or three more times.  If it still
 fails, check your cable(s), check that the 48 can transmit and receive
 to/from the PC, do the same with your modem.  And when everything else
 has failed anyway, connect your modem to the PC, crank up a terminal
 program (as Terminal / Hyperterminal, or Kermit's 'Connect' command),
 and type:


      AT&D0 [ENTER]


 the modem should respond:


      OK


 This tells the modem to ignore the DTR signal from the host, which the
 48 can't supply.  Try again with the calculator, if it works, go back
 to the terminal and type:

      AT&W0&Y0 [ENTER]


 to save the current modem configuration as default.  If it has not
 worked so far, I can't help you.

 Assuming you've got it to work, now all you have to do is learn a few
 modem commands to dial and, possibily, hang up.  In general, modem
 commands start with the two-character sequence 'AT' (no quotes) and
 end with a single <CR> character (dec 13), <LF> is optional.

 To dial a number use:


      ATDT12345<CR>


 where 12345 should be replaced by the actual number.  For example:


      [RightShift]+[""] [alpha] [alpha] ATDT0800890011 [ENTER]
      13 [LeftShift]+[CHARS] [CHR] [+] [LeftShift]+[I/O] [NXT] [SERIAL] [XMIT]


 dials the AT&T Direct access number for the UK.

 If your line is not connected to a digital switchboard, you may need
 to dial by pulses, then you should use instead:


      ATDP12345<CR>


 Next thing you'll probably ask is: 'How do I know that I'm connected?'

 If the modem has successfully established a connection, it should
 respond in most cases with a message like:


      CONNECT 9600/V34/LAPM/V42BIS/9600:TX/9600:RX


 or simply "1" if its not in the default verbose mode. Also, if the
 modem has a 'CD' indicator, it'll usually light up.  To find out via
 the calculator whether it's connected or a problem has occurred, use
 the following keystrokes:


      ( [LeftShift]+[I/O] [NXT] [SERIAL] )
      [BUFLEN] [DROP] [SRECV]

 repeatedly until a non-empty string appears in level 2.  Some common
 messages are:


      verbose:         non-verbose:

      CONNECT                    1
      NO CARRIER                 3
      ERROR                      4
      NO DIALTONE                6
      BUSY                       7
      NO ANSWER                  8
      DELAYED                   24


 Once you get the CONNECT message, you're ready to send any data you
 want to the remote host as you'd usually do.  I personally use Kermit
 this way when I'm not in the office or at home.

 Finally, when you're done you'll want to hang up the line.  The
 simplest way is turn the modem off, which I recommend.  But if you
 want to instruct the modem to hang up, the process usually is:

 (wait at least 1 sec without sending any data)


      [RightShift]+[""] [alpha] [alpha] +++ [ENTER]
      [LeftShift]+[I/O] [NXT] [SERIAL] [XMIT]


 (wait at least 1 sec without sending any data)


      [RightShift]+[""] [alpha] [alpha] ATH [ENTER]
      13 [LeftShift]+[CHARS] [CHR] [+] [LeftShift]+[I/O] [NXT] [SERIAL] [XMIT]


 Note, however, that this, as most of what I have said here about modem
 commands, might vary depending on each modem's particular brand, model
 and configuration.  You may need to read your modem's manual for more
 details.

 Disclaimer: As you'd expect, I take no responsibility for anything you
 may break, twist, cut, slice, burn, hurt, or otherwise damage while
 following these instructions.


 12.3.  Additional Information on the HP48 and RS-232

 From: John Meyers

 You can't connect the HP48 to anything else until you have first
 plugged in its cable, which finally brings the HP48's serial
 connections out to a DB9 connector.  At that point, the HP48,
 including its attached cable, is clearly configured as DCE (the same
 as a modem), so you need a "crossover" (such as a "null-modem
 adapter") to connect the HP48 to a modem.
 12.4.  Using Non-HP RAM Cards

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

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


 From [email protected] Fri Mar  1 17:00:00 1991
 From: [email protected] (Steve Harper)
 Date: Thu, 10 May 1990 22:46:09 GMT
 Subject: RE: HP48 SX Memory Card Pricing
 Organization: Hewlett-Packard Co., Corvallis, OR, USA


 There has been a substantial amount of comment regarding the memory
 cards for the HP48 SX 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 I/O 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 HP48
 SX.  Other memory cards exist which are mechanically compatible with
 the HP48 S, but these cards cannot be relied upon to work electrically
 in the calculator.  The HP48 SX 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 [email protected] Fri Mar  1 17:00:00 1991
 From: [email protected] (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-HP48 SX
 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-HP48 SX 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 HP48 SX 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 HP48 SX 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 HP48 SX cards are
 not at all out of line.

 Steve "I claim all disclaimers..."


 From [email protected] Fri Mar  1 17:00:00 1991
 From: [email protected] (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 specified to be 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 through 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


 12.5.  Where can one obtain third party RAM cards?

 If you decide you want to look into the non-mainstream alternatives
 for RAM cards, you might like to check the following URLs:


 o  <http://www.cynox.de/>

 o  <http://stolte-edv.com/de/>

 o  <http://www.cyberline.de/kkgbr/>

 o  <http://www.Digitalis.de/>

 o  <http://home.t-online.de/home/FFFFF/>

 o  <http://www.geocities.com/Eureka/Enterprises/3190/>



-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.0i for non-commercial use
Charset: noconv

iQA/AwUBNz8oQOhzXOws+qC7EQKLNACfdCHbhGSpsjKRoxJB1FlyIgTmU1MAn37G
3ET/SX5Luix7oTUtkKnLB89p
=qFFu
-----END PGP SIGNATURE-----