Post Reply 
HP48GX - Simple Program Question
08-28-2019, 09:34 PM
Post: #1
HP48GX - Simple Program Question
For the 48GX I created some simple programs, things that will take user entries, bring up the Solver, run that, etc. Or calculate several different things for me based on what I input. Just really, really simple stuff that just calculates and manipulates the stack.

When I use the Connectivity Kit and then pull up these things in a text editor I notice that there's a certain width and then (apparently) a carriage return to the next line.

My question is, if I edit these things and the width of a given line is longer than what I see represented in existing programs, will it error out on me?

Thanks for your help!

Thanks!

-Matt
Find all posts by this user
Quote this message in a reply
08-28-2019, 09:45 PM
Post: #2
RE: HP48GX - Simple Program Question
(08-28-2019 09:34 PM)MattGreer Wrote:  For the 48GX I created some simple programs, things that will take user entries, bring up the Solver, run that, etc. Or calculate several different things for me based on what I input. Just really, really simple stuff that just calculates and manipulates the stack.

When I use the Connectivity Kit and then pull up these things in a text editor I notice that there's a certain width and then (apparently) a carriage return to the next line.

My question is, if I edit these things and the width of a given line is longer than what I see represented in existing programs, will it error out on me?

Thanks for your help!

No, the program source content is pretty much free-form (though there could be a line limit of 255 or something high likes that), but the machine renders the lines into shorter segments to reflect how they will appear on the 48 LCD, and be easily edited.

Long lines do work, the editor scrolls the whole window, but it's not too useful since you can't see the start of the next/prev lines when you're out past the screen edge on the current line.

--Bob Prosperi
Find all posts by this user
Quote this message in a reply
08-29-2019, 07:56 AM (This post was last modified: 09-11-2019 05:23 AM by Giuseppe Donnini.)
Post: #3
RE: HP48GX - Simple Program Question
The following chart might help you understand what is really going on under the hood.


           «                While a program is being typed in, it
 TEXT       SIN             merely exists as a text string--in a
STRING      3.1415 *        format freely chosen by the user.
           »
               |
               |            Once [ENTER] is pressed, the string is
            PARSING         parsed and potential syntax errors
               &            are catched.  If there are no errors,
           COMPILING        the string is converted into a proper
               |            program object.
               |
               v
        +-------------+
        |D9D20E1632CA4|     Regardless of the format in which the
PROGRAM |B133920000000|     text string was originally entered,
OBJECT  |0000514130EED|     this internal representation will
        |A193632B2130 |     always have the same bit pattern.
        +-------------+
               |
               |            If the system later needs to display
               |            the program in a readable form, it will
               |            reconvert a copy of the program object
               |            into a text string according to certain
               |            rules.  For example, if the purpose is
               |            to show the program on the stack, the
               |            conversion will take into account the
               |            current display mode, e.g. if 2 FIX mode
               |            is active, 3.1415 will be displayed as
               |            3.14.  If on the other hand the purpose
               v            is to display the program in the editor,
               |            real numbers are shown in STD notation
               |            to avoid loss of precision; program
               |            structure words, like IF...THEN...END,
               |            are indented according to their level of
               |            nesting to make them stand out, etc.
               |            All this, however, does NOT in any way
               |            change the internal representation of
               |            the program.
               |
               +--------------------+--------------------+------------------+
               |                    |                    |                  |
         DECOMPILATION       DECOMPILATION         DECOMPILATION           etc.
          FOR EDITING          FOR STACK             FOR ASCII
               |            DISPLAY (2 FIX)        FILE TRANSFER
               |                    |                    |
               v                    v                    v
 TEXT    « SIN 3.1415 *      « SIN 3.14 * »      ( determined by )
STRING   »                                       ( TRANSIO value )


So in the end—as Bob already pointed out—the resulting program object will always be the same, whether you changed the line length of your source code or not.

But the very fact that you wanted to adjust it is quite interesting, because it reveals an actual problem: what might be a convenient format for the calculator's screen might become a real headache on a PC, and vice-versa. Unfortunately, when you transfer a program to the PC in ASCII mode, the line wrap width is automatically set to the HP-48's system default of 19 characters per line. Even if the nesting level of your program is only moderately deep, the result can be quite confusing on a PC screen.

The easiest solution to this problem is to convert the program to a string (using \->STR) before sending it to the PC. As a matter of fact, \->STR uses a line wrap width of 0, while still indenting all the program structure words. The contrast between a direct ASCII transfer:


%%HP: T(3)A(R)F(.);
\<< \-> test
  \<<
    IF DUP SIZE 1 >
    THEN OBJ\-> DUP 2
/ 1 + ROLL NEWOB \->
x
      \<< { } { } 2 4
ROLL
        START ROT
          IF DUP x
test EVAL
          THEN ROT
+ SWAP
          ELSE +
          END
        NEXT test
GSORT SWAP test
GSORT x + SWAP +
      \>>
    END
  \>>
\>>


and one preceded by \->STR:


