Luc Pauwels

HP28S Memory Map

Dave Kaffine

NOTE: I don't have access to the news, so I'm having a friend post this for me. Please send any responses or questions to the address below, not to any address you may find in the header.

Here is a partial memory map for the HP-28S. It starts at the bottom of RAM, and continues to the beginning of user variables at the top of RAM, filling in details for everything I've figured out so far. In the map, lower addresses are toward the right and toward the top (because that's the way things look when I use my routines to display a screenful of data). Any specific ROM addresses shown are for version 2BB.

I hope my format is comprehensible. If anyone can fill in any of the gaps, or point out corrections, please post!

    Dave Kaffine            davek01%cs@ncr-fc.ftcollins.ncr.com
                       or   kaffine_d%cubldr@vaxf.colorado.edu

Fixed location system storage:

   F   E   D   C   B   A   9   8   7   6   5   4   3   2   1   0
 -----------------------------------------------------------------
     |   48-bit timer value (updated each minute)    |  KEYMASK  |   C0000
 -----------------------------------------------------------------
   register by interrupt service routine     | ? | CALIB. FACTOR     C0010
 -----------------------------------------------------------------
   register by interrupt service routine     |  Storage for D        C0020
 -----------------------------------------------------------------
   keys in buffer        |K2 |K1 |  ???  | ? |  Storage for B        C0030
 -----------------------------------------------------------------
   keystrokes.  K2 and K1 are pointers to beginning and end of       C0040
 -----------------------------------------------------------------
     |  Start of RSTK    | 15 key buffer (2 nibbles per key) for     C0050
 -----------------------------------------------------------------
 pointer |  Start of stack   |    End of stack   |  End of RSTK      C0060
 -----------------------------------------------------------------
 HOME (??)   |  Menu keys ptr    | Internal loop ptr |Local variable C0070
 -----------------------------------------------------------------
 PC (copy of D0) | Ptr to HOME (??)  | Ptr to cur. dir   | Ptr to    C0080
 -----------------------------------------------------------------
 |  LAST arg2 ptr    |  LAST arg1 ptr    |      Note 1       | RPL   C0090
 -----------------------------------------------------------------
     |      Note 3       |      Note 2       |  LAST arg3 ptr    |   C00A0
 -----------------------------------------------------------------
  3 ptr  |  CMD line 2 ptr   |  CMD line 1 ptr   |       ?????       C00B0
 -----------------------------------------------------------------
   Note 5    |      Note 4       |  CMD line 4 ptr   |  CMD line     C00C0
 -----------------------------------------------------------------
  Free nibs / 5  |      D0000        |  Custom menu ptr  |           C00D0
 -----------------------------------------------------------------
       flags     |PD |      ?????        |    Last ERRN (?)  |       C00E0
 -----------------------------------------------------------------
 |   |   |      Note 6       |   |   |   |   |   |   | Internal      C00F0
 -----------------------------------------------------------------
 ..1 |  ANN  |   |   |   |   |   |   |   |   |   |   |   |   |   |   C0100
 -----------------------------------------------------------------
 |   |   |   |   User flags 64..                                     C0110
 -----------------------------------------------------------------
 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   C0120
 -----------------------------------------------------------------
 |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   C0130
 -----------------------------------------------------------------
 |   |   |   |   |           |   Last ERRN (?)   | L |   |   |   |   C0140
 -----------------------------------------------------------------
 RPL |   | ? |P2 |P1 |T1 | Menu3 |      Menu2        | Menu1 |   |   C0150
 -----------------------------------------------------------------
 |   |   |   |   |   |   |   |      Note 7       | Ptr to current    C0160
 -----------------------------------------------------------------

 Where:

   CALIB FACTOR - Calibration factor that relates CPU clock to
                  real-time.  Calculated by mcode routine at 01143
   Note 1 - Contains RPL location to resume after garbage collection (?)
   Note 2 - Points to a 336 bit binary integer.  This integer is normally
            the first object on the heap, at location C0184, but (?) if
            its value has changed since the last garbage collection, it may
            be elsewhere (pure conjecture)
   Note 3 - This seems to point to a list { {} {} } which is located
            at the boundary between objects allocated before/after the
            last garbage collection
   Note 4 - This seems to always contain 04075 - a pointer to a 0-bit
            binary integer in ROM
   Note 5 - This seems to always contain 04093 - a pointer to an empty
            algebraic '' in ROM
   PD    -  Print Display:  This nibble is set to 1 when the ON-L key
            combination is pressed, and is reset to 0 when the display
            has finished printing.
   Note 6 - This contains the number of nibbles on the stack (5 per level)
            excluding the arguments for the current function
   ANN    - Current status of the annunciators
   L      - Number of arguments that were saved for recall by LAST
   Menu1  - The menu currently display, 00 if cursor keys active
   Menu2  - Offset into current menu (multiple of 6 in normal operation)
   Menu3  - Menu that is current (not necessarily displayed), 00 if none
            uses same numbering as MENU command
   T1     - 10 minute counter for turning off inactive calculator
   P1     - # of lines currently in printer's buffer (8 max)
   P2     - Counter for print timing: counts 3 2 1 0, decrements P1
   Note 7 - Saves the m-code address the garbage collection routine returns
            to.

