Date: 29 Mar 90 22:13:23 GMT
From: alonzo@microsoft.UUCP  (Alonzo GARIEPY)
Organization: Microsoft Corp., Redmond WA
Subject: Re: Hidden types on 28C/28S/48SX
Message-Id: <53863@microsoft.UUCP>
References: <8921@boring.cwi.nl>
Sender: handhelds-request@csl.sri.com
To: handhelds@csl.sri.com

In article <8921@boring.cwi.nl> jurjen@lijster.cwi.nl (Jurjen N.E. Bos) writes:
> Do you guys realized how many types there are that you can't access
> from the outside in the 28/48?

There are 24, 27 or 28 types, depending on how you count them. The
following 10 or 11 are generally inaccessible.  I suppose it would
be possible to create new object types according to the scheme used
for the built-in ones.
                                Example
Address Type    Name            Display                 Syntax
------- ----    ----            -------                 ------
02e92   14      XLIB name       XLIB 2 261              none
02b40   16      Library         Library                 none
02b62   17      Backup obj      Backup Object           none
02911   20      Address         <28FCh>                 none
02955   21      Long Real       Long Real               none
0299d   22      Long Complex    Long Complex            none
02a0a   23      Linked Array    Linked Array            none
029bf   24      Character       Character               none
02dcc   25      Code            Code                    none
02b88   26      Library Data    Library Data            none
other   27      External        External                none

Any detailed information about the structure and use of the above
objects will be much appreciated.  Address, Long Real, Long Complex,
and Code have been explained elsewhere.  XLIB name is the same as
Command and Function.  External includes any object which is not
recognized (not built-in).

Alonzo Gariepy
alonzo@microsoft

Date: 30 May 90 10:31:17 GMT
From: alonzo@microsoft.UUCP  (Alonzo GARIEPY)
Organization: Microsoft Corp., Redmond WA
Subject: Re: HP48 Machine Code
Message-Id: <54937@microsoft.UUCP>
References: <MaMa1yy00UhBQ0jWBD@andrew.cmu.edu>
Sender: handhelds-request@csl.sri.com
To: handhelds@csl.sri.com

In article <MaMa1yy00UhBQ0jWBD@andrew.cmu.edu> paul+@andrew.cmu.edu writes:
> From Alonzo Gariepy's HP28-S Machine Code User's Guide:
> > ...
> On my 48, when I follow the above steps, I get the message:
>                      "Try to Recover Memory?"
> What am I doing wrong?  Do these HP28 procedures even apply to the 48?

No.  That is why I called it "HP28-S Machine Code User's Guide".  Virtually
all addresses have changed in the 48 and many details of internal operation
are different.

Your best bet with the HP 48, is to enter hex by hand using the debugger or
to create binary files on a PC and download them.  Both of these approaches
require some understanding of the appropriate formats.  Here is a technique
you can use if you have a way to patch binary files on your PC.

1.  Create your program using a dummy string where you want the machine
    code object to go.  For example, if there will be 35 or 36 nibbles
    of machine code in your machine code object, make the dummy string
    18 characters long: << blah blah "ABCDEFGHIJKLMNOPQR" blah blah >>

2.  Save the dummy program to your PC using Kermit in Binary mode.

3.  Patch the dummy string object in the binary file into a code object.
        a.  remember that the nibbles in each byte are reversed on the PC
        b.  the string begins with C2A20 followed by a five nibble length
        c.  change the prolog from C2A20 (string) to CCD20 (code)
        d.  don't change the the five nibbles following the prolog
        e.  change the dummy string contents to machine code
        f.  remember that the nibbles in each byte are reversed on the PC!

4.  Load the patched file back into the 48 using Kermit

Backup your 48 during experimentation.

Here is a reposting of some pertinent information on the 48 that some of
the newcomers will not have seen.  It gives some interesting addresses and
instructions for using the debugger, if you choose to go that route.  Some
information has, no doubt, been superceded by more recent discoveries.


Introduction to HP 48SX Internals (version 0)   (C) 1990, Alonzo Gariepy
========================================================================

Following is some information that may be useful if your interests
run to machine language.  Misapplication of the information contained
in this document may result in corruption of memory and even damage
to the hardware.  Backup the contents of your HP 48SX if necessary.

                        Objects
                        =======


Address Type    Name            Example Display         Syntax (if different)
-----------------------------------------------------------------------------
02933   0       Real            3.14159265359
02977   1       Complex         (1,2)
02a2c   2       String          "hello" or C$ 5 hello
029e8   3       Real Array      [1 2 3]
029e8   4       Complex Array   [(1,0) (2,2)]
02a74   5       List            { DUP 3 '3/4' }
02e48   6       Global Name     'PEEK'
02e6d   7       Local Name      't'
02d9d   8       Program         << 440 .5 BEEP >>
02ab8   9       Algebraic obj   'SIN(X)'
02a4e   10      Binary Integer  # 454432h
02b1e   11      Graphics obj    Graphic 4 x 4           GROB 4 4 70607050
02afc   12      Tagged  obj     root1: 2.6              :root1: 2.6
02ada   13      Unit obj        1_lyr                   1_lyr
02e92   14      XLIB name       XLIB 2 261              none
02a96   15      Directory       DIR Avog 6.02E23 END
02b40   16      Library         Library                 none
02b62   17      Backup obj      Backup Object           none
02e92   18      Function        SIN
02e92   19      Command         SWAP
02911   20      Address         <28FCh>                 none
02955   21      Long Real       Long Real               none
0299d   22      Long Complex    Long Complex            none
02a0a   23      Linked Array    Linked Array            none
029bf   24      Character       Character               none
02dcc   25      Code            Code                    none
02b88   26      Library Data    Library Data            none
other   27      External        External                none

        *       *       *       *       *       *

                        Memory Layout
                        =============

00000-0FFFF     ROM (and registers for the display controller, I/O, and timers)
10000-6FFFF     ROM
70000-7FFFF     User/Display RAM (overlaid on Font/Strings ROM)
80000-BFFFF     128k for plug-in
C0000-FFFFF     128k for plug-in
F0000-FFFFF     User/Display RAM (when 70000-7FFFF is used for Font/Strings ROM)

                        Memory Scanner
                        ==============

There is a built-in memory scan mode that lets you examine and modify
memory.  This is a convenient way to enter machine code programs into
the calculator, to examine memory, and to download memory to a PC via
the serial cable.

In the key descriptions below, I have referred to several of the keys
by their orange labels because the title on the key is a non-ascii symbol.
None of these keys should be orange shifted, however.

Back up your calculator if necessary.  To get into the memory scanner,
press [ON][D] together, then [DROP].  You are now in memory scan mode.
Following is a list of keys and the functions they perform in scan mode.
Most keys will repeat if held down for a moment.  All numbers are in hex.

[DROP]          refresh
[LIBRARY]       increment by 1000
[REVIEW]        decrement by 1000
[/]             decrement by  100
[*]             increment by  100
[-]             decrement by    1
[+]             increment by    1
[ENTER]         goto address 00100 (?display controller?)
[+/-]           goto address F000A
[1/X]           goto address F0A8C or F1210 (display, see below)
[EEX]           goto address 80000 (?port 1?)
[DEL]           goto address C0000 (?port 2?)
[0]-[F]         enter corresponding nibble at address, increment by 1
[.]             transmit 16 nibbles to IR and serial, increment by 10
[SPC]           dump 1000h memory locations to the serial port (9600 baud)
[EVAL]          execute at address

When you first press [DROP] to enter scan mode, the address is
705D9.  Pressing [EVAL] at this address displays:

                Version HP-48A Copyright HP 1989.

The most interesting thing about scan mode is that the memory layout
is different than in normal operation.  The 32k of user/display RAM
is moved from 70000 to F0000 so that you can see the ROM that is normally
hidden underneath.  In normal operation, the address space at 70000 is
shared between this ROM and display RAM.  The hidden ROM is used for code
and data related to I/O, such as strings and font bitmaps, as well as for
diagnostic functions, such as the self tests and scan mode.

In normal operation, whenever you need access to the hidden ROM, you have
to perform some magic to switch the address space.  This must be done in
the few cycles between display refresh.

F0A8C and F1210 are the addresses of the second line of the bitmap,
depending on whether you were looking at the stack or plot displays
when you entered scan mode.  If you press one of the keys [0]-[F] after
pressing [1/X], you can see the effect of writing each nibble into the
display bitmap.  You can draw on the display this way.

        *       *       *       *       *       *

The first variable in the HOME directory is stored ending at #7FFFAh,
unlike the HP28, where this variable ended at #CFFFF.  Address #7FFFAh
appears at FFFFA in the memory scanner.  Once you have use libraries
or ports, you can no longer easily find the first variable's location!!

I believe that coma mode is entered with [ON][SPC].  When you press on,
much of the calculator will have been reinitialized.  One undocumented
command is WSLOG, which gives you a log of warm starts.  I cannot find
any command strings with my FIND program.  They are most probably stored
in the hidden ROM.

        *       *       *       *       *       *

        Easy Machine Code: PEEK, POKE, and FIND
        =======================================

The obvious way to enter machine code is with scan mode.  You don't
need to waste time with hex string converters and other silliness.
Store the following PEEK program template in the first variable of the
HOME directory.

        << RCWS SWAP 64 STWS #0h OR SWAP STWS
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >>

        HOME 'PEEK' DUP PURGE STO

Now go into scan mode and find the start of the string object:

        [ON][D], [DROP], [ENTER], [/], hold down [-] until you get to FFFB3.

Now change the object type (C2A20) to

        CCD20

Note that the length is 93000 -> 39 hex = 57 decimal = 26*2 + 5.

Move forward to address FFFBD using the [+] key, and enter the machine
code into the string.  Remember, don't type past FFFF0.

        13210314313016914613615671301691547113132142164808C0

Press [ON][C] together to get back to the calculator.

