HP Forums

Full Version: Free42 version 1.0 released
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

Hi all,

I just finished version 1.0 of Free42, a new HP-42S emulator.
It's not as pretty as Emu42 yet, and there's no printer emulation yet, nor is there a facility for importing/exporting programs (RAW or otherwise). All these things are planned for the next release, probably 1st quarter 2005.

Meanwhile, what you do get with Free42 is: speed (no Saturn emulation layer slowing things down; I rewrote the entire HP-42S in C) and PalmOS, Linux, and Windows support. And best of all, it's freely redistributable and requires no ROM image.

The goods are at http://home.planet.nl/~demun000/thomas_projects/free42/

Enjoy!

- Thomas

Good job! I really hope that the OpenRPN people sees this! This would be great on a small Embedded Linux device...

Best regards,

Erik Ehrling (Sweden)

hi there,

this is really cool indeed. i like the palm version, it works well, although the beep is a bit loud.

i have a few ideas that might help it to become even better. firstly, your wrestle with bcd vs binary is something ive been struggling with for some time. i can well understand your use of ieee754 not least from a performance point of view. i did the same in my implementation of scicalc http://www.voidware.com/scic.html but more and more recently i am going away from binary back to bcd. here are some things that increasingly bug me (and you). try, 2 enter .2 + .2 + .2 + .2 + .2 + 3 - you get 8.8818e-16 also, 1 enter 1e-13 + 1 - to get 9.9920e-14 both of these are really annoying.

i have an alternative implementation of the gamma function you might like,
http://www.voidware.com/gamma2.htm
http://www.voidware.com/gamma.htm

i see you need a ln1(x) = ln(x+1), here’s one i wrote for scicalc,

double ln1(double x)
{
double s = x;
double c = 2;
double t;
double s1;
if (fabs(x) >= 0.01) return log(1+x);
x = -x;
t = x;
for (;;) {
t *= x;
s1 = s - t/c;
if (s1 == s) break;
c += 1;
s = s1;
}
return s1;
}
also, i can suggest a better integ algorithm. this code i developed by trying to reverse engineer the method used on the 15c and it performs about the same,
http://www.voidware.com/rombint.htm it was part an attempt to recreate the missing solve and integ features on the hp9g
http://www.voidware.com/calcs/hp9g.htm

also, i had a substantial improvement for solve by moving from the secant method to ridder’s method as described there. i can give you some c code for ridders if you like, but i just cribbed it from numerical algorithms in C.

lastly, thanks for writing this calculator!

PS. can you supply the bmp resource files to build the windows version.

a few more discoveries.
sin(360) degrees isn’t zero. this is a bug.

also, binary is hampering mod. for example 1e50 enter 9 mod, comes out at 3 instead of 1. i had real trouble fixing this in scicalc for the same binary reasons. what i did in the end, and this approach works with similar decimal problems, is to decimalise the number by re-representing binary X by M*10^E where M is a binary integer. this is another way to tackle bcd, ie to have a binary integer mantissa and a power of 10 exponent. some decimal systems work entirely like this (ie using a binary mantissa), but the problem is that you have to cope with denomalised numbers. so anyway, what im doing is temporarily recasting X into a decimal form but i store M in my floating point representation even though it is actually an integer (that’s because ints arn’t big enough). what then happens, is that digits below M in significance are regarded as zero, although they wouldn’t be zero if kept in binary (there is implied decimal garbage if multiplied). ok, so then after effectively converting to decimal, i can algorithmically treat each part (M and E) separately eg mod(mod(M,r) + mod(10^E,r), r). how nasty!

ahah! i figured out how to build the BMP files. looks like netpbm isnt part of cygwin as standard.

[...]but more and more recently i am going away from binary back to bcd. here are some things that increasingly bug me (and you). try, 2 enter .2 + .2 + .2 + .2 + .2 + 3 - you get 8.8818e-16 also, 1 enter 1e-13 + 1 - to get 9.9920e-14 both of these are really annoying.

I suppose it depends on what you're used to. I started computer programming on a Commodore PET, 28 years ago, and one of the first things I noticed were numerical quirks like that. And even today, programming in C or FORTRAN or Java it's the same.