Complete memory map:

The structure of the rest of memory follows. I have tried to indicate the locations that various system pointers point to by giving the address of the system pointer and an arrow of sorts. Also, the standard uses of some of the CPU registers are indicated (e.g. B(A) ---> The 5-nibble A-field of register B points to the RPL return stack)


                                           <---------  increasing addresses
                                                                      |
-----------------------------------------------------                 |
   Fixed system         |                           | : C0000         |
    storage             |   See above description   |                 v
                        |                           |
-----------------------------------------------------
          |                                            /------------[C00A5]
  HEAP    |    00064 .. 336-bit binary .. 00059  02A70  U : C0183
          |
          |--------------------    SSSSS      Object    U
          Objects in use at   |          ...
          time of last garbage|          ...
          collection.  SSSSS  |    /----SSSSS = size----\
          is the size in nibs |    SSSSS      Object    U
          of entire object    |
           --------------------                        /----[C00AA]
   Divider |       0001A   02F90   04089  04089  02A96  U
           --------------------
          Objects allocated   |    SSSSS      Object    U
          since last GC.  The |          ...
          U nibble is a usage |          ...
          flag for GC routine |    SSSSS      Object    U
-------------------------------
                     |
  RPL return stack   |    {oldest return address}   00000 <--[C005A]
  (RSTK)             |      rrrrr   rrrrr   rrrrr   rrrrr
                     |       {most recent return address}
                     |       \-------------------------------[C005F], B(A)
                     | grows|
----------------------      |
                     |      |
   Free memory       |      v         ...
  5 * D(A)           |                ...
  5 * [C00DC]        |      ^         ...
                     |      |
----------------------      |
                     | grows|
   Data stack        |           Level3   Level2   Level1 <--[C0064], D1
                     |                  ...
  5 nibble pointer   |            00000   {Highest Level}
  for each level     |           \---------------------------[C0069]
----------------------
                     |
      ???            |               ...
                     |
----------------------
 Local variables  |  /--------SSSSS = frame size--------\
                  |  binding ...  binding   TTTTT   SSSSS <--[C006E]
 Frame types:     |                           \--------------frame type
  0 - Normal      |                 ...
  1 - ?????       |  binding ...  binding   TTTTT   SSSSS
  2 - Stack save  -----------------------------
 Bindings are all ten nibbles, of the form    |     00000
    ddddd  nnnnn   : nnnnn points to name     |
                     ddddd points to value    |
   (in special cases, ddddd is value)         |
 Sorry, but more details will have to wait    |
 for a separate article.                      |
-----------------------------------------------
  Internal loop records  |
  (User loops are not    |  RecordN  ...  Record1   RRRRR <--[C0073]
  handled here)          -----------------
  RRRRR = number of records              |
  Record =  fffff    ccccc    00000      |
            final    current  (???)      |
            value    value               |
------------------------------------------
   Menu Key data structure       |
                                 |                   NN W <--[C0078]
   W = flags (indicates which    |    Name3  Name2  Name1
       sections are available)   |    Name6  Name5  Name4
       Structure to right        |
       assumes W = C             |           04075  0407F
   NN = number of entries per    |
        section                  |
   Namex = Pointer to string, or |    Func3  Func2  Func1
           pointer to function   |    Func6  Func5  Func4
           that creates string   |
           for menu key x        |    00000  18F25  18F75
   0407F-> ""  04075-> " "       -----------------------
   Funcx = Pointer to execution routine for menu key x |
   18F25->???  18F75->???                              |
-----------------------------------------------------------
                    |  object ...                   02AB8 | : HOME <-[C007D],
     User           |                                     |        <-[C0087]
   variables        |                ... 02AB8 ...        |
                    |                         \---------------[C0082]
  (Future article)  |            ... object ...           |   current dir
       (???)        |                                     |
-----------------------------------------------------------
                                                            : D0000<-[C00D7]