You can now checksum PEEK with the BYTES command.  The result should
be #8568h.  This is a binary checksum, so it includes the contents of
the Code object, and is independent of display modes.

Store the following POKE program template in the first variable of the
HOME directory.

        << SWAP OVER #0h AND OR SWAP
           "123456789 123456789 123456789 123456789 123" >>

        HOME 'POKE' DUP PURGE STO

Go into scan mode, change type of the string to a Code object as above,
and enter the machine code into the string.  This string is longer, so
you have to go back further to get to the beginning.  The machine code
still ends at the same address.  Be sure you understand the format of
string and code objects so that you don't make a fatal mistake.

        13210314317414717413416414613618513680D0164
        1561E71301691421301541113132142E720164808C0

Press [ON][C] together to get back to the calculator.

You can now checksum POKE with the BYTES command.  The result should
be #725D.

        *       *       *       *       *       *

                Mini RAM Map
                ============

The address of the end of the stack, normally stored in register D1, is
saved at #70579.  To examine the stack, first go to F0579 in scan mode:

        [1/X], [/] 5 times, [-] 19 times

The address of the end of the stack is displayed in reverse.  If your
display says

        F0579:9F8E7309E7...

then the stack starts at 7E903 and ends at 7E8F9.  There are obviously
two objects on the stack.  By moving to FE8F9, you can see the stack
itself, and the two addresses it contains.  Here is a list of interesting
locations (the initial 7 is mapped to an F in scan mode):

Real Address    Description

#704EAh         key buffer
#70579h         top (end) of stack
#7057Eh         bottom (start) of stack
#70583h         ?? local variables ??
#70588h         ?? internal loop ??
#7058Dh         ?? menu keys ??
#70592h         HOME directory
#70597h         end of HOME directory (7FFFB)
                        (points to five 0 nibbles, probably used for ATTACH)
#7059Ch         current directory

#70713h         graphic obj used for composing lines of the stack.  There
                is just enough memory reserved for a 19 character bitmap.
#70844h         graphic obj used for menu display: 8 by 131
#70968h         graphic obj used for the rest of the screen: 56 by 131
#710ECh         graphic obj used for plot display: variable size

The questionable values are inferred from the HP-28 RAM map by Dave Kaffine.
There are obviously many similarities.  You can use the real addresses at
#7xxxxh employing PEEK.

        *       *       *       *       *       *

                Keyboard Buffer and Scan Codes
                ==============================