I don't understand what the fuss is about. I can understand it for financial applications, I guess, but even there it's hard to see what problem would be caused by having $2 plus 5 times 20 cents minus $3 come out less than one tenth of one trillionth of a cent wrong. Presumably you're going to round money amounts to two decimals before printing your bill? :-)

But all kidding aside, outside of financial applications, all you're dealing with in the example given above is a misconception of how computers store numbers, and about the limits of precision. Personally, I don't like it very much that 1/7 + 1/7 + 1/7 + 1/7 + 1/7 + 1/7 + 1/7 does not come out as 1, but that's life, or rather, that's limited precision. Just because BCD can calculate certain special cases exactly does not make it more accurate in general, and for the scientific applications I'm primarily interested in, it's accuracy in the general case that matters.

i have an alternative implementation of the gamma function you might like, http://www.voidware.com/gamma2.htm http://www.voidware.com/gamma.htm

i see you need a ln1(x) = ln(x+1), here’s one i wrote for scicalc,

Thanks! It is much appreciated. I will also take a look at your INTEG implementation and take a look at the Numerical Algorithms book. Hopefully all those improvements will make it into Free42 version 1.1.

a few more discoveries. sin(360) degrees isn’t zero. this is a bug.

Good point. I missed that -- and there's really no excuse because only a week ago, I was reading an article about the HP-91 on the HP Museum CD set, where they mention doing user-unit argument reduction for trig functions, for preventing precisely that type of inaccuracy! Oops.

also, binary is hampering mod. for example 1e50 enter 9 mod, comes out at 3 instead of 1.

Whether or not that's a bug is a matter of perspective. If you feel that an HP-42S emulator has to go to every possible length to disguise the fact that it's using binary under the hood, then that's a bug -- but if you're comfortable with the notion of binary under the hood (I am, but I suspect I may be in the minority on that issue, at least among HP handheld fans), it's different, because the number you enter as 1e50 is stored as 1.000100011011... * 2^166, and for all I know the remainder of THAT divided by 9 could well be 3 (I'd have to check but that kind of integer algebra is beyond me, as I keep finding out whenever I try to understand how modern encryption algorithms work).

The solution you suggest works, but this does not seem to me like a problem, or rather, I prefer to do things the "binary" way throughout, so I'll stick with the current fmod()-based implementation.

Still, if enough people keep complaining about the numerical behavior of Free42, maybe I'll add support for other number representations. If there is a BCD library available under the LGPL or similar, and if it includes the full complement of trig, log, etc., then I'd certainly be interested in evaluating it.

PS. can you supply the bmp resource files to build the windows version.

When I build the Windows version, I run the make-images script to create them. You can generate them from the images in the 'common' directory simply by converting the 8 GIFs and the one PBM (for the 7 annunciators, the skin, and the keyboard mask) to monochrome BMPs while enlarging them by a factor of exactly 2.

lastly, thanks for writing this calculator!

My pleasure! I'm glad you like it, even if we may not see eye to eye in the great binary-vs-decimal debate. :-)

- Thomas

Thank you very much. I like having an RPN programmable calculator that actually works on Windows. Plus I want a 42S for my collection. Sensational job!

Eddie

Good job Thomas! Your emulator will never have keyboard problems, display problems, run out of silver-oxide cells ... and being on the PC, it can travel with me without worrying about extra weight!

Thanks!

Namir

Hmm... porting it to HP-GCC for the HP-49G+ still strikes me as an interesting idea though :-)

Best regards,
Erik Ehrling (Sweden)

PS. Aren't there "out-of-the-box" decimal arithmetic packages out there? (e.g. "http://www2.hursley.ibm.com/decimal/")

Thanks for a great job!

I've found a small display issue when there is a two line alpha display at the end of a program and a softkey menu is active - such as the custom menu has been used to run the program. When this occurs, keyboard number entry does not cause the softkeys to be displayed. Instead the second alpha line is displayed on the bottom line and the data is entered in the top line.

Again, Thanks for the program

Hi Erik!

Tnx a lot 4 that link!!!

Ciao.....Mike

Hi Thomas!

