Hello all. I hope this thread finds you well. I have a couple questions about methods of programming on the HP 50g. But before I start asking questions, keep in mind that my only programming experience is with UserRPL with the HP 50g. I have 0 experience and knowledge in programming computers.

1. Besides UserRPL, SystemRPL, and Assembly, what other methods of programming are available for the HP 50g?

2. For creating a ton of programs in the form of a library, what programming method is the best to use in terms of speed and memory?

3. I read about the HP 50g crashing with SystemRPL. What happens when it crashes? What are the dangers of programming in SystemRPL?

I want to create my own library full of programs utilizing choose boxes, screens with input forms, drawing shapes of graphs on the screen... just to name a few. And with my 1 year experience with the HP 50g, I need all the help I can get to form my own powerful libraries of programs.

For 3: have you never seen that funny "Try to recover memory" message? Even when it tries after Yes I from time to time had to reinstall everything from scratch which is annoying as one has to take care to install them in a correct order due to their memory consumption, I had a list for that purpose.

(11-04-2017 12:58 PM)Arno K Wrote: For 3: have you never seen that funny "Try to recover memory" message? Even when it tries after Yes I from time to time had to reinstall everything from scratch which is annoying as one has to take care to install them in a correct order due to their memory consumption, I had a list for that purpose.

I cannot really follow this, could you elaborate more and , if possible, share the list?

No, I don't have the list anymore. After a total reset you have to reinstall all your libraries of which extable must be taken first, otherwise you can encounter a problem with not enough memory, I have some libraries with more than 60000 bytes..., a backup must be restored last, if I forget or ommit one of the larger libraries I have to clean HOME first.
Arno

(11-04-2017 01:38 AM)Carsen Wrote: 1. Besides UserRPL, SystemRPL, and Assembly, what other methods of programming are available for the HP 50g?

I believe others have already listed the important ones.

(11-04-2017 01:38 AM)Carsen Wrote: 2. For creating a ton of programs in the form of a library, what programming method is the best to use in terms of speed and memory?

There's not really a "best for libraries" method (IMHO). It really depends on what you want to do, and the programming environments with which you are most comfortable. Any object that can be stored on your calculator (program, list, matrix/array/vector, number, etc.) can be included in a library. The 50g has a "development menu" (256 MENU will show it to you) which includes a command (CRLIB) for building libraries based on the contents of a directory on your 50g. There's a good description of how to use it in this manual in Appendix B.

(11-04-2017 01:38 AM)Carsen Wrote: 3. I read about the HP 50g crashing with SystemRPL. What happens when it crashes? What are the dangers of programming in SystemRPL?

Apologies in advance for my long response, but this needs a bit of an explanation.

When you program using standard (aka "User") RPL, each and every command executes special code to make sure that everything is safe before proceeding to perform the indicated function. For example, if you have a "/" in your program, that command first checks to make sure that there are at least two objects already on the stack, and also that they are objects that make sense for a division to occur. This is even more complex than it may first seem, as the actual method of division can vary even further depending on whether the arguments are exact integers, real numbers, complex, symbolic, algebraics, or some combination of the above. This "pre-check" is absolutely necessary to ensure that user-written programs will gracefully avoid those situations where a user has done something inappropriate (such as attempting to divide a number by a string) as well as branching to the proper method of performing the division based on what's been given. This branching aspect is common to many programming languages and is usually referred to as "overloading" a function or procedure.

In contrast, most System RPL commands don't do any pre-checking at all. They are written to assume that the programmer has already made sure that everything is OK. Furthermore, most System RPL commands are highly specific to certain object types. There are unique "division" commands for various kinds of arguments, and they are not interchangeable. You shouldn't attempt to use %/ (division for two standard-precision reals) if you have two extended reals on the stack -- there's a %%/ command for that situation. This specificity is simultaneously one of the best features as well as a dangerous one. The commands perform well because they skip all of the "safety checks" of their UserRPL counterparts. But they blindly assume that it's OK to proceed without checking.

System RPL commands will gladly attempt to do very inappropriate things if you give them bad arguments, and the results are never good when they do. At the very least, a system reset can occur. Just as likely, though: data loss, data corruption, or the complete loss of your calculator's stored data in some situations. IMHO, a hard crash is actually better than data corruption, which can sometimes go unnoticed for a long time before its impact is seen.

