Copyright (C) 1994, 95, 96 Alex T. Ramos. All rights reserved. Licensed for use under the terms of the GNU Public License.
This is free software. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You are allowed to make and redistribute copies of this package, under certain terms and conditions. Please read the enclosed COPYING and COPYING.LIB file for details. The author, Alex T. Ramos, may be reached by e-mail as alex_ramos@users.sourceforge.net .
Please note that CLASS, CLLD, and the LKV library were written by Lutz Vieweg and are bound by a different licence. Please read the documentation in the class directory within the package. Likewise, OBJDUMP was written by Eddie C. Dost and has its own license terms. Eddie's contributions to the compiler and libraries, however, are under the GNU licence.
hp48xgcc is a C cross-compiler. It is a program that runs on your workstation, and translates C code into objects that can be executed on the HP48. It is based on (well, that's an understatement) the GNU C Compiler (gcc), therefore it supports the complete C language and not just a subset.
hp48xgcc, the package
Long File Name UNZIP for Windows 95
GNU Make
gcc source code
This manual
Please keep mind that if you have never programmed in C on a Unix system, you'll have a significant learning curve ahead of you. Otherwise, this will be a snap:
First, make sure xgcc (or xgcc.exe, on Windows95) is installed in /usr/bin (c:\usr\bin), and the compiler libraries are installed in /usr/lib/gcc-lib/saturn-local-hp48/2.x.x. This is how everything comes out of the ZIP file, so if you haven't mucked up the directory structure you should be ok. For convenience, you'll want to add /usr/bin to your PATH permanently, by editing AUTOEXEC.BAT on Win95, or .*shrc / .profile (which one exactly depends on your site) on Unix.
xgcc works almost exactly like the Unix gcc, except that the output binary can only be executed on an HP48 handheld calculator.
The simplest usage case (compile "prog.c" into an executable
called "prog") is:
xgcc prog.c -o prog
Most of the standard GCC options are supported (read the GCC manual), the notable exceptions being "-g" and "-p", and some others which don't make sense on the HP environment. It is highly recommended that you *always* use the -O2 (maximum optimization) option, or the executables might not fit in your HP. That's dash-oh-two, not "zero two", by the way.
If your package was installed in some random directory other than /usr (c:\usr), you'll have to use the -B option or the GCC_EXEC_PREFIX environment variable (again, read the GCC manual). This option is usually a pain in the neck to get to work right (should it point to the top, the parent, the machine-specific directory, or the version-specific directory? when does it require a final slash? I can never remember).
There are some examples that come with the package, they are in /usr/saturn-local-hp48/samples. Run make there to compile all examples, and make install to copy them all to the download directory. See below on how to run them. Note that there are two download directories, one in the samples directory, the other one up two levels.
Before you start, you need to setup your HP with the shared C libraries and the dynamic linker. There's not much setting up actually, you just need to download them. They are in the /usr/saturn-local-hp48/download directory. GCCLDD and libgcc.sl are required. The other libraries are optional, and you'll know you need one if its name comes up on the stack when you try to run a program that requires it.
Compiled programs have no further dependencies other than the linker and the libraries listed above. Therefore, to run a C program in the future, just download it to the HP, and start it either by name or from the menu just like any user-written RPL program. Of course, you can also invoke it from RPL programs, assign it to a key, etc.
When downloading, there are 2 common problems: One - the Unix kermit file transfer defaults to ASCII mode, and you need to set it to binary or else the download gets corrupted. And Two - some versions of Kermit insist on mangling the filename beyond recognition (e.g. it might change libgcc.sl to LIBGCC.SLX). If this happens, be sure to rename the object once it's in the HP. The world is case-sensitive, so keep in mind 'gccldd' is not the same as 'GCCLDD'. This is probably not an issue with X-Modem. The correct name is GCCLDD all-caps, but all the libs are lowercase.
IN THIS VERSION, argc is always zero and argv is always NULL. It will be fixed later. In the meantime, use the macro _STACK to get to the HP's data stack. e.g.: _STACK(0) returns a pointer to the object that is at the top of the stack. In keeping with the C spirit, no bounds checking is made, and you can crash your HP by trying to access stack levels that are not there.
Unsigned comparison is faster & smaller than signed comparison on the HP48. That's because the Saturn processor doesn't have signed arithmetic, and it has to be emulated.
short int i; for(i=0; i<1000; ++i) /* BAD */ unsigned short int i; for(i=0; i<1000; ++i) /* GOOD */ if (c >= 'A' && c <= 'Z') /* GOOD - chars are unsigned */
This performance problem only affects the inequality operators, since
all other arithmetic is indifferent to your perception of signedness.
char 8 bits, short 16 bits, int 32 bits, long 32 bits, long long 64 bits, float 64 bits, double 64 bits, long double 128 bits, pointers 20-bits-stored-as-32-bits Unimplemented features: long double, stdio, libc - Non-optimizing compilation is not supported. Therefore you must always use the -O2 (dash-oh-two) flag. - Global variables retain their values accross program executions!
This section might be out of date. Just to be safe, check the value of PARM_ALLOC_ORDER in local-hp48.h before you depend on this: frame pointer: D1 stack pointer: R1 struct value: D static chain: D0 function parameters: B, R0, R2, R3, R4, then stack. function return value: C The current implementation uses the "caller saves" convention - all functions are free to clobber any registers they wish, EXCEPT the frame and stack pointers and the P register. The P register must be restored to the value 7 before returning to the "C" caller.
This is for my own reference, as well as for anybody else who wants to run the C-torture (v1.34) compiler test suite. 940409-1 (4) This one is correct to fail. (Fails on all systems). 930326-1 (4) "Initializer too complex" (gcc-2.6.x) (exit 1) "Initializer not computable at load time" (gcc-2.7.0) (exit 1) This is correct, because this test depends on byte pointers. On usual systems the value is: (&f + 2) - (&f + 1), but for the HP48 with 4 bit addressing the value to compute would be ((&f + 4) - (&f + 2)) / 2 initializer_constant_valid_p () in c-typeck.c can only handle PLUS_EXPR and MINUS_EXPR, *NOT* EXACT_DIV_EXPR. (Try substituting 'char' with 'int', and gcc will fail on any system). Total: 8 expected failures.
...please, share your question (and the answer) with other hp48xgcc enthusiasts by sending it to the mailing list! For general HP48 help, try also comp.sys.hp48 and (for C Language questions) comp.lang.c. Please be aware that if you email me any hp48xgcc questions directly, I will "Carbon Copy" to the mailing list in my reply.