The keyboard buffer works just like in the 28.  The scan codes run in
sequence: #01h for A, #02h for B, ..., #30h for SPC, #31h for +.  There
are 49 keys and the scan codes run from 1 to 49 (#01h to #31h), with
four exceptions.  The key codes #1Eh, #23h, #28h, and #2Dh are not used.
The first three are replaced with #80h for AlphaShift, #40 for LeftShift,
and #C0 for RightShift, and the ON/ATTN/CONT/OFF key has no scan code.

When a key is pressed, the interrupt handler puts the scan code into
the next position of the keyboard buffer, except for the ON key which
gets special treatment.  I assume that the shift values can be OR'd
with the scan value to get more compact key codes.  Obviously one can
not apply mutliple shifts to the same character this way.

        *       *       *       *       *       *

                Command List and SYSEVAL Map
                ============================

Here are all the commands in the HP48 with their command number and
address.  This list serves as a map for navigating through the ROM.
Each address is the beginning of an RPL routine.  Note how short these
routines are.  The 48 has been set up so that command addresses never
change.  Disassembling the commands will lead the way to the underlying
RPL routines stored elsewhere in ROM and eventually a complete SYSEVAL
map.

On the 48, for the first time, programming with these faster SYSEVAL
addresses is easy (it can be done on the PC and downloaded).  Of course,
that defeats the whole purpose of having the standardized ROM addresses
below.  A utility for speeding up user programs could automatically
expand commands into the underlying RPL.  Once a program is tested, some
of the built in error checking code can be circumvented.  This is kind
of like a compiler since your source would be user code.

Addr   XLIB # Name         Addr   XLIB # Name         Addr   XLIB # Name
----------------------     ----------------------     ----------------------
1957B  000002 ASR          1C3CF  089002 GRAD         1FC7F  116002 DUPN
1959B  001002 RL           1C3EA  08A002 FIX          1FC9A  117002 PICK
195BB  002002 RLB          1C41E  08B002 SCI          1FCB5  118002 ROLL
195DB  003002 RR           1C452  08C002 ENG          1FCD0  119002 ROLLD
195FB  004002 RRB          1C486  08D002 STD          1FCEB  11A002 CLEAR
1961B  005002 SL           1C4A1  08E002 FS?C         1FD0B  11B002 STOsigma
1963B  006002 SLB          1C520  08F002 FC?C         1FD2B  11C002 CLsigma
1965B  007002 SR           1C559  090002 BIN          1FD46  11D002 RCLsigma
1967B  008002 SRB          1C574  091002 DEC          1FD61  11E002 sigma+
1969B  009002 R->B         1C58F  092002 HEX          1FD8B  11F002 sigma-
196BB  00A002 B->R         1C5AA  093002 OCT          1FDA6  120002 Nsigma
196DB  00B002 CONVERT      1C5C5  094002 STWS         1FDC1  121002 CORR
1971B  00C002 UVAL         1C5FE  095002 RCWS         1FDDC  122002 COV
1974F  00D002 UNIT         1C619  096002 RCLF         1FDF7  123002 sigmaX
19771  00E002 UBASE        1C67F  097002 STOF         1FE12  124002 sigmaY
197A5  00F002 UFACT        1C78C  098002 ->LIST       1FE2D  125002 sigmaX^2
197F7  010002 TIME         1C79E  099002 R->C         1FE48  126002 sigmaY^2
19812  011002 DATE         1C7CA  09A002 RE           1FE63  127002 sigmaX*Y
1982D  012002 TICKS        1C819  09B002 IM           1FE7E  128002 MAXsigma
19848  013002 WSLOG        1C85C  09C002 SUB          1FE99  129002 MEAN
19863  014002 ACKALL       1C8EA  09D002 REPL         1FEB4  12A002 MINsigma
1987E  015002 ACK          1C95A  09E002 LIST->       1FECF  12B002 SDEV
1989E  016002 ->DATE       1C98E  09F002 C->R         1FEEA  12C002 TOT
198BE  017002 ->TIME       1C9B8  0A0002 SIZE         1FF05  12D002 VAR
198DE  018002 CLKADJ       1CAB4  0A1002 POS          1FF20  12E002 LR
198FE  019002 STOALRM      1CB0B  0A2002 ->STR        1FF7A  12F002 PREDV
19928  01A002 RCLALRM      1CB26  0A3002 STR->        1FF9A  130002 PREDY
19948  01B002 FNDALRM      1CB46  0A4002 NUM          1FFBA  131002 PREDX
19972  01C002 DELALRM      1CB66  0A5002 CHR          1FFDA  132002 XCOL
19992  01D002 TSTR         1CB86  0A6002 TYPE         1FFFA  133002 YCOL
199B2  01E002 DDAYS        1CE28  0A7002 VTYPE        2001A  134002 UTPC
199D2  01F002 DATE+        1CEE3  0A8002 EQ->         2003A  135002 UTPN
1A105  020002 CRDIR        1CF7B  0A9002 OBJ->        2005A  136002 UTPF
1A125  021002 PATH         1D009  0AA002 ->ARRAY      2007A  137002 UTPT
1A140  022002 HOME         1D092  0AB002 ARRY->       2009A  138002 COLsigma
1A15B  023002 UPDIR        1D0DE  0AC002 RDM          200C4  139002 SCLsigma
1A194  024002 VARS         1D186  0AD002 CON          200F3  13A002 sigmaLINE
1A1AF  025002 TVARS        1D2DC  0AE002 IDN          2010E  13B003 BINS
1A1D9  026002 BYTES        1D392  0AF002 TRN          20133  13C002 BARPLOT
1A2BC  027002 NEWOB        1D407  0B0002 PUT          20167  13D002 HISTPLT
1A303  028002 KILL         1D5DF  0B1002 PUTI         2018C  13E002 SCTRPLT
1A31E  029002 OFF          1D7C6  0B2002 GET          201B1  13F002 LINFIT
1A339  02A002 DOERR        1D8C7  0B3002 GETI         201D6  140002 LOGFIT
1A36D  02B002 ERR0         1DD06  0B4002 V->          201FB  141002 EXPFIT
1A388  02C002 ERRN         1DE66  0B5002 ->V2         20220  142002 PWRFIT
1A3A3  02D002 ERRM         1DEC2  0B6002 ->V3         2025E  143002 BESTFIT
1A3BE  02E002 EVAL         1E04A  0B7002 INDEP        202CE  144002 SINV
1A3FE  02F002 IFTE         1E07E  0B8002 PMIN         2034D  145002 SNEG
1A4C0  030002 IFT          1E09E  0B9002 PMAX         203CC  146002 SCONJ
1A52E  031002 SYSEVAL      1E0BE  0BA002 AXES         2044B  147002 STO+
1A584  032002 DISP         1E0E8  0BB002 CENTR        20538  148002 STO-
1A5A4  033002 FREEZE       1E126  0BC002 RES          2060C  149002 STO/
1A5C4  034002 BEEP         1E150  0BD002 *H           20753  14A002 STO*
1A5E4  035002 ->NUM        1E170  0BE002 *W           208F4  14B002 INCR
1A604  036002 LASTARG      1E190  0BF002 DRAW         209AA  14C002 DECR
1A71F  037002 WAIT         1E1AB  0C0002 AUTO         20A15  14D002 COLCT
1A858  038002 CLLCD        1E1C6  0C1002 DRAX         20A49  14E002 EXPAN
1A873  039002 KEY          1E1E1  0C2002 SCALE        20A7D  14F002 RULES
1A8BB  03A002 CONT         1E201  0C3002 PDIM         20A93  150002 ISOL
1A8D8  03B002 =            1E22B  0C4002 DEPND        20AB3  151002 QUAD
1A995  03C002 NEG          1E25F  0C5002 ERASE        20AD3  152002 SHOW
1AA1F  03D002 ABS          1E27A  0C6002 PX->C        20B20  153002 TAYLR
1AA6E  03E002 CONJ         1E29A  0C7002 C->PX        20B40  154002 RCL
1AABD  03F002 pi           1E2BA  0C8002 GRAPH        20CCD  155002 STO
1AADF  040002 MAXR         1E2D5  0C9002 LABEL        20D65  156002 DEFINE
1AB01  041002 MINR         1E2F0  0CA002 PVIEW        20EFE  157002 PURGE
1AB23  042002 e            1E31A  0CB002 PIXON        20FAA  158002 MEM
1AB45  043002 i            1E344  0CC002 PIXOFF       20FD9  159002 ORDER
1AB67  044002 +            1E36E  0CD002 PIX?         210FC  15A002 CLVAR
1ACD7  045002 +            1E398  0CE002 LINE         2115D  15B002 TMENU
1AD09  046002 -            1E3C2  0CF002 TLINE        21196  15C002 MENU
1ADEE  047002 *            1E3EC  0D0002 BOX          211E1  15D002 RCLMENU
1AF05  048002 /            1E416  0D1002 BLANK        211FC  15E002 PVARS
1B02D  049002 ^            1E436  0D2002 PICT         2123A  15F002 PGDIR
1B185  04A002 XROOT        1E456  0D3002 GOR          2125A  160002 ARCHIVE
1B1C4  04B002 XROOT        1E4E4  0D4002 GXOR         2133C  161002 RESTORE
1B278  04C002 INV          1E572  0D5002 LCD->        2137F  162003 MERGE
1B2DB  04D002 ARG          1E58D  0D6002 ->LCD        213D1  163002 FREE
1B32A  04E002 sigmaN       1E5AD  0D7002 ->GROB       2142D  164002 LIBS
1B374  04F002 sqrt         1E5D2  0D8002 ARC          21448  165002 ATTACH
1B426  050002 SQ           1E606  0D9002 TEXT         2147C  166002 DETACH
1B4AC  051002 SIN          1E621  0DA002 XRNG         21E75  167002 XMIT
1B505  052002 COS          1E641  0DB002 YRNG         21E95  168002 SRECV
1B55E  053002 TAN          1E661  0DC002 FUNCTN       21EB5  169002 OPENIO
1B5B7  054002 SINH         1E681  0DD002 CONIC        21ED5  16A002 CLOSEIO
1B606  055002 COSH         1E6A1  0DE002 POLAR        21EF0  16B002 SEND
1B655  056002 TANH         1E6C1  0DF002 PARMTRC      21F24  16C002 KGET
1B6A4  057002 ASIN         1E6E1  0E0002 TRUTH        21F62  16D002 RECN
1B72F  058002 ACOS         1E701  0E1002 SCATTER      21F96  16E002 RECV
1B79C  059002 ATAN         1E721  0E2002 HISTGRM      21FB6  16F002 FINISH
1B7EB  05A002 ASINH        1E741  0E3002 BAR          21FD1  170002 SERVER
1B830  05B002 ACOSH        1E761  0E4002 SAME         21FEC  171002 CKSM
1B8A2  05C002 ATANH        1E783  0E5002 AND          2200C  172002 BAUD
1B905  05D002 EXP          1E809  0E6002 OR           2202C  173002 PARITY
1B94F  05E002 LN           1E88F  0E7002 NOT          2204C  174002 TRANSIO
1B9C6  05F002 LOG          1E8F6  0E8002 XOR          2206C  175002 KERRM
1BA3D  060002 ALOG         1E972  0E9002 ==           22087  176002 BUFLEN
1BA8C  061002 LNP1         1EA9D  0EA002 !=           220A2  177002 STIME
1BAC2  062002 EXPM         1EBBE  0EB002 <            220C2  178002 SBRK
1BB02  063002 !            1EC5D  0EC002 >            220DD  179002 PKT
1BB41  064002 FACT         1ECFC  0ED002 <=           224CA  17A002 INPUT
1BB6D  065002 IP           1ED9B  0EE002 >=           224F4  17B002 ASN
1BBA3  066002 FP           1EE38  0EF002 OLDPRT       22514  17C002 STOKEYS
1BBD9  067002 FLOOR        1EE53  0F0002 PR1          22548  17D002 DELKEYS
1BC0F  068002 CEIL         1EE6E  0F1002 PRSTC        22586  17E002 RCLKEYS
1BC45  069002 XPON         1EE89  0F2002 PRST         225BE  17F002 ->TAG
1BC71  06A002 MAX          1EEA4  0F3002 CR           22633  180002 DTAG
1BCE3  06B002 MIN          1EEBF  0F4002 PRVAR        22EC3  000700 IF
1BD55  06C002 RND          1EF43  0F5002 DELAY        22EFA  001700 THEN
1BDD1  06D002 TRNC         1EF63  0F6002 PRLCD        22FB5  002700 ELSE
1BE4D  06E002 MOD          1EF7E  0F7002 delta        22FD5  003700 END
1BE9C  06F002 MANT         1EFCC  0F8002 delta        22FEB  004700 ->
1BEC8  070002 D->R         1F133  0F9002 RCEQ         23033  005700 WHILE
1BEF4  071002 R->D         1F14E  0FA002 STEQ         2305D  006700 REPEAT
1BF1E  072002 ->HMS        1F16E  0FB002 ROOT         230C3  007700 DO
1BF3E  073002 HMS->        1F1D4  0FC002 integral     230ED  008700 UNTIL
1BF5E  074002 HMS+         1F21D  0FD002 integral     23103  009700 START
1BF7E  075002 HMS-         1F2C9  0FE002 sigma        231A0  00A700 FOR
1BF9E  076002 RNRM         1F354  0FF002 |            2324C  00B700 NEXT
1BFBE  077002 CNRM         1F3ED  100002 |            23380  00C700 STEP
1BFDE  078002 DET          1F500  101002 QUOTE        233DF  00D700 IFERR
1BFFE  079002 DOT          1F55D  102002 APPLY        23472  00E700 HALT
1C007  07D002 %T           1F9C4  107002 ->Q          2349C  00F700
1C01E  07A002 CROSS        1F9E9  108002 ->Qpi        234C1  010700 ->
1C03E  07B002 RSD          1FA59  109002 ^MATCH       235FE  011700 >>
1C060  07C002 %            1FA8D  10A002 vMATCH       2361E  012700 <<
1C149  07E002 %CH          1FAEB  10B002 _            23639  013700 >>
1C1B9  07F002 RAND         1FB5D  10C002 RATIO        23654  014700 '
1C1D4  080002 RDZ          1FB87  10D002 DUP          23679  015700 '
1C1F6  081002 COMB         1FBA2  10E002 DUP2         23694  016700 END
1C236  082002 PERM         1FBBD  10F002 SWAP         236B9  017700 END
1C274  083002 SF           1FBD8  110002 DROP         2371F  018700 THEN
1C2D5  084002 CF           1FBF3  111002 DROP2        2378D  019700 CASE
1C313  085002 FS?          1FC0E  112002 ROT          237A8  01A700 THEN
1C360  086002 FC?          1FC29  113002 OVER         23813  01B700 DIR
1C399  087002 DEG          1FC44  114002 DEPTH        23824  01C700 PROMPT
1C3B4  088002 RAD          1FC64  115002 DROPN

Alonzo Gariepy
alonzo@microsoft

Date: 30 May 90 18:58:26 GMT
From: prestonb@hpcvra.UUCP  (Preston Brown)
Organization: Hewlett-Packard Co., Corvallis, OR, USA
Subject: Re: The hp48sx screen-fade
Message-Id: <25590005@hpcvra.CV.HP.COM>
References: <9909@hydra.gatech.EDU>
Sender: handhelds-request@csl.sri.com
To: handhelds@csl.sri.com

Actually, you are putting the display controller into test mode.  This
is used for hardware testing during the IC manufacturing; its not designed
to be used by the user.  This is not a really good thing to do to your
calculator because it puts a DC bias onto the display.  If you left it like
that for a long time it may dammage your display.

The area from 0100-013F in memory are the hardware control registers
100 - [DON OFF2 OFF1 OFF0]        Display on, bit offset
101 - [CON3 CON2 CON1 CON0]       display contrast control
102 - [VDIG LID TRIM CON4]        display test and high contrast bit.
                     VDIG LID and LTRIM should be left 0.

Preston

Jan Brittenson: RPL constructs
   Could someone who knows, please describe how conditionals, loops,
and CASEs are stored internally? I need it to get SAD 1.02 to
disassemble RPL code. Actually, it already does, but I intend to
supply macros for common RPL constructs to get the indentation
correct.

   Oh, and could someone explain what reals (i.e. 64-bit floating
point words) look like? Things like how the exponent is stored, the
exponent sign, the mantissa sign, etc. I haven't done any thorough
investigation here, and only know vaguely what is what.

   Also, please voice your opinion on the following (PROGRAM and END
are SAD macros, which currently is the only way to define proper
indentation among other things) format:


1cb86   Cmd_TYPE:
1cb86 d9d20    PROGRAM
1cb8b 5aa81      #18aa5
1cb90 d9d20      PROGRAM
1cb95 d9f81        #18f9d
1cb9a 9ff30        Short_1              ; ; #3ff9
1cb9f 4b2a2        Real_0               ; ; #2a2b4
1cba4 30040        Short_2              ; ; #4003
1cba9 9c2a2        Real_1               ; ; #2a2c9
1cbae d0040        Short_3              ; ; #400d
1cbb3 ed2a2        Real_2               ; ; #2a2de
1cbb8 71040        Short_4              ; ; #4017
1cbbd 1bdc1        #1cdb1
1cbc2 12040        Short_5              ; ; #4021
1cbc7 d13a2        Real_5               ; ; #2a31d
1cbcc b2040        Short_6              ; ; #402b
1cbd1 233a2        Real_6               ; ; #2a332
1cbd6 53040        Short_7              ; ; #4035
1cbdb 743a2        Real_7               ; ; #2a347
1cbe0 f3040        Short_8              ; ; #403f
1cbe5 4ddc1        #1cdd4
1cbea 94040        Short_9              ; ; #4049
1cbef 173a2        Real_9               ; ; #2a371
1cbf4 d5040        Short_0bh            ; ; #405d
1cbf9 7e056        Real_10              ; ; #650e7
1cbfe 76040        Short_0ch            ; ; #4067
1cc03 3392010      REAL 1.1E1
      0000000
      0000110
1cc18 17040        Short_0dh            ; ; #4071
1cc1d 3392010      REAL 1.2E1
      0000000
      0000210
1cc32 b7040        Short_0eh            ; ; #407b
1cc37 3392010      REAL 1.3E1
      0000000
      0000310
1cc4c 58040        Short_0fh            ; ; #4085
1cc51 3392010      REAL 1.4E1
      0000000
      0000410
1cc66 52140        Short_1fh            ; ; #4125
1cc6b 3392010      REAL 2.0E1
      0000000
      0000020
1cc80 03b46        Short_2fh            ; ; #64b30
1cc85 3392010      REAL 1.5E1
      0000000
      0000510
1cc9a 11920f3      ADDRESS #3f
      000
1cca4 3392010      REAL 2.1E1
      0000000
      0000120
1ccb9 11920f4      ADDRESS #4f
      000
1ccc3 3392010      REAL 2.2E1
      0000000
      0000220
1ccd8 11920f5      ADDRESS #5f
      000
1cce2 3392010      REAL 2.3E1
      0000000
      0000320
1ccf7 11920f6      ADDRESS #6f
      000
1cd01 3392010      REAL 2.4E1
      0000000
      0000420
1cd16 11920f7      ADDRESS #7f
      000
1cd20 3392010      REAL 2.5E1
      0000000
      0000520
1cd35 e2d46        Short_8fh            ; ; #64d2e
1cd3a 3392010      REAL 1.6E1
      0000000
      0000610
1cd4f 06d46        Short_9fh            ; ; #64d60
1cd54 3392010      REAL 1.7E1
      0000000
      0000710
1cd69 11920fa      ADDRESS #af
      000
1cd73 3392010      REAL 2.6E1
      0000000
      0000620
1cd88 fef30        Short_0              ; ; #3fef
1cd8d 3392010      REAL 2.7E1
      0000000
      0000720
1cda2 b2130      END
1cda7 b9f06      #60f9b
1cdac b2130    END
1cdb1 d9d20    PROGRAM
1cdb6 88130      Dup                    ; ; #3188
1cdbb b3226      #6223b
1cdc0 8da16      #61ad8
1cdc5 3f2a2      Real_3                 ; ; #2a2f3
1cdca 803a2      Real_4                 ; ; #2a308
1cdcf b2130    END
1cdd4 d9d20    PROGRAM
1cdd9 9af16      #61fa9
1cdde da916      Branch_if_true         ; ; #619ad
1cde3 c53a2      Real_8                 ; ; #2a35c
1cde8 d2a62      #26a2d
1cded 39916      Branch_if_false        ; ; #61993
1cdf2 3392010    REAL 1.8E1
      0000000
      0000810
1ce07 3392010    REAL 1.9E1
      0000000
      0000910
1ce1c b2130    END

17 Oct 90 06:52
Rick Grevelle: >RPL constructs

In article <11408@life.ai.mit.edu> you write:
>
>   Could someone who knows, please describe how conditionals, loops,
>and CASEs are stored internally? I need it to get SAD 1.02 to
>disassemble RPL code. Actually, it already does, but I intend to
>supply macros for common RPL constructs to get the indentation
>correct.
>

I not quite sure what it is that you're asking; are you wanting someone
to explain how machine code handles these items, or are you asking about
the prefixed machine routines that RPL calls to handle decision making?
By common RPL constructs I assume you mean the later; but please explain 
further.

>   Oh, and could someone explain what reals (i.e. 64-bit floating
>point words) look like? Things like how the exponent is stored, the
>exponent sign, the mantissa sign, etc. I haven't done any thorough
>investigation here, and only know vaguely what is what.

Alonzo Gariepy explains this in his Processor Notes in terms of the various
fields used within the internal registers.  Here is a simplification of it.

                         Internal Real
                 
                    s mmmmmmmmmmmm s ee ppppp
    
i)   The lower case s's indicate the sign of the mantissa and exponent.  For 
     positive values a zero is used, and a nine is used for negative values.