Yes, it's very easy to inadvertently crash your calculator with System RPL (sometimes badly). But there are also advantages besides faster operations due to the lack of pre-checks. System RPL gives you access to different object types (such as the extended reals mentioned above) and additional functionality that you can't obtain through standard User RPL (far more input form features, for example). One of my most frequently-used SysRPL features is the use of null-named locals, which is essentially a faster way to use locals in your programs than is available with User RPL. The benefits that brings to code readability/maintainability and organization are significant.

Some SysRPL programmers have reached the level where they are perfectly comfortable writing their programs and testing them on the calculator itself (and with the proper tools installed, this is easy to do). My preferred method, though, is to use Debug4x on my laptop and testing the code on its integrated Emu48 target during the development process. No matter how careful you are, you will eventually do something you never intended in your code which crashes. If you don't, you simply aren't trying hard enough. Using an emulated calculator gives you the freedom to develop without having to worry about the inevitable "reset and restore" operations that are required with crashes of the real thing. Once you've got the code working properly, copying to your calculator is all that's needed.

Having a background in programming can give you a head start on learning many of the concepts needed to write useful programs for your 50g, but it's not a prerequisite IMHO. I do, however, strongly encourage you to start with User RPL first. Not only is it safer, but it also forces you to become familiar with many of RPL's more abstract concepts and features before being exposed to the nitty-gritty details of how they are actually implemented in something like SysRPL.

Just to share some of my own experience of working with SysRPL/ASM development directly on the calculator itself (my preferred way of developing because I can do it anywhere):

(11-04-2017 05:02 PM)DavidM Wrote: IMHO, a hard crash is actually better than data corruption, which can sometimes go unnoticed for a long time before its impact is seen.