Quite nice, but I assume it's still a beta version. When I enter a little test routine (LBL 00, SQRT, VIEW ST X, LASTX, DSE ST X, GTO 00) your Free42 shows "20-Byte Prgm", if I count correctly there are 9 bytes only (one for the statements LBL 00, SQRT, LASTX and 2 for the others).

Ciao.....Mike

hi thomas,

i completely agree with your sentiment regarding accuracy and representation. its one of the reasons i tried the binary route as well. since, in the main, its better. ie you get more bits of accuracy out of a given number size than in a corresponding binary version. however, its one of those things that bothers calculator people and i wanted to pass on information about some of the troubles i have had trying to make a native binary implementation behave like a decimal one. i kept thinking that there’s no fundamental reason why binary shouldn’t be adequate. i still do.

fyi, i am currently working on a 24 decimal digit number class for the openrpn project. so far it does the basic ops and square root. when i get time, i’ll add the scientific functions. this might turn into a freely available bcd library. at least, that’s my understanding of “open”.

here follows a wish for the palm version;

going over to arm native would be cool. you could keep your 1.x version as is for compatibility, but fix any bugs. also have a 2.x version that’s arm native. with this, it could use hires and therefore have a true 42s skin and use the larger screen size (ie 480x320). the additional performance boost could mean having a really superlative solve and integ implementations that are even better than a real 42s plus truly excellent program execution speed.

one other small palm wish, is the ability to tap on the shifted name without pressing the shift key.

thanks again and keep posted.

Hi Thomas,

First of all: You did a great job, amazing calculator, fast, a lot of user memory.

I have keyed in some of my programs into Free42 and I saw some differences between Free42 and a real HP42S:

I am missing the hidden matrix functions [MAX], [MIN], [FIND]

When in an alpha string the LF character is on the 23th place, then AVIEW show that character on the display, on the second row.

It is impossible to create a global label with only numbers in it. EG: LBL “1234”

When executing a Base mode command in a program, the calculator returns not to normal when the program is stopped. This little test routine shows the problem: (BINM, VIEW ST X, EXITALL). The calculator stays in Binary mode.

When the matrix editor is on, flag 65 is not set.

I don’t want to criticize you, but I want to help you making a better calculator.

Regards,
Ton van de Burgt

going over to arm native would be cool. you could keep your 1.x version as is for compatibility, but fix any bugs. also have a 2.x version that’s arm native. with this, it could use hires and therefore have a true 42s skin and use the larger screen size (ie 480x320). the additional performance boost could mean having a really superlative solve and integ implementations that are even better than a real 42s plus truly excellent program execution speed.