%%HP: T(3)A(R)F(.);
\<< \-> test
  \<<
    IF DUP SIZE 1 >
    THEN OBJ\-> DUP 2 / 1 + ROLL NEWOB \-> x
      \<< { } { } 2 4 ROLL
        START ROT
          IF DUP x test EVAL
          THEN ROT + SWAP
          ELSE +
          END
        NEXT test GSORT SWAP test GSORT x + SWAP +
      \>>
    END
  \>>
\>>


speaks for itself, I think.

[The program used for the sake of illustration is Bill Wickes' GSORT (General-purpose Sort) program, which you will find on p. 328 of his excellent book "HP-48 Insights — I. Principles and Programming of the HP-48 — HP-48G/GX Edition," Corvallis 1993.]

But what if you need a specific line width? What if neither 19 nor 0 fits your bill? Take for example a long list of several hundreds or even thousands of numbers. You definitely don't want those displayed on a single line in your PC text editor! What you most probably want is one number per line, but a line wrap width of 19 will almost certainly produce something very different—and very messy.

So here is a little utility which I wrote for my own purposes that lets YOU specifiy the line wrap width (a compiled version is attached to the posting):


*******************************************************************************
* DCMP
*******************************************************************************
* ABSTRACT : Decompiles an object in standard display format, breaking down the
*            resulting string into lines of specified length.
*
* STACK    : ( ob %len --> $ )
*
*            * If %len = 0, no newlines are added after decompilation.
*
*            * If %len > 255, a line length of %len MOD 256 chars will be used.
*
*            * If ob is a string, no decompilation takes place, but newlines
*              are still inserted according to %len (if the latter is zero, the
*              string remains unchanged).
*******************************************************************************
ASSEMBLE

* Binary transfer header ; remove if compiled directly on the HP-48.

        NIBASC /HPHP48-A/

* Unsupported, but stable entry points:

=ResetSTKDC  EQU #159B4
=ederr       EQU #15A40

RPL

::
 0LASTOWDOB!     ( *Clear command name* )
 CK2NOLASTWD     ( *Require 2 arguments ; don't save command name* )
 CKREAL          ( *Require real on stack level 1* )
 ResetSTKDC      ( *Declare decompilation for editing, not for stack display* )
 COERCE          ( ob #len --> )
 !DcompWidth     ( ob --> ) ( *Set line length* )
 savefmt1        ( *Save user's wordsize & display format ; set 64bit & STD* )
 ERRSET          
   editdecomp$w  ( $ ) ( *Decompile using specified line length* )
 ERRTRAP         
   ederr         ( *If an error occurs, do rstfmt1 before erroring out* )
 rstfmt1         ( *Restore user's wordsize & display format* )
;


To carry on the list example above, just put your list on stack level 2, the real number 1 on stack level 1, and run DCMP. Theoretically, this would insert a line break after every single character, but since whole words are never broken up, the result will be the desired one-number-per-line format.

Compare the uses of:

—  \->STR or  0 DCMP  (no line wrapping):

%%HP: T(3)A(R)F(.);
{ 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400 }


—  normal ASCII transfer or  19 DCMP  (line wrap width = 19):

%%HP: T(3)A(R)F(.);
{ 1 4 9 16 25 36 49
64 81 100 121 144
169 196 225 256 289
324 361 400 }


—  and  1 DCMP  (line wrap width = 1):

%%HP: T(3)A(R)F(.);
{
1
4
9
16
25
36
49
64
81
100
121
144
169
196
225
256
289
324
361
400
}


Attached File(s)
.zip  DCMP.zip (Size: 185 bytes / Downloads: 3)
Find all posts by this user
Quote this message in a reply
08-29-2019, 10:00 AM (This post was last modified: 08-31-2019 05:44 AM by Giuseppe Donnini.)
Post: #4
RE: HP48GX - Simple Program Question
(08-28-2019 09:45 PM)rprosperi Wrote:  [...] though there could be a line limit of 255 or something high like that [...]

The maximum decompilation width is indeed 255. The System RAM variable DcompWidth which holds the pertinent information, is two nibbles wide, allowing for values between 0 and FF hex or 255 decimal.

DcompWidth is set by the Primitive Code Object !DcompWidth which takes a system binary integer (5 nibbles) as an argument, but only the two least significant nibbles of the latter are taken into account:


        D0=(5)  =DcompWidth   
        DAT0=A  B               * with A[A] containing the body of the bint


Or, to put it differently, any argument for !DcompWidth is taken modulo 256 while being written to DcompWidth.

[DcompWidth is located at address #70770h in the HP-48SX, and at address #808EEh in the HP-48GX; !DcompWidth is a supported entry point at #1795Ah.]
Find all posts by this user
Quote this message in a reply
08-29-2019, 12:52 PM
Post: #5
RE: HP48GX - Simple Program Question
Really nice, clear and thorough explanation Giuseppe!!

And a useful and thoroughly documented SysRPL utility as a bonus. Smile

Consider this post bookmarked for future inquiries...

--Bob Prosperi
Find all posts by this user
Quote this message in a reply
09-08-2019, 11:00 PM
Post: #6
RE: HP48GX - Simple Program Question
Giuseppe, that's amazing. Thank you!

Thanks!

-Matt
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)