I learned that one the hard way. I've lost count of how many times I've discovered odd corruption in variables and programs, seemingly out of nowhere, days or even months after doing some low-level development and wondered how in the world that happened. Or the even better question, when. Bad system-level code can result in garbage bytes being overwritten into variables. If this happens to programs (UserRPL included, as there's no internal distinction between compiled User- and SysRPL code), the result of executing the corrupted part of the program is usually that the OS will jump to an arbitrary execution address, resulting in a lockup, reboot, or generally anything but what was intended and expected.

I've also had corruption apparently occur to the file system itself, resulting in unexpected crashes when navigating (in the Filer, for instance) or trying to manipulating directories when it otherwise appeared as though nothing was wrong. Recovering from that was a particularly time-consuming mess. I no longer remember what I did (this was several years back), but I probably had to salvage as many individual variables as I could and copy them to fresh directories (while backing up frequently for the inevitable further crashes I hit during the recovery process).

So, my practice eventually evolved into the following:

1. Have a small program to write an archive of HOME to the SD card, each one to a separate file (maintaining a full backup history is important to find fresh copies of variables in case of undetected corruption that occurred at an unknown point in time; the SD card has enough room for practically a lifetime's worth of backups )

2. Assign the backup program to a key for convenient backups on the fly, anytime

3. Every time I'm about to run new ASM/SysRPL code, press the backup key

4. If a crash occurs (or anything strange at all, for that matter), immediately do an [ON]+[A]+[F] reset and answer “no” to the “Try to Recover Memory?” prompt. Instead, reload the latest backup from the SD card to ensure a fresh copy of all HOME variables is reloaded.

That might sound like a pain, but it's not too bad (other than waiting a few seconds) because a lot of it can be automated. I have the assigned keystroke to automatically store a HOME backup, and I have a routine somewhere in a custom library stored in Port 2 to detect on startup if RAM was cleared and automatically prompt for restoring the latest SD card backup if so. So I crash, press [ON]+[A]+[F], [NO], [OK], then I'm back in business, ready for another try.

All of my questions that I posted above have been answered. Thank you all so much!

I have decided to master UserRPL and then proceed to learn SystemRPL. This is because UserRPL is the most familiar and comfortable method of programming I know. The main purpose of learning systemRPL for me is increasing the speed of the program and doing the "impossible" with the HP 50g.

I also decided to use Emu48 for SystemRPL and I thank DavidM for the idea and that lengthy explanation for question 3 (I understand it mostly because of the material and research I have read about SystemRPL vs UserRPL).

(11-05-2017 06:07 AM)Carsen Wrote: I have decided to master UserRPL and then proceed to learn SystemRPL. This is because UserRPL is the most familiar and comfortable method of programming I know. The main purpose of learning systemRPL for me is increasing the speed of the program and doing the "impossible" with the HP 50g.

This is how I got into SysRPL. I became familiar with UserRPL first, and when I felt I was ready, I started working toward SysRPL in small steps. The nice thing is that since the two are internally one and the same language, it's trivial to mix User- and SysRPL routines. So you can start out by writing a full program in UserRPL, then add some very small, simple bits of SysRPL in just a few specific places where you need some extra speed or need to do something UserRPL can't. As you become more comfortable with SysRPL, you may find yourself gradually using more and more SysRPL in your projects.

Another useful thing to do with SysRPL is creating new commands by writing your own small wrappers around SysRPL objects or calls so that you can use them conveniently from UserRPL code, thereby extending the user language. There are a lot of useful built-in SysRPL routines which are sadly not available from UserRPL out of the box… but you can change that! This is a good way to practice writing the SysRPL code for doing the proper argument checking, object conversion, etc., needed to safely interface with UserRPL code.

Quote:One last question. Is Assembly different from System RPL?

Yes. The 50g has two types of ASM: There is the assembly language for the Saturn processor, which is emulated on the 50g, and this is what most of the low-level parts of the original calculator system are written in (including the Sys/UserRPL implementation itself); and there is the assembly language for the actual ARM processor the 50g uses, which contains the Saturn emulator and the software interfacing the hardware to the emulated Saturn-based OS. The higher-level parts of the Saturn system are largely implemented in (Sys)RPL code.

I haven't dealt with ASM much, so others will probably be able to answer that better.

(11-05-2017 06:07 AM)Carsen Wrote: One last question. Is Assembly different from System RPL?

Yes, very different. There's two different types of assembly on a 50g (Saturn and ARM), but when you see the term tossed about it is usually referencing the Saturn variety. That's what I'll focus on here.

Assembly programs are the closest representation of code to what the CPU actually processes at its lowest level (which is sometimes called "machine code"). In the case of Saturn assembly on a 50g, the O/S of the calculator emulates an enhanced Saturn CPU; the physical CPU is an ARM processor, but the Saturn machine code is interpreted and processed by the O/S as if it were an enhanced Saturn CPU instead.

Writing assembly programs requires a detailed understanding of many important aspects of the targeted environment. Exact data formats, addresses of important subroutines and O/S variables, standards for how "upper level" processes work and their protocols, etc. are all critically important.

Each UserRPL command you use in a program can be "traced" to a subroutine of some kind, which is usually a SysRPL subroutine. Each SysRPL command can be similarly traced to either more SysRPL commands or, ultimately, to Saturn code. And sometimes, these "levels" are skipped or restarted in the chain of commands.

To get a taste of how this works, consider the User RPL command "DROP" (which internally goes by the name of "xDROP"). It's a relatively simple function, right? All it does is to remove the object in stack level 1, and all other objects shift down in position to "fill the void" left by that action.

The UserRPL DROP command is actually a call to a SysRPL subroutine:

Code:

xDROP
::
CK1
DROP
;

The :: and ; are similar in function to the « and » you use in UserRPL. CK1 actually does quite a bit, but for now I'll just highlight that it makes sure there's already something to drop before proceeding. This is critical for the reasons mentioned in previous posts. Without that check, the following SysRPL DROP command would charge ahead making the required low-level changes to the RPL environment assuming that it was OK to do so. If that SysRPL DROP was executed with nothing on stack, it would set up a pending failure that shows up as soon as you (or more specifically some other command) tries to add something else to the stack. And it's a major, data-loss-assured crash.

So if something is on the stack to be dropped, what happens then? Well, the SysRPL DROP immediately jumps to a series of Saturn steps:

Code:

D1+5
D=D+1 A
A=DAT0 A
D0+5
PC=(A)

Knowing exactly what those steps are doing isn't important here, but suffice it to say that the only reason they achieve the intended purpose is because of how the RPL environment is designed to operate. The CPU doesn't "know" anything at all about the user stack -- none of those steps actually destroy stack data or move all of the other stack objects into new positions. They work only because of how the RPL environment is designed to operate, and the programmer who wrote them could only do it from knowing the low-level aspects of how stack data is organized in memory and processed, and the proper way to jump back to "regular RPL stream processing". Those are meaningless concepts to the CPU, and are simply designed by convention into the RPL operating environment.

Those 5 Saturn steps operate at the lowest level achievable for the emulated Saturn processor on the 50g. As such, they are very fast. DROP is actually one of the fastest commands you can execute on the calculator. It's difficult to time just those steps, but you can measure the UserRPL DROP command fairly easily -- it's about 8ms on my 50g.

Finally, assembly programs take up a lot of space. While the above example is actually fairly small, that's not the norm. It's not so much that the individual steps take more memory than individual steps in higher-level languages, but rather that it takes many more individual steps to do even simple things in assembly.

An analogy that may help to clarify this: imagine that you (as the programmer) are giving instructions to a programmable robot to move a box from one spot to another. Using a "high level language" (such as UserRPL), you might say "move the blue box from point A to point B". The robot will ultimately translate that statement into a myriad of individual steps that will achieve the goal. That translation will take some time, but it's easy and simple to deliver such a short message.

Now imagine that you want to achieve the same goal, but instead of the short message above you have to deliver each and every detailed step of how to perform that function to the robot:
- set orientation change to -12 degrees
- activate rotational position motors
- set distance counter to 6 feet
- activate forward motion motors
- raise left arm 12 inches
- raise right arm 12 inches
- set distance counter to 1 foot
- activate forward motion motors
...

The robot wouldn't need to do much translating of those steps, so it could execute them quickly after receiving them. But the quantity of steps needed to achieve the same goal goes up exponentially. That's why assembly programs tend to be larger -- there's a lot more highly detailed steps to be done at that level.

Once again, a long answer. But the salient points here:
- All code executed on the 50g is ultimately machine code, but there's multiple "layers" to go through before it gets to that point.
- There exists a hierarchy of code environments, and assembly is at the bottom (or more accurately "just above the bottom").
- Writing assembly code requires detailed knowledge (and access to a wealth of technical documentation) about the targeted environment.
- Assembly programs will generally be the fastest available for a given CPU.
- Assembly programs are usually larger than their higher-level counterparts.

My intent here is not to scare you away from any of this, but rather to give you an idea of the scope of what's ahead of you. Many people have successfully gone through this learning process, and the early adopters didn't even have the benefit of the wealth of information which now exists for doing this sort of thing. Your decision to start with UserRPL is a wise one, and will pay off in the long run.

A very rough rule of thumb is that SysRPL is about 5 times faster than UserRPL; Saturn assembly is about 5 times faster than SysRPL, and ARM assembly (or C code) is about 5 times faster than Saturn assembly.

HPGCC has an interesting trade-off: programs are about 100 times faster than their UserRPL equivalents, but they are also about 100 times larger. You can avoid taking the space in your HOME directory by storing the programs on an SD card, but you still need the RAM to run them. I find that it takes about 0.25s to load a C program from the SD card.

When using C code, it's best to have a UserRPL or SysRPL driver program that handles the user interface stuff and then just do the computing in C. I'll also toot my horn and suggest my hpobjects library for hpgcc2. The library makes it relatively easy to read and write calculator objects with your C program.http://www.hpcalc.org/details/7177

(11-06-2017 09:30 PM)David Hayden Wrote: A very rough rule of thumb is that SysRPL is about 5 times faster than UserRPL; Saturn assembly is about 5 times faster than SysRPL, and ARM assembly (or C code) is about 5 times faster than Saturn assembly.

(11-06-2017 09:30 PM)David Hayden Wrote: HPGCC has an interesting trade-off: programs are about 100 times faster than their UserRPL equivalents, but they are also about 100 times larger. You can avoid taking the space in your HOME directory by storing the programs on an SD card, but you still need the RAM to run them. I find that it takes about 0.25s to load a C program from the SD card.

This paragraph doesn't apply to hpgcc3, where programs have a size around 30% larger than sysRPL while keeping the speed advantage.

(11-06-2017 09:30 PM)David Hayden Wrote: When using C code, it's best to have a UserRPL or SysRPL driver program that handles the user interface stuff and then just do the computing in C. I'll also toot my horn and suggest my hpobjects library for hpgcc2. The library makes it relatively easy to read and write calculator objects with your C program.http://www.hpcalc.org/details/7177

Actually, hpgcc 2.0 is more useful when creating the user interface in C. Entering/exiting the C program has a significant overhead, so going back and forth from UserRPL to C is probably not the best idea. HPGCC3 solves this issue, with very light overhead and small program size. This is much better suited to code small routines and call them in a tight loop from userRPL.

Each has its separate target audiences: hpgcc2 is easier to get started on, but less refined (big executables) and cumbersome to use (need a library and run the C code through another command). It's easy to publish code for others to run.
hpgcc3 takes a bit longer to setup, since you have to compile your own ROM, but once you get to the point to compile the ROM, you are ready to code with a complete IDE environment. It's much more refined (programs evaluated with EVAL just like any other program, faster startup, smaller size, more complete libraries, easier to port C programs from other platforms, etc), but publishing programs is a bit more difficult since final users need to have an hpgcc3 modified ROM, which is not published. Now that the 50g is discontinued, perhaps uploading an hpgcc3 ROM to hpcalc.org wouldn't trigger any response from HP. This would make it just as easy for final users.

Thank you for the detailed explaination DavidM. I understand most of it. I'm not scared of learning it but right now, I see no use for Assembly in my applications. I am content with the increase of speed going from UserRPL to SysRPL. I believe SysRPL is as far as I should go, after learning UserRPL no less.

Claudio L. Wrote

Quote:I think you are a couple orders of magnitude short on the speed of C/ARM Assembler. The HPMuseum Calculator Benchmark by Xerxes gives a pretty good idea of relative speeds of various languages.

This chart is so cool! It's fun to see how programming the HP 50g with different methods makes it one of the fastest - even compared to the Prime! I like seeing how the speed went from 22.6 seconds to 2.32 seconds just from changing from UserRPL to SysRPL.

I also learned that NewRPL is created using Assembly Language (the ARM version) in a video. It's a great example to see what Assembly can do in my opinion. Of course, I don't aspire to don a project THAT massive.

(11-07-2017 09:11 PM)Carsen Wrote: Thank you for the detailed explaination DavidM. I understand most of it. I'm not scared of learning it but right now, I see no use for Assembly in my applications. I am content with the increase of speed going from UserRPL to SysRPL. I believe SysRPL is as far as I should go, after learning UserRPL no less.

If speed is all you are looking for, newRPL is very close (nearly identical) to userRPL, and the result is faster than sysRPL (in those benchmarks newRPL is running *exactly* the same code as the userRPL entry), so I'm not sure sysRPL would be a good choice for a second language. If your objective is learning (rather than speed), perhaps C would be more useful, since it's more common in many platforms. Lua is also quite common in video game engines and in many applications as scripting language. I'd think learning C or Lua might get you a job in the future. But you have time to decide.

You have a point. Learning C language is a valuable skill in the workforce. And it could be a skill that helps me get my first professional job (along with my future degree of course).

Ahh, NewRPL. I think you (Claudio L.) are the main creater of NewRPL, are you not? I have researched quite extensively on NewRPL to see what it was all about. It seems like a fantastic new OS for the HP 50g with quite a impressive set of boons, especially the speed of it's programs and how programming is almost the same as UserRPL. But what holds me back from using it is I have read it does not have a CAS system at the moment. Sadly, that is a feature I rely on all the time. Also, I have am a little wary of messing with my HP 50g's original OS. I want to be certain that I can restore it to its factory OS if NewRPL isn't my style - which I highly doubt.

Right now, I have narrowed my choices to SysRPL because I heard it is similar to UserRPL. NewRPL because I have high hopes for the project. Lastly, C because of its powerful use outside programming the HP 50g.

(11-10-2017 05:43 AM)Carsen Wrote: Ahh, NewRPL. I think you (Claudio L.) are the main creater of NewRPL, are you not?

Yes, newRPL, hpgcc 2.0 and hpgcc3 as well.

(11-10-2017 05:43 AM)Carsen Wrote: Also, I have am a little wary of messing with my HP 50g's original OS. I want to be certain that I can restore it to its factory OS if NewRPL isn't my style - which I highly doubt.

You can go back and forth freely between newRPL and the stock firmware in a matter of 2 minutes (time it takes to flash the firmware and recover your last backup).
No calculators have ever been bricked by newRPL, since it uses the standard bootloader that comes with your calc from the factory. That guarantees you'll always be able to recover.
Same thing applies if you decide to install an hpgcc3 ROM to program in C. My calc has had hpgcc3 in ROM since 2006, you don't know it's there until you run a C program.

(11-10-2017 05:43 AM)Carsen Wrote: Right now, I have narrowed my choices to SysRPL because I heard it is similar to UserRPL. NewRPL because I have high hopes for the project. Lastly, C because of its powerful use outside programming the HP 50g.

In this forum you'll find the right people to help you along the way with each of those languages, so stick around and enjoy your new calculator.

Oh yes Claudio. I expect to be at the MOHPC for a long time now. And you have convinced me to try UserRPL after this semester is over and head into winter break. I'm really dependent on my HP 50g at the moment and I'm suppose to be studying too.