ii)  The twelve lower case m's represent the mantissa.

iii) The two lower case e's are the exponent.

iv)  And the lower case p's are the prolog #02933h.

>   Also, please voice your opinion on the following (PROGRAM and END
>are SAD macros, which currently is the only way to define proper
>indentation among other things) format:

Whoa!  I don't know about this; it could be a potential copy right violation.
Don't get me wrong, you're doing an extraordinaryly good job; obviously you're
quite knowledgeable.  But HP is a rather large and powerful corporation, with
high dollar attorneys on retainer.  Posting, without permission, portions of
code from the 48's ROM on which HP holds the copyright is a very grey area.

Personally, I'm little paranoid about much of the material alluded to in my
postings.  I am almost certain that by now HP must hate me.  However, I once
discussed the matter with Alonzo, from whose opinion I formed my currenlty
used guidelines for posting to the net, so there is probably no reason for
me to worry.
 
As for as my opinion on your format is concerned; it is EXCELLENT!  It looks
almost identical to RPL disassemblies I've been doing by hand since the 28.
I'm looking forward to this latest version of SAD, with it I could cover ten
times the amount of territory than in the past.  No one has yet to produce,
outside of HP, an RPL disassembler this accurate; at least of which I know.

Rick Grevelle

17 Oct 90 20:55
Jan Brittenson: >>RPL constructs

In article <9206@helios.TAMU.EDU> 
   n233dk@tamuts.tamu.edu (Rick Grevelle) writes:

 > I not quite sure what it is that you're asking; 

   Perhaps I should have been more precise: this may dumbfound you,
but all I want to know is how they are stored. I remember someone
mentioning a while ago that there is more to how an IF clause is
stored than just the keywords (RPL addresses of IF, THEN, etc). I have
also noticed there are several more branch (switch on types, for
instance) instructions used internally.

 >> Oh, and could someone explain what reals (i.e. 64-bit floating point
 >> words) look like? Things like how the exponent is stored, the exponent
 >> sign, the mantissa sign, etc. I haven't done any thorough
 >> investigation here, and only know vaguely what is what.

 > Alonzo Gariepy explains this in his Processor Notes in terms of the
 > various fields used within the internal registers.  Here is a
 > simplification of it.

 >
 >                         Internal Real
 >                 
 >                    s mmmmmmmmmmmm s ee ppppp

 >iii) The two lower case e's are the exponent.

   Is the exponent stored as an 8-bit integer (i.e. 0-255), or as two
digits (00-99)? It would make sense to me if also bits of the exponent
sign nibble were used, since the exponent range is -499 to 500.
Perhaps it's three digits (000-999), with a xsn digit of '5' or higher
denoting negation? What about the mantissa sign - are mantissa signs
of 0-4 considered positive while 5-9 are considered negative?

 > Whoa!  I don't know about this; it could be a potential copy right
 > violation.  ...HP is a rather large and powerful corporation, with
 > high dollar attorneys on retainer.  Posting, without permission,
 > portions of code from the 48's ROM on which HP holds the copyright is
 > a very grey area.

   If this is a problem, I can volunteer to set up a mailing list to
which I only add people after they submit me a message stating their
48's serial number, and its place and date of purchase. I'll be more
careful with posting things like this to the net.

 > Personally, I'm little paranoid about much of the material alluded to
 > in my postings.  I am almost certain that by now HP must hate me.

   Does HP even care? If nothing else, it's probably just good for
their sales and image.

18 Oct 90 07:53
Rick Grevelle: >>>RPL constructs

In article <11423@life.ai.mit.edu> bson@rice-chex.ai.mit.edu (Jan Brittenson) wr
ites:

> Perhaps I should have been more precise: this may dumbfound you,
> but all I want to know is how they are stored. I remember someone
> mentioning a while ago that there is more to how an IF clause is
> stored than just the keywords (RPL addresses of IF, THEN, etc). I have
> also noticed there are several more branch (switch on types, for
> instance) instructions used internally.

Jan, it was me to whom you refer.  I now know what it is you're asking, but
this should be an easy task for you.  The difficult task is deciphering the
numerous machine routines used internally by RPL to handle these structures.
The relatively few prefixed machine routines used to support keywords such as
these are just the tip of the iceberg as far as the internal world of RPL is
concerned.