Rest assured that when I do get around to making an ARM version for PalmOS, it will not replace the 68k version. I'll probably build 68k-only and 68k/ARM-mixed versions for public download. As far as feature sets are concerned, again I don't know when exactly I'll get around to any of this, but the plan is to support whatever screen sizes the OS supports, regardless of whether you're on an ARM-based machine or not. (I don't know if there are 68k-based PalmOS devices with big screens, but if there are, it's no extra effort to support them as well; from a coding point of view, it's just a matter of checking the OS version and hardware characteristics and using them the best you can.) In terms of the Free42 architecture, I'll only compile ARM versions of the "core" code, while the "shell" code will remain 68k.

one other small palm wish, is the ability to tap on the shifted name without pressing the shift key.

Interesting! That hadn't occurred to me yet. It seems easy enough to support; I'll just have to add another option to the configuration dialog. Erm, I'll have to add a configuration dialog first. :-)

BTW, the fact that clicking on the label above a key also presses that key is deliberate; on really tiny screens like the m100's, I wanted to maximize the area you could hit, the reason being that my aging tendons give me tons of grief when I have to do super-accurate clicking for long periods of time. But, of course that's not to say I couldn't add something to help people whose fine motor ability is better than mine!

Thanks for the feedback -- I'm glad you like it!

Thanks for the bug report; I'm putting it on my list. I'll put a bug fix release on my web page soon, probably in a week or so. I found a couple of bugs myself too (less than a day after the release -- how embarrassing), and I'd like to put the fixes "out there" without making people wait for the next major release (major == PalmOS ARM version, printer emulation, pluggable skins... those things will take a while).

When I enter a little test routine (LBL 00, SQRT, VIEW ST X, LASTX, DSE ST X, GTO 00) your Free42 shows "20-Byte Prgm", if I count correctly there are 9 bytes only (one for the statements LBL 00, SQRT, LASTX and 2 for the others).

Actually, there are 20 bytes -- Free42 uses a different format for storing instructions. My format uses more space, but it's easier to decode... One feature I wanted especially was for numbers to be stored in binary, so you don't incur the cost of a decimal-to-binary conversion each time a program hits a "number" line. Also, all local GTO/XEQ targets are stored using 4 bytes, so all local labels are long range. All instructions are at least 2 bytes: byte 1 and the top 4 bits of byte 2 are the command code, and the lower 4 bits of byte 2 are the argument type. Take a look at common/core_globals.h if you're interested in the details.

As far as your example is concerned: LBL 00: 3 bytes, SQRT: 2 bytes, VIEW ST X: 3 bytes, LASTX: 2 bytes, DSE ST X: 3 bytes, GTO 00: 7 bytes -- for a total of 20. I'm not counting the END, which is another 2 bytes, because the 42S doesn't either. (Actually, the memory usage picture is a bit more complicated still, because I maintain an additional array of pointers to global labels and ENDs, and those array entries take up space, too -- but that is not included in the byte count at line 00.)

(When I implement program import/export, I'll support the HP-42S original program format externally, but for Free42 internally, I don't think I'll bother... Unless someone can suggest a good reason why I should! It could be done; program storage is not encapsulated particularly well at the moment but that would not be too hard to fix.)

I am missing the hidden matrix functions [MAX], [MIN], [FIND]

When in an alpha string the LF character is on the 23th place, then AVIEW show that character on the display, on the second row.

When executing a Base mode command in a program, the calculator returns not to normal when the program is stopped. This little test routine shows the problem: (BINM, VIEW ST X, EXITALL). The calculator stays in Binary mode.

When the matrix editor is on, flag 65 is not set.

Noted. These will all be fixed in the upcoming bug fix release.

It is impossible to create a global label with only numbers in it. EG: LBL “1234”

No, it's not: type LBL, CATALOG, ENTER (SHIFT, PGM.FCN, LBL, SHIFT, +, ENTER). Then you can type numbers and they will be treated as alphanumeric instead of numeric. (It's a bit awkward, I guess, but that's how the real HP-42S does it -- or did I miss an easier way?)

I don’t want to criticize you, but I want to help you making a better calculator.

And it is appreciated! Thanks for letting me know.

It is impossible to create a global label with only numbers in it. EG: LBL “1234”

My HP42S won't do that either! There appears to be no way enter a global "numeric only" label, since entering a number as the first character in a label instruction forces it to be a local label. It is possible to create a numeric only GTO "1234" instruction, but the corresponding label can't exist.

Regards,

Bruce

Simple way to create a global label with only numbers:
Choose LBL, press one of the menu keys once, type your number.

Regards,
Ton van de Burgt

Amazing. I've used the HP-42S for more than 12 years and I keep learning new things about it!

Thanks for the tip. The LBL bug will be fixed in the next release.

Tnx a lot for your detailed explanation. So I assume, the state files of your Free42 and Emu42 are not interchangable.

Ciao.....Mike

So I assume, the state files of your Free42 and Emu42 are not interchangable.

That is correct. I'm no Emu42 expert, but I believe the Emu42 state file is essentially an HP-42S RAM snapshot. Since Free42 is a complete re-write, without any use or even knowledge of how the HP-42S ROM is organized, there are bound to be major differences in storage layout.

Once I implement program import/export in Free42 1.1, I will make sure that the program files, at least, are interchangeable with those of Emu42. I hope that will be adequate... State file compatibility just seems impractical to accomplish.

Way too cool!

Thanks for doing this (though I'm sure it was not just for the betterment of your fellow man)...

I work mostly on a *nix box @ work and have been looking for an emulator for my 42S for when I leave it at home. Actually, seeing how valuable they are now, I'm tempted just to leave it at home anyway.

I don't have a good way to extract the ROM contents to try the other emulators other then to compile it manually (not attractive), so I was happy to see someone generated another solution.

Carter