ruputer

onHand

Home PcOnHand

OnHand Pc Details

HandySurf

Software

Jukebox

Store

Developer

About

Developers

onHand Manual: Compiler tips

Contents


Introduction

The CPU of the onHand/Ruputer is a panasonic PanaXSeries MN102L00/MP102L00, in which certain things that we take for granted as expert programmers of the x86 architecture doesn't apply, or are just different. Here is a list of some of the quirks that have annoyed me in the development of programs for the onhand/ruputer.

 


Tips

Header files

Linux is my devepment system and it haves it's own compiler (gcc) and header files. Somewhere in my hard disk is installed the cross-compiler (a patched gcc) to develop for the onhand/ruputer. The bad thing is that both copies of gcc share the same header files, and that isn't good for one reason:

  • The machine in which I've Linux running is a 32-bit CPU (AMD K6-II/300)
  • The onhand/ruputer has a 16-bit CPU (MN102L00/MP102L00).
Specifically, the size of int data type is different (4 bytes the x86 and 2 bytes in the panax). This makes some constants defined in the libc to have an incorrect value when compiling for the panax.

For example, RAND_MAX should be 65535 (or 32767, see below) for the onhand/ruputer and in the header files it states the correct value for x86, that is 2147483647.

Another problem is that the return values of some libc functions aren't the correct ones. For example, rand() (we need RAND_MAX to use it) returns an int and the value returned is between -32768 and 32767, when the returned value should be always positive. There are two posible fixes:

  • Set RAND_MAX to 65535 and cast the return value to unsigned short.
            #ifdef RAND_MAX
            #undef RAND_MAX
            #endif
            #define RAND_MAX 65535
            #endif
    
            unsigned short
            rand_ok(void)
            {
                    return((unsigned short)rand());
            }
    
  • Set RAND_MAX to 32767 and bit-shift right the return value
            #ifdef RAND_MAX
            #undef RAND_MAX
            #endif
            #define RAND_MAX 32767
            #endif
    
            int
            rand_ok(void)
            {
                    return((int) ((unsigned short)rand()>>1));
            }
    

Char signedness

This one have very subtle effects. Apart from the size of int, the data types of the onhand/ruputer compiler and the ones of the x86 compilers have another difference; in the C standard the signedness of char (if it's signed or unsigned when we don't specify it) is left out to the implementor. Thankfully it's only with char type and not with int or long types (they are by default signed in all platforms).

The thing to watch here is that:

  • In the x86 architecture char type defaults to signed char.
  • In the onhand/ruputer char type defaults to unsigned char.
So to try routines for the onhand/ruputer in the x86, one should have this in mind or use the compiler flags to reverse this; in the x86 we can simply say:
        gcc -funsigned-char -g progname.c -o progname
to make it behave as the onhand/ruputer does.

Call parameter stacking

In Linux x86 the parameters are thrown into the stack using the "C" calling convention, that is, last parameter is pushed first, while the ruputer uses Pascal calling convention, that is, first parameter is pushed first.

This is very important if you use autoincrement/decrement operators in some variable in the parameter list of a function call and that variable appears more than once in the aforementioned parameter list. For example:

 
Environment Code Result  
Linux/x86
int i;
i=1;
f(i++,i);
f(2,1)
onhand/ruputer
int i;
i=1;
f(i++,i);
f(1,2)

Compiler bugs

I'm using to compile for the onhand/ruputer the following compiler:

  • binutils-2.9.1
  • gcc-2.8.1
  • newlib-1.8.1
  • rutools-0.7.3
  • the libraries from the original onHandSDK

What I've found to date is that in some cases (perhaps only after sentences like "var = var2 - var3;") parameters are not passed properly to the functions (perhaps only in "myfunc(float1,Ptr1,long1);"). If this is the case, the workaround is very simple: call some dummy function prior to the "real" funcion call:

        void dummyfunc(void) {}

        void
        myfunc(void)
        {
                long Var1=1,Var2=2,Var3=3;
                Var3=Var2-Var1;
                dummyfunc();
                realfunctioncall(0.0,"Hi",Var3);
        }
I'll investigate this further, but at this moment this is all I know.
Information from my own experience, in the hope it can help someone else. Copyleft by dario@softhome.net
This text is distributed under the GNU FDL. Last updated (dd/mm/yyyy): 21/10/2001