Further, many of these are multifacited in that they will perform differently
depending on what conditions exist at the time of execution.  Take for example 
the prefixed machine routine responsible for both keywords START and DO.  The
routine's address is #71A2h.  Here is an example of how this routine works.

     Used as START

     02D9D  begin RPL
     23754  list_{ 'noname 'stop }
            (these are local variables used to store the start and end of loop)
     074D0  store_local_variables
     071A2  start
     .....
     .....  (loop clause)

     2326A  next
     0312B  end RPL


     Used as DO

     02D9D  begin RPL
     071A2  do
     .....
     .....
    
     071C8  end? (requires boolean #3A81h, true; or #3AC0h, false)

Here are some other clause addresses I've currently documented in the 48:

073C3  start 0 to n-1 1short
073C3  start 1 to n-1 1short
073DB  start 1 to n-1 1short
073F7  start n2 to n1 1short2short
07221  current loop increment
07249  n of loop
07334  next
073A5  step

If you're interested in how these routines manipulate data, do what I did and
disassemble them.  If it's the keyword structures such as DO UNTIL END, START
NEXT, or IF THEN ELSE in which you're interested, store them in the top of the
RAM and PEEK at what is there.  The manner in which these are stored is fairly
straight foward; there is some nesting which occurs, but it shouldn't be any
sort of a problem for you.  If you should have any specific questions about
you findings, post them here or send via <email>.

>  Is the exponent stored as an 8-bit integer (i.e. 0-255), or as two
> digits (00-99)? It would make sense to me if also bits of the exponent
> sign nibble were used, since the exponent range is -499 to 500.
> Perhaps it's three digits (000-999), with a xsn digit of '5' or higher
> denoting negation? What about the mantissa sign - are mantissa signs
> of 0-4 considered positive while 5-9 are considered negative?

You are quite right, I stand corrected.  The exponent for a real is stored as
twelve bits.  The quick and dirty way to determine what negative exponents will
look like when stored internally is to add the negative exponent to a thousand.

For example, to determine what 1.23E-456 would look like internally, add -456
to 1000.  The negative exponent would be stored as 544.  Here is how the real
looks internally.

012300000000054402933

As far as the sign field of the mantissa is concerned, it remains as previously
described; a zero for a positive and nine for negative mantissas.  Also note
that the mantissa utilizes only decimal numerals, hex characters A-F never
appear.

>  If this is a problem, I can volunteer to set up a mailing list to
> which I only add people after they submit me a message stating their
> 48's serial number, and its place and date of purchase. I'll be more
> careful with posting things like this to the net.

>  Does HP even care? If nothing else, it's probably just good for
> their sales and image.

The mailing list sounds great to me.  Does HP care?... I don't know.. I don't
think I'd want to find out, at least in a court of law I wouldn't.  Now about
it being good for their sales image, it wouldn't seem so.  Eventhough this news
group is read around the world, I'd bet you that were only a very small percent
of HP users.  For instance, there are 44,000 students enrolled this Fall here 
at A&M.  I've seen 48s all over, especially within the college of engineering,
but I personally know of only a couple of individuals who actively read this 
board.

Rick Grevelle

Derek S Nickel: >>RPL constructs
BCD numbers (binary coded decimal) are represented by a mantissa,
sign and exponent fields.  There are two kinds of BCD numbers in 
the HP 48SX, 12-form and 15-form BCD numbers, called BCD12 and
BCD15 in the field descriptions.

Both kinds have several things in common:

    *    A mantissa.  Each digit of the number is represented by 
         one nibble in the mantissa.  12-form BCD numbers have a
         12 digit mantissa and 15-form BCD numbers have a 15
         digit mantissa.  There is an implied decimal point after
         the Most Significant Digit (msd) with respect to the 
         exponent.

    *    A sign nibble.  Positive numbers are represented by a 
         0 and negative numbers are represented by a 9.

    *    An exponent.  The exponent is in 10's compement.
         12-form BCD numbers have a 3 nibble exponent and 15-form
         BCD numbers have a 5 digit exponent.

12-form BCD numbers are the basis for Real Number, Complex 
Number, Real Array and Complex Array data types.

15-form BCD numbers are the basis for Long Real and Long
Complex data types.

BCD12:

 15 14                     3  2   0
+--+------------------------+------+
|S | msd..  Mantissa  ..lsd | Exp  |
+--+------------------------+------+
 1             12              5

BIN15:

 21 20                           5  4       0
+--+------------------------------+----------+
|S | msd...    Mantissa    ...lsd |   Exp    |
+--+------------------------------+----------+
 1                15                   5

------------
This is from my 'HP 48SX Internals' document that is getting close to its
first posting.  Hope it helps.

Take a look at the Real Number and Long Real objects starting with 
0 (Real Number) at 2A2B4 to 10 (Long Real) at 2A596.  There are 34
objects in that range.  Most are simple.  But includes PI and MAXR...

    Good Luck!

    Derek S. Nickel

17 Oct 90 00:31
Kenneth Brunell: HP48sx Transfers

I am having some problems with uploading stuff from my 48 to my computer.  I
have had no trouble whatsoever downloading to the 48.  But, if I try to upload
a directory it goes to 2 or maybe 4 blocks and croaks, like it can't get a
good checksum.  I can upload single items, in ascii mode.  Trying those
same files in binary mode, it dies on either the 4th block or the 15th block,
depending on which file, and apparently at the same place in the same file.
ARCHIVE stops on the 2nd block.  (as the others, 10 retrys, then fails)
I am using OS9 Kermit on a Tandy CocoIII.  Could there be a problem in my
Kermit?  Oh, also, the "cable" is rather makeshift, and unshielded, but, again,
id downloads OK.

Any help GREATLY appreciated.  I sure would like to be able to back memory.
-Ken

-------------------------------------------------------------------------------
|  _   ,                __                     _  _  |  "It's green . . ."    |
| ' ) /                /  )                   // //  |       Mr. Scott        |
|  /-<   _  ____      /--<  __  . . ____  _  // //   |                        |
| /   ) </_/ / <_    /___/_/ (_(_/_/ / <_</_</_</_   |   Loooove that .sig    |
|          <khbsnsr@jupiter.nmt.edu>                 |                        |
===============================================================================

Rick Grevelle: Internal Argument Checking

In article <41777@eerie.acsu.Buffalo.EDU> cloos@acsu.buffalo.edu (James H. 
Cloos) writes:

> Back in September, someone posted the addresses of routines you can
> SYSEVAL to convert strings to names and visa-versa.  As I understood
> it, these addresses did no argument checking.  .............. 
> 
> There is one oddity here I would like to note  ..............
> ......... the prefixed machine routine at <#18FB2h> checks whatever is
> on stack in level one (better be something there :) to see if its TYPE 
> is appropriate to your program.  The format is:
>
> 18FB2 : cck for type
> nnnnn : <xh> where x is the short integer at address #nnnnnh
>
> Now, PRG\-> used the short int <8h> to check for a program; this
> matches the user language (usrlang) TYPE command's output when given a
> program.  Similarly, I used <9h> for an algebraic as the TYPE of an
> algebraic is 9.  For S\->N I tried to use <2h>, as the TYPE of a
> string is 2.  This did not work; it turns out that you have to use
> <3h> with the routine at #18FB2h to check for a string.  <2h> will
> check for a complex number.  <1h> tests for a real.  <5h> does test
> for a list, and it turns out that <4h> will test for any array, real
> or complex, 1D or 2D, and given the internal structure of the arrays,
> I'd assume it would accept arrays of strings, etc., as well.
>

Internal types for some objects differ from that of those which the TYPE
command returns (page 97 of the reference manual).  Perhaps not everyone
saw the TYPE RPL disassembly recently posted by Jan Brittenson.  While
not all of the conversions are apparent, most of them can be determined
with out having to disassemble and study the machine code.  In order to
alleviate any further confusion, I'm posting some of the more frequently
used types internally along with several prefixed machine routines used
to check arguments.  Lastly, I've included two routines that exemplify a
multiple argument checking application.

Rick Grevelle


                     Internal Object Type Numbers

      Stack Object            Type Number            ROM Address

        Any                     <0h>                    #3FEFh
        Real number             <1h>                    #3FF9h
        Complex number          <2h>                    #4003h
        String                  <3h>                    #400Dh
        Real array              <4h>                    #4017h
        Complex array           <4h>                    #4017h
        List                    <5h>                    #4021h
        Global name             <6h>                    #402Bh
        Local name              <7h>                    #4035h
        Program                 <8h>                    #403Fh
        Algebraic               <9h>                    #4049h
        Algebraic/Global        <Ah>                    #4053h
        Binary integer          <Bh>                    #405Dh
        Graphics object         <Ch>                    #4067h
        Tagged object           <Dh>                    #4071h
        Unit object             <Eh>                    #407Bh
        XLIB name               <Fh>                    #4085h
        

                       
                          ROM  Checking Routines
                        

                Address             Routine Description
        
                 18A68          checks for 3 stack arguments
                 18A8D          checks for 2 stack arguments
                 18AB2          checks for 1 stack argument
                 18B7A          checks for 5 stack arguments
                 18B9F          checks for 4 stack arguments
                 18F9D          checks stack arguments type 
                 18FA9          checks stack arguments type
                 18FB2          checks stack arguments type

         

                                                        
PSERS

02D9D   begin_RPL
18F8D   need_2_stack arguments
18FA9   check_2_arguments_for_type_
64C70   <56h>_list(2)_global(1)
02D9D   begin_RPL
549CC   list_{ 'dvar }_(local name)
074D0   store_local_variable(s)_1{locals}2any...nany
054AF   list->
03FF9   short_integer_<1h>
073F7   start_n(2)_to_n(1)_1short2short
03223   swap
549DB   'dvar  (local name)
07221   current loop count
18DBF   short_integer->real
1B02D   ^
1ADEE   *
1AB67   +
07334   next
0312B   end RPL
0312B   end RPL


CPSERS
(BYTES: #7350h 157.5)


%%HP: T(1)A(D)F(.);
\<<
 # 18FA918A8D02D9Dh
 # D0549CC02D9D64C7h
 # 3F703FF9054AF074h
 # 7221549DB0322307h
 # 1ADEE1B02D18DBF0h
 # B0312B073341AB67h
 # 312h 1 6
 START # 5193h
  SYSEVAL
 NEXT # 4003h
 SYSEVAL # 62B9Ch
 SYSEVAL 
\>>


PSERS  (reqires ASC\->)

%%HP: T(1)A(D)F(.);
"D9D20D8A819AF8107C46D9D20CC9450D470FA4509FF307F37032230BD9451227
 0FBD81D20B1EEDA176BA143370B2130B213097C6"%%HP: T(1)A(D)F(.);


PCOEF

02D9D   begin RPL
18A68   need_3_stack_arguments
18F9D   check_3_arguments_for_type_
65008   <A61h>_algebraic/name(3)_global(2)_real(1)
02D9D   begin_RPL
18CEA   real->short_integer
03223   swap
549CC   list_{ 'dvar }_(local name)
074D0   store_local_variable(s)
59373   polynomial->coefficients
03188   dup
03E2D   add_2_1short
0400D   short_integer_<2h>
073F7   start_n(2)_to_n(1)_1short2short
07221   current_loop_count
03223   roll
07334   next
05459   ->list
0312B   end RPL
0312B   end RPL


CPCOEF
(BYTES: #7350h 157.5)

\<<
 # 818F9D18A6802D9Dh
 # 2318CEA02D9D6500h
 # 373074D0549CC032h
 # 400D03E2D0318859h
 # 332507221073F70h
 # B054590733403223h
 # 312B0312h 1 6
 START # 5193h
  SYSEVAL
 NEXT # 4003h
 SYSEVAL # 62B9Ch
 SYSEVAL
\>>


PCOEF (requires ASC\->)

%%HP: T(1)A(D)F(.);
"D9D2086A81D9F8180056D9D20AEC8132230CC9450D4703739588130D2E30D004
 07F3701227052330322304337095450B2130B213083C9"

James H. Cloos: Directory structure unearthed
Hello all.  I've finally determined precisely *how* sub-dir's are
stored in the 48sx and 28s's.  Below, I will use the code _DIR for the
header.  In the 48sx, the value of this is <#02A96h>; on the 28s, it
is <#02AB8h>(from Eric Toonen's obj.doc; don't blame me if its incorrect).
(I do take responsibility for the 48sx value, though).

The format is:

_DIR <#7ffh> (link_to_1st_object) (end_link) (nth_object) (link_to_nth_object)
(n-1th_object) (link_to_n-1th_object) ... (1st_object)

1st object is the one that is on the left-most menu key == the last
object STO'ed, assuming ORDER hasn't been used.

All links are 5 nybbles long.

A link_to_ith_object field is also the length of the ith_object, in
nybbles.

An object has the form:
(len_of_name) (the_name) (len_of_name) (data_STO'ed_in_name)

The (end_link) field is <#00000h>.

Notice that the object are stored in reverse order, which means that
when searching the directory tree, the hp sees a dir via the _DIR
header, then uses the pointers to find each of the id's w/in that dir
by 1st jumping to the "1st" one, which is at the end of the mem
structure; it then sequentially looks at the pointer just before the
"current" name and jumps back that many nybbles to find the "next" id.
When a pointer of 0 is found, it knows that it is at the end of the
directory. 

2 Examples:

(remove the spaces and then ASC\-> these...)

1)      DIR END
is:     "69A20 FF7 00000 B6E5" == _DIR,7FF,00000,kcrc

2)      DIR A SIN B COS END
is:     "69A20 FF7 02000 00000 10 24 10 29E20 200 250 11000
         10 41 10 29E20 200 150 1D89"
which is:  _DIR,7ff,lnk_to_A,1_char_id,'B',1_char_name,
                RomPtr,002,052,lnk_to_B,1_char_name,
                'A',1_char_name,RomPtr,002,051,kcrc

(A RomPtr = ROM pointer = XLIB, so we see that SIN is library 2, cmd 52h.)

--
I hope that this is understandable.  I'm currently at work putting
together a rpl compiler, and have been concentrating just now on
getting the bison grammer together.  I still have to figure out how to
do a library, backup object, & unit object.  (At least now that it can
do a directory, usrlib can be used to convert that into a library.)
Anyway, given my primary project, I've not a lot of time to get this
posting done properly.  Perhaps someone who understands what I'm
saying can take the time to explain it for any who don't.  Oh, yes,
the "kcrc" means kermit crc, which as I pointed out earlier is the
algorithm for the BYTES crc; it is the one used for kermit transfers
when checksum type is set to 3.  I included it above only so that the
strings could be put thru ASC\->, these are not there in memory.

-JimC
--
James H. Cloos, Jr.             Phone:  +1 716 673-1250
cloos@ACSU.Buffalo.EDU          Snail:  PersonalZipCode:  14048-0772, USA
cloos@ub.UUCP                   Quote:  <below:  ;^)>

THIS INFORMATION COMES WITHOUT ANY FORM OF WARRENTY, NOT EVEN IMPLIED ONES.

Relay-Version: VMS News - V6.0 13/10/90 VAX/VMS V5.4; site gacvx2.gac.edu
Path: gacvx2.gac.edu!noc.MR.NET!msi.umn.edu!src.honeywell.com!sol.ctr.columbia.edu!cica!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!uwm.edu!ogicse!plains!lien
Newsgroups: comp.sys.handhelds
Subject: Re: Directory structure unearthed
Message-ID: <6993@plains.NoDak.edu>
From: lien@plains.NoDak.edu (Craig Lien)
Date: 2 Dec 90 21:08:01 GMT
References: <46136@eerie.acsu.Buffalo.EDU> <2758b6f2:1124.1comp.sys.handhelds;1@
   hpcvbbs.UUCP>
Organization: North Dakota State University, Fargo
Lines: 37
 
In article <2758b6f2:1124.1comp.sys.handhelds;1@hpcvbbs.UUCP> akcs.dnickel@hpcvb
   bs.UUCP (Derek Scott Nickel) writes:
>Jim,
>
>In reguards to that 3 nibble field near the start of a directory.  You
>stated that it was 7FF.  I've played around with the ATTACH command and
>have discovered this:
>
>For the HOME directory:  this field is the count of the Library objects
>that are attached to the HOME directory, including the two standard
>libraries 2 and 1792.
>
 
Lately I've been doing menu commands on every Library number that I know of.
When I saw the above posting I did menu 2 I didn't expect anything
spectacular.  However menu 1792 is quite unique.  What I get on a REV E. is
 
IF THEN ELSE END -> WHILE
REPEAT DO UNTIL START FOR NEXT
STEP IFERR HALT XLIB -> >>
<< >> ' ' END END
THEN CASE THEN DIR PROMPT XLIB
XLIB XLIB XLIB XLIB XLIB XLIB
the above menu contiues for as long as I can tell.
 
Will the XLIBs ever stop?  I realize that numbers in computers are finite
and it will stop when the menu number rolls over.
 
I hope someone follows up on this.
 
[7 lines deleted]
>        Derek S. Nickel
 
Craig
--
 
           We've come a long way since the world was flat.
                       lien@plains.nodak.edu

Relay-Version: VMS News - V6.0 13/10/90 VAX/VMS V5.4; site gacvx2.gac.edu
Path: gacvx2.gac.edu!noc.MR.NET!msi.umn.edu!src.honeywell.com!uwm.edu!wuarchive!sdd.hp.com!hp-pcd!hpcvra.cv.hp.com!rnews!hpcvbbs!akcs.dnickel
Newsgroups: comp.sys.handhelds
Subject: Re: Directory structure unearthed
Message-ID: <2758b6f2:1124.1comp.sys.handhelds;1@hpcvbbs.UUCP>
From: akcs.dnickel@hpcvbbs.UUCP (Derek Scott Nickel)
Date: 2 Dec 90 08:40:12 GMT
References: <46136@eerie.acsu.Buffalo.EDU>
Lines: 17
 
Jim,
 
In reguards to that 3 nibble field near the start of a directory.  You
stated that it was 7FF.  I've played around with the ATTACH command and
have discovered this:
 
For the HOME directory:  this field is the count of the Library objects
that are attached to the HOME directory, including the two standard
libraries 2 and 1792.
 
For subdirectories:  this field is 7FF if no library has been attached to
the subdirectory.  Otherwise
Otherwise it is the library number of the attached library.
 
I hope this additional info is of use...
 
        Derek S. Nickel

Jan Brittenson: >HP48SX Screen Addresses
In article <0481BF77937F618367@ISUVAX.BITNET> TNAN0@CCVAX.IASTATE.EDU writes:

 > I am enjoying programming my HP48SX in machine language, but I am
 > running into problems accessing display memory.  I need to know how
 > video memory is laid out and where the elusive pointers are that keep
 > track of its current location.

@70551: menu GROB; 131x8
@70556: stack GROB; 131x56
@7055b: current display GROB
@70560: graph GROB; at least 131x64
@70565: graph GROB (?)

   I prefer using 70556 for TEXT, 70560 for PICT, and 7055b for the
current display mode. (Notice that these are pointers to GROBs, not
GROBs themselves.)

> Also, where is the most complete set of internal addresses available from?

HP/CV? :-)

 > It seems that SAD expects its compiler to use at least 4-byte
 > integers, and most PC compilers use only 2-byte integers...

Can't all PC compilers be set to default to 32-bit ints? It's fairly
resonable to assume that argc and other system-defined int's conform
to the specified size. (Be happy I switched from GCC's 64-bit `long
long' to the more portable 32-bit int!)

   What compiler are you using? The last time I looked at MS-DOS, MSC
had a library that looked very much like it contained the basics of
unix' libc. SAD uses qsort(), for instance. The fact that you got it
to link at all, is a good indicator that someone has tried to be unix
compatible. Suffice to say that SAD wasn't ever intended for use on
PC/XTs. I very much doubt MS-DOS virtual address space (= 640k) will
stand up to SAD's needs. Especially in 1.03 which automatically
deduces format info and generates symbols. I doubt an MS-DOS machine
will ever be able to disassemble the entire ROM (00000-6FFFF) without
running into memory problems, since this would involve perhaps tens of
thousands of user-defined symbols, 100000's of generated symbols, as
well as comments and cross referencing tables. Notice that 1.03 also
cross references auto-symbols, so you're in deep shit here.  Partial
disassembly will never yield the same results. I don't mean to bash
MS-DOS here; just state the fact that it has a memory model everyone
else stopped using in the early 80's. I don't have any good libraries
around for work-file stuff anymore, and besides, it would make SAD
prohibitively slow to put the symbol table or xref tables, even
partially, and however well cached, in a file.

   Sorry about this. I sincerely hope SAD will still prove somewhat
useful for MS-DOS users, though.

 > It compiles fine, but when I disassemble it only prints the first
 > couple of columns...  (Thus I can only see the disassembly if I have
 > SUPPRESS COMMENTS on...)

   It's a little hard to tell exactly what's going   on from your
description - can you mail me a sample?

 > it also freaks out when it tries to disassemble anything with a "D" in
 > the ML...  I just can't figure out why...

   Do you mean whenever the mnemonic contains the letter `D' or
whenever the opcode contains (starts with?) the hex digit D? What
happens - do you suspect that it scambles the memory?

   I just discovered the master bug in SAD 1.03, by the way. It is
present in 1.02 also - there MUST be a format specified at address 0.
This is present in `stdformats' as distributed with 1.02. I won't fix
this bug, just keep this in mind - don't remove the 0:c from .formats!

   Perhaps this is somehow related to your problem - make sure SAD
reads the formats file; you have to rename it for MS-DOS and edit
sad.h to reflect this name change.

James H. Cloos: Today the subject is libraries (LONG)
Yup, you guessed it; I spent the last few hours pouring over hex dumps
of libraries, both created from directories by usrlib, and some from
the bbs.  Anyway, this is what I found out:

(NB, each of these fields is individually reversed in memory; unlike
the dir posting, I'll write these in readable format.)

A library looks like this:

#02b40          LIB header
#nnnnn          size of the library, incl this field.
#nn             the length of the lib's name, in chars

(If the lib is unnamed, this is #00 and the next two fields are missing)

asciiascii      the name of the library
#nn             the length of the lib's name, again

(Now back to always there mode :)

#nnn            the LIB's id number
#nnnnn          offset to hash table    \
#nnnnn          offset to message arry  | offsets are from the start of
#nnnnn          offset to link table    | the offset field 
#nnnnn          ofset to config object  /

the data follows.

Named xlibs are stored in the format:
#000 or #8      000=ok in alg expressions, 8= not ok in algebraics
#nnn            lib's id number from above
#nnn            the xlib's member number
the actual object, starting w/ a std type field.

(You'll find that lib #002 (the usrlang commands) is stored this way also.)

Unnamed xlib's are stored w/o the #000nnnmmm or #8nnnmmm header, so
you just start w/ the type field.

The config object is what is evaluated after each system halt, and is
usually a program. To borrow from the usrlib doc file, make sure this
DOES NOT LEAVE ANYTHING ON THE STACK OR DROP ANYTHING THAT WAS THERE.
My assumption is that only a ram clear will fix the 48 if there is a
lib installed that has a bad config obj, as the post-system-halt
routines will probably crash each time you try one.

The link table is a hex string (a la a binary integer, but with a max
wordsize of 2^5 - 6 nybbles) (proof of that is left as an exersise for
the reader).  This hex string is 5 nybbles long per XLIB in the
library, and each group of 5 nyb's forms an offset from the table to
the beginning of the type field of each xlib.  These offsets are
signed, so if this table is after the actual XLIB's, the offsets
will be the complement (as per the NEG key on a binary integer--I'm
too tired to figure out if this is 1's or 2's ;) of the actual
distance from the field to the XLIB.  These are the only signed
offsets I'm aware of so far, though maybe all offsets are, check your
local saturn guru for details.  ;)

The message array is a simple array of strings.  (Which have the format: 

#029e8          type of ARRY
#nnnnn          size of array, incl this field
#02a2c          type of data in general, #2a2c is string type
#nnnnn          number of dimentions
#nnnnn          number of elements in 1st dimention
...
#nnnnn            ''   ''    ''    '' nth    ''
data

Where data is sum(i=1,no_of_dims,no_of_elem_in_this_dim) elements of
the type specified.  In the case of strings, each of these looks like
a 5 nybble size field (in nyb's incl itself) plus the ascii chars in
the string.)

This leaves the hash table.  This is also a hex string.  At the end of
this hex string are 5 nyb pointers for each named XLIB which point to
that XLIB's name.  These names immediately precede the pointers.
These offsets, though pointing backwards, are positive (or unsigned?),
ie., #00020 would point 32 nybbles back from the start of itself.

The names these point to are in the familiar global name format, ie a
2 nybble size field (in char's, excluding itself) followed by that
many bytes of ascii (each of course in reverse nybble order).  This is
followed by a 3 nybble field of that XLIB's member number.  Before
this is a 5 nyb field that is the length, in nybbles, of itself, & each
of the XLIB names (inlc that name's length field and number field).
Before all this, in each of the lib's I've looked at, is 85 nybbles of
mostly 0's.  They seem to be 16 fields of 5 nybbles each (resonable
thought) and there would seem to be on the order of 3 or so of these
fields that contain any non zero data, this is usually only 2 nybbles.
I presume they are some sort of offset, but to where (or from where
for that matter) I've no idea.

The CONFIG, MESSAGE, LINK, HASH, and each individual XLIB can be, so
far as I can tell, in any order, so long as each is itself contiguous ;^)
I would presume, however, that there is some performance penalty if
they are all mixed around, as minor as that might be (though if you
use a XLIB in such a library in a type loop, these penalties could
amount to a noticable delay).  (My compiler will use a standard order
which is the easiest for me to put together. ;)

I better leave now, before I go over 900 words; I've already passed
100 lines.  Enjoy this info.  & like the post on dir's, if you don't
understand it, ask & someone (maybe even me) will try to explain it
better.  This *is* fun.  Trust me.  Really.  Would *I* lie to you?
Seriously.  As much as this looks sarcastic, it isn't.  I promise.

BTW, the library: "04B20E10000066600000000000000000000577E" (in ASC
format) is nothing but an unnamed lib, lib# = 666h = 1638d, w/o
anything in it.  ASC\-> will work on the string, resulting in :
`Library 1638: ` on the stack (w/o the `'s of course).  I'm not going
to try installing it, as I don't feel like a mem lost just now.  Could
someone out there who has a handy archive try this and report on it?

L8r, ffolks.

-JimC
--
James H. Cloos, Jr.             Phone:  +1 716 673-1250
cloos@ACSU.Buffalo.EDU          Snail:  PersonalZipCode:  14048-0772, USA
cloos@ub.UUCP                   Quote:  <>

David_Michael_Ka: >Today the subject is libraries (LONG)
Please bear with me - I've rarely posted my own articles before, and
I'm using an unfamiliar system.

In a recent article (see - I don't know how to do followups correctly yet),
Jim Cloos described the structure of the Library object on the HP-48.  He
left a couple of question marks in the description, which I will try to
elaborate here.

The unknown fields were all a part of the hash table.  Here's my
current understanding of the hash table structure:

#02a4e          Prolog for binary integer
#length         Length of binary from this field to end
#ptr1           5-nibble offset (from start of this field) to first
                  1 character name (#00000 if none)
#ptr2           Pointer to first 2 character name
...
#ptr16          Pointer to first 16 character name
#decompile      5-nibble offset (from start of this field) to #xlib0
                  below.  This tells the 48 where the poin  ters are
                  for it to decompile a name from an xlib object

1-char-name-data        This is as Jim described - each name is
2-char-name-data        entered here, in no particular order, except
3-char-name-data        that names of the same size are grouped
4-char-name-data        together.  Each name is a two nibble size,
5-char-name-data        the ascii data, then the XLIB number.
...
16-char-name-data

#xlib0          5 nibble offset, which as Jim mentioned, is positive
                  to point backwards (unlike most of the other offsets),
                  This points to the size nibbles of the name for
                  XLIB object #0
...
#xlibn          Pointer for the last named XLIB object's name.



That's it for the hash table.  One other thing that I think Jim
left out - the library object has 4 CRC nibbles appended to it.
These CRC nibbles are calculated using the Kermit CRC algorithm,
but the CRC is calculated starting with the length field, not the
#02b40 field, and includes everything up to (but, for obvious reasons,
not including 8-) the CRC itself.  The length field of the library
includes the 4 CRC nibbles.

WARNING:  Be careful when playing around with library objects with
incorrect CRCs.  I did this several months ago, and started to notice
that I had less memory than expected.  It turns out that if you
install a library with a bad CRC in port 0, at the next system halt,
the bad CRC is detected, and the bad library object is 'pushed' aside
so that all the good objects in port 0 are contiguous.  But, the
bad library still takes up memory!!  I ended up doing a lot of peeking
and poking to reclaim my memory again.  I didn't try it, so I'm not
even sure a memory clear would work.  This warning applies to the
simple library that Jim posted, since it doesn't have a CRC field
(I'm not talking about the CRC needed for the ASC-> program - the
library object itself has an embedded CRC).  I don't know for sure
since I'm not risking any memory lost right now - oh, what the hell,
I just tried it, and sure enough, the library doesn't install correctly.
Instead, when the bad CRC is detected, you get the message
Invalid Card Data,
and the behavior I just described.

One final note - I don't believe there would be any performance
penalty for ordering the various components of a Library object
at random - they are always going to be accessed via pointers.


Again, I apologize if the preceding post is all messy.  It will take
me some time to get used to this new system (I'm using a $#@!% line
editor right now).  But, I'll never learn it if I don't try it.
Please direct replies to the address above, or
Dave.Kaffine@MicroProd.NCR.com

16 Nov 90 04:49
David_Michael_Ka: >Today the subject is libraries (LONG)

(I'm still trying to get used to posting, bear with my mistakes)

Just one more note on library objects.  I made a small mistake in
my previous post.  When you install a library with an incorrect CRC,
it does not get moved so that all of the 'good' objects in that port
are contiguous, as I stated before.  Instead, the object stays 
still, and the prolog (in this case, #02b40 for a library) 
is overwritten with 0's.  This 00000 is also what's used to 
mark the end of objects in a port (i.e Port 0, at least, is
just a sequence of RPL objects, terminated by 00000).  Thus, the bad
object is now hidden, ALL objects that were after it in port memory
are hidden, and you're suddenly missing a fair chunk of memory.  The
only reasonable way of getting the memory back is to archive your user
data, do an ON-A-F, and restore your user data.

I apologize for the mistake - my memory on this was a few months old,
and wasn't refreshed until I installed Jim Cloos' sample library and
saw the same things over again.

To summarize:  If you store the library object from Jim Cloos' article
into port 0 and press ON-C (or turn calc. off and on), you will get the
message "Invalid Card Data".  The library will no longer show up in the
port 0 listing.  Anything that was previously in the port 0 listing will
no longer show up.  All of the objects that have disappeared are still
taking up memory.  A memory-clear will reclaim the lost memory (not to
mention your user variables!).


Dave.Kaffine@MicroProd.NCR.com          or
David_Michael_Kaffine@cup.portal.com

16 Nov 90 16:40
Derek S Nickel: >>Today the subject is libraries (LONG)

Jim,

Requarding those unknown nibbles.  You'll notice that the name-table part
of the hash-table is sorted by command name length, and then
alphabetically.  These 5 nibble fields are offsets into the name table
for a specific name length.  I.e., the first slot contains the offset to
one character names (or zero if no one character names), the second slot
contains the offset to the first two character name, the third is an
offset the first three character name... and so forth.

Thanks for the info on the unsigned pointers at the end of the hash
(pointing back to the individual names).  That had ne stumped.  I knew
they had to be related to the commands themselfs, but never guessed that
they were backward pointing.

        Derek S. Nickel

John P Morrison: HP 48 Object types
Here's a little item that may be of interest, which is not documented in
the (error)
messages section of the manuals. Try  this:

STYPE

\<< TYPE 263 + DOERR \>>

In case you see an object, and you  don't recognize what it is, you can
run
this program on the object, and it will tell you what it is.

eg. if you find this on the stack after CHIP:

<0h>

STYPE will tell you that it is a System Binary

from this you can deduce that an object of
type 20 =       System Binary (called shorts by some) 
type 21 =       Long Real
type 22 =       Long Complex
type 23 =       Linked Array
type 24 =       Character
type 25 =       Code
type 26 =       Library Data
type 27 =       External

of these object types, has anyone actually seen types 21,22,23,24 or 26
on the stack?

jpm

21 Nov 90 02:49
Jan Brittenson: >HP 48 Object types

In article <1990Nov20.140927@ee.ubc.ca> jmorriso@ee.ubc.ca writes:

 >from this you can deduce that an object of
 >type 20 =     System Binary (called shorts by some) 
 >type 21 =     Long Real
 >type 22 =     Long Complex
 >type 23 =     Linked Array
 >type 24 =     Character
 >type 25 =     Code
 >type 26 =     Library Data
 >type 27 =     External

   An interesting side-note here is that objects with types #2baa,
#2bcc, #2bee, and #2c10 all appear as External on the stack, and have
TYPE 27. They can be recognized in a type switch as <1ah>, <1bh>,
<1ch>, and <1dh>. They are Library Data objects, i.e. a type followed
by a 5-nibble size word, followed by the data, and evaluate to
themselves.

Jan Brittenson: >Lists in the HP48
In article <kskalb.659353921@faui1f> 
   kskalb@faui1f.informatik.uni-erlangen.de (Klaus Kalb) writes:

 > I want to know how the HP48 implements the data type LIST.  Are they
 > just plain, ordinary linked lists or is there something more
 > spohisticated going on ?

   No, they're not cons cell lists, or linked in any way. Lists are
simply a List data type (#2a74) followed by the contents and
terminated with an End (#31b2). Like in a program, data may be of any
type, either in-line or somewhere else. (I.e. there may be either data
or pointers to data, or both randomly intermixed.) They can be
regarded (sort of) as CDR-coded lists, or hunks, or functionally (not
implementationally) like (make-array ... :element-type t) Common Lisp
arrays.

   RPL arrays differ by being restricted to a single type - real or
complex (has anyone attempted to synthesize an array of some other
type, like Character?), which allows for faster element address
calculations.

Frobozz: >>Lists in the HP48 (really arrays)
In <12017@life.ai.mit.edu> bson@rice-chex.ai.mit.edu (Jan Brittenson) writes:

>   RPL arrays differ by being restricted to a single type - real or
>complex (has anyone attempted to synthesize an array of some other
>type, like Character?), which allows for faster element address
>calculations.

I haven't tried this.  I did try to change the number of dimensions in
an array (on my old '28S) and it caused an interesting pattern on the
display when I tried to display the thing.  I never tried to do anything
else with it (because the display was suffering really badly).  I may have
had to do a system reset (the ON-C equiv, I cannot even remember what key
it was ummm up arrow?? :-).  I don't think I suffered a memory lost playing
around like this.


                                                        Pauli
seeya

Paul Dale               | Internet/CSnet:            grue@batserver.cs.uq.oz.au
Dept of Computer Science| Bitnet:       grue%batserver.cs.uq.oz.au@uunet.uu.net
Uni of Qld              | JANET:           grue%batserver.cs.uq.oz.au@uk.ac.ukc
Australia, 4072         | EAN:                          grue@batserver.cs.uq.oz
                        | UUCP:           uunet!munnari!batserver.cs.uq.oz!grue
f4e6g4Qh4++             | JUNET:                     grue@batserver.cs.uq.oz.au
--

25 Nov 90 07:40
Derek S Nickel: >>Lists in the HP48 (really arrays)

I've played around with Arrays of odd types (even Ayyays of Code).  The
message tables in HYDE are just Array of String.  But the user-level
commands only recognize 1 and 2 dimensional arrays of Real Number or
Complex Number.

In case any body cares...

Array (029EB)

<prolog><size><item-prolog><#dims><dim-1>...<dim-n><item-1>...
    <item-m>

<prolog> = 029EB (BIN5)

<size> = size of object in nibbles without the prolog (BIN5)

<item-prolog> = prolog of array elements (BIN5)

<#dims> = number of array dimensions (BIN5)

<dim-i> = i-th dimension (BIN5)

<item-j> = j-th item sans prolog (ANY)

n = <#dims>
m = <dim-1> * <dim-2> * ... * <dim-n>

        Derek S. Nickel

Derek S Nickel: >HP 48 Object types
Oh, yes!  They really do exist.  Here are two short ASC programs to play
with Long Real numbers.

"D9D202BA819AF819FF301C5A2B2130496B" ASC\-> 'R\->LR' STO
"D9D202BA819AF810DB460B5A2B21304635" ASC\-> 'LR\->R' STO

These two routines do type checking, the real heart of them is the
routines at 2A5C1 and 2A5B0 (respectively).

        Derek S. Nickel

Received: from gacvx2.gac.edu by gacvx1.gac.edu with PMDF#10127; Thu, 13 Dec
 1990 07:21 CST
Date: Thu, 13 Dec 1990 07:04 CST
From: handhelds@gac.edu
Subject: Re: Chip question
Sender: NEWSMGR@gacvx2.gac.edu
To: HANDHELDS@gacvx2.gac.edu
Errors-to: postmaster@gac.edu
Reply-to: handhelds@gac.edu
Message-id: <D1355E8100000726@gacvx2.gac.edu>
X-Envelope-to: d09c@DHBRRZ41.BITNET
X-VMS-To: IN%"HANDHELDS@GACVX2.GAC.EDU"
Comments: Forwarded from COMP.SYS.HANDHELDS by GACVX2.GAC.EDU

Relay-Version: VMS News - V6.0-1 14/11/90 VAX/VMS V5.4; site gacvx2.gac.edu
Path: gacvx2.gac.edu!noc.MR.NET!msi.umn.edu!news.cs.indiana.edu!sdd.hp.com!usc!a
   pple!snorkelwacker.mit.edu!ai-lab!rice-chex!bson
Newsgroups: comp.sys.handhelds
Subject: Re: Chip question
Message-ID: <12400@life.ai.mit.edu>
From: bson@rice-chex.ai.mit.edu (Jan Brittenson)
Date: 13 Dec 90 12:03:22 GMT
Sender: news@ai.mit.edu
References: <F002EC16567F006FAC@ISUVAX.BITNET>
Organization: nil
Lines: 75

In article <F002EC16567F006FAC@ISUVAX.BITNET> TNAN0@CCVAX.IASTATE.EDU writes:

 > I've been trying to write some stand alone (non-RPL-stack dependent)
 > programs...  What's the best way to locate and access relative memory
 > addresses?  For example, if I have a data area at the beginning of my
 > code, it seems to me the best way to access it would be to use a
 > thisone move.a pc,a" followed by a "move.p5 thisone-dataarea,c"
 > sub.a c,a" thus leaving the address

   STAR 1.02.3 and later comes with a macro ADDR in hp48.star. The
macro is used as follows:


        ADDR    location, dest


Where `location' is any expression and `dest' is either C, A, D0, or D1.
An example:

        ; ...

        addr    foo, c

        ; ...

foo:    ascii   `Hello world!'


   The code generated is much what you describe, although ADD is used
instead of SUB. A.a is used for temporary storage, unless the
destination is A, in which case C.a is used as a temporary register.
The macro can easily be modified to take an optional third argument to
specify which register to use for temporary storage.

For the insanely curious, I'll include the macro definition.

                                                -- Jan Brittenson
                                                   bson@ai.mit.edu

        macro   addr  operand, dest

        save    sym
        sym  = gensym

        save    tmp
        save    ntmp

        dest = uc^`$dest'

        if `$dest' == `A'
          tmp = `C'
          ntmp= `A'
        else
          tmp = `A'
          ntmp= `C'
        endif

        move    pc, $tmp
        $sym = .

        if (`$dest' == `D0') || (`$dest' == `D1')
          move.5 ($operand)-$sym, $dest
          swap    $ntmp, $dest
          add.a   $tmp, $ntmp
          swap    $ntmp, $dest
        else
          move.p5 ($operand)-$sym, $dest
          add.a   $tmp, $dest
        endif

        restore tmp
        restore ntmp
        restore sym

        endmacro
