分享
 
 
 

GCC programming tricks for the PalmPilot

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

All code snippets presented here are public domain, feel free to use them in your own Pilot programs!

Having more than 32k code

Interfacing to IEEE floating point system traps

Printing and scanning IEEE floating point

Having more than 32k codeIt has often been said, that this is not possible, but this is wrong. In fact, there're two ways to overcome the 32k limit. The first one is using shared libraries, which has some problems (e.g. accessing global data) and the second one is described here.

Your PilotMain() is not the first function called when your app starts. The (normal) entry point is a function start(), which is buried in the object module crt0.o. (This module is automatically put at the beginning of the code section by the linker) start() relocates the data segment and calls some "hooks" (I don't know, what these hooks exactly do, but it seems that you need them).

The PalmOS starts an app by simply jumping to adress 0, where the start() function is put by the linker.

Now here comes the problem: start() is at the very beginning of the code segment, then your code follows and the hooks are at the very end, so to call the hooks from start(), they must be within 32k (the range of the relative branch instructions of the 68000), so normally your code mustbe <32k.

/

start()

<32k

your code

hooks

Now the trick is to put start() in the middle of your objects and provide an entry function myStart() at adress 0, which simply calls start().

When start() is within 32k of myStart() and the hooks are within 32k of start(), you have TWO 32k ranges to put your code. Of course you must ensure (by shuffling your functions and objects) that calls between your functions don't exceed the 32k branch limit.

/

myStart()

<32k

your code

/

start()

<32k

more of your code

hooks

That's the theory, to make this work you have to do the following:

Increase the coderes size in the file pilot.ld. Here's mine: MEMORY

{

coderes : ORIGIN = 0x10000, LENGTH = 65535

datares : ORIGIN = 0x0, LENGTH = 32767

}

SECTIONS

{

.text :

{

*(.text)

. = ALIGN(4);

bhook_start = .;

*(bhook)

bhook_end = .;

. = ALIGN(4);

ehook_start = .;

*(ehook)

ehook_end = .;

} > coderes

.data :

{

data_start = .;

*(.data)

} > datares

.bss :

{

bss_start = .;

*(.bss)

*(COMMON)

} > datares

end = ALIGN( 4 );

edata = ALIGN( 4 );

}

Compile the following file (start.c): extern unsigned long start();

unsigned long myStart()

{

return start();

}

Link with a command like this:

$(CC) $(LDFLAGS) -nostartfiles start.o some objects $(CRT0) more objects $(LIBS) -oyourprog

The option -nostartfiles tells the linker not to automatically use crt0.o as the first object.

Interfacing to IEEE floating point system trapsGCC doesn't handle NewFloatMgr.h correctly (in version 0.5.0). On the other hand, using arithmetic operators like + in a C program use the emulated operations from the C runtime library, not the Pilot system traps, which creates bloated PRC files.

The following code snippet shows how to access the system traps with GCC. #define _DONT_USE_FP_TRAPS_ 1

#include <Common.h>

#include <System/SysAll.h>

#include <SysTraps.h>

#include <System/NewFloatMgr.h>

void SysTrapFlpLToF(FlpDouble*, Long) SYS_TRAP(sysTrapFlpEmDispatch);

/* convert a long to double */

double longToDouble(long l)

{

FlpCompDouble fcd;

asm("moveq.l %0,%%d2" : : "i" (sysFloatEm_d_itod) : "d2");

SysTrapFlpLToF(&fcd.fd, l);

return fcd.d;

}

Long SysTrapFlpFToL(FlpDouble) SYS_TRAP(sysTrapFlpEmDispatch);

/* convert a double to long */

long doubleToLong(double d)

{

FlpCompDouble fcd;

fcd.d = d;

asm("moveq.l %0,%%d2" : : "i" (sysFloatEm_d_dtoi) : "d2");

return SysTrapFlpFToL(fcd.fd);

}

void SysTrapBinOp(FlpDouble*, FlpDouble, FlpDouble) SYS_TRAP(sysTrapFlpEmDispatch);

/* the same interface is used for all basic arithmetic operations */

double genericDoubleOp(double a, double b, long opcode)

{

FlpCompDouble fcda, fcdb, fcds;

fcda.d = a; fcdb.d = b;

asm("move.l %0,%%d2" : : "g" (opcode) : "d2");

SysTrapBinOp(&fcds.fd, fcda.fd, fcdb.fd);

return fcds.d;

}

/* basic arithmetic operations */

#define addDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_add)

#define subDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_sub)

#define mulDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_mul)

#define divDouble(a,b) genericDoubleOp(a,b,sysFloatEm_d_div)

SDWord SysTrapCompare(FlpDouble, FlpDouble) SYS_TRAP(sysTrapFlpEmDispatch);

/* compare 2 doubles for equality */

Boolean eqDouble(double a, double b)

{

FlpCompDouble fcda, fcdb;

fcda.d = a; fcdb.d = b;

asm("moveq.l %0,%%d2" : : "i" (sysFloatEm_d_feq) : "d2");

return SysTrapCompare(fcda.fd, fcdb.fd);

}

/* compare 2 doubles for less or equal */

Boolean leqDouble(double a, double b)

{

FlpCompDouble fcda, fcdb;

fcda.d = a; fcdb.d = b;

asm("moveq.l %0,%%d2" : : "i" (sysFloatEm_d_fle) : "d2");

return SysTrapCompare(fcda.fd, fcdb.fd);

}

You should get the idea how to extend this for other operations. By the way, you can use floating point constants in your code, they are correctly converted into their IEEE bit pattern by GCC!

Printing and scanning IEEE floating pointThough you could use SysTrapFlpFToA or SysTrapFlpAToF, I don't recommend so, as the ROM routines

provide only 9 digits of accuracy

can't handle exponents >99

don't provide error checking Unfortunately, not even the otherwise excellent MathLib supports floating point IO, so I had to write my own for LispMe.

Here's my printing function for doubles: /**********************************************************************/

/* Formatting parameters */

/**********************************************************************/

#define NUM_DIGITS 15

#define MIN_FLOAT 4

#define ROUND_FACTOR 1.0000000000000005 /* NUM_DIGITS zeros */

/**********************************************************************/

/* FP conversion constants */

/**********************************************************************/

static double pow1[] =

{

1e256, 1e128, 1e064,

1e032, 1e016, 1e008,

1e004, 1e002, 1e001

};

static double pow2[] =

{

1e-256, 1e-128, 1e-064,

1e-032, 1e-016, 1e-008,

1e-004, 1e-002, 1e-001

};

void printDouble(double x, Char* s)

{

FlpCompDouble fcd;

short e,e1,i;

double *pd, *pd1;

char sign = '\0';

short dec = 0;

/*------------------------------------------------------------------*/

/* Round to desired precision */

/* (this doesn't always provide a correct last digit!) */

/*------------------------------------------------------------------*/

x = mulDouble(x, ROUND_FACTOR);

/*------------------------------------------------------------------*/

/* check for NAN, +INF, -INF, 0 */

/*------------------------------------------------------------------*/

fcd.d = x;

if ((fcd.ul[0] & 0x7ff00000) == 0x7ff00000)

if (fcd.fdb.manH == 0 && fcd.fdb.manL == 0)

if (fcd.fdb.sign)

StrCopy(s, "[-inf]");

else

StrCopy(s, "[inf]");

else

StrCopy(s, "[nan]");

else if (FlpIsZero(fcd))

StrCopy(s, "0");

else

{

/*----------------------------------------------------------------*/

/* Make positive and store sign */

/*----------------------------------------------------------------*/

if (FlpGetSign(fcd))

{

*s++ = '-';

FlpSetPositive(fcd);

}

if ((unsigned)fcd.fdb.exp < 0x3ff) /* meaning x < 1.0 */

{

/*--------------------------------------------------------------*/

/* Build negative exponent */

/*--------------------------------------------------------------*/

for (e=1,e1=256,pd=pow1,pd1=pow2; e1; e1>>=1, ++pd, ++pd1)

if (!leqDouble(*pd1, fcd.d))

{

e += e1;

fcd.d = mulDouble(fcd.d, *pd);

}

fcd.d = mulDouble(fcd.d, 10.0);

/*--------------------------------------------------------------*/

/* Only print big exponents */

/*--------------------------------------------------------------*/

if (e <= MIN_FLOAT)

{

*s++ = '0';

*s++ = '.';

dec = -1;

while (--e)

*s++ = '0';

}

else

sign = '-';

}

else

{

/*--------------------------------------------------------------*/

/* Build positive exponent */

/*--------------------------------------------------------------*/

for (e=0,e1=256,pd=pow1,pd1=pow2; e1; e1>>=1, ++pd, ++pd1)

if (leqDouble(*pd, fcd.d))

{

e += e1;

fcd.d = mulDouble(fcd.d, *pd1);

}

if (e < NUM_DIGITS)

dec = e;

else

sign = '+';

}

/*----------------------------------------------------------------*/

/* Extract decimal digits of mantissa */

/*----------------------------------------------------------------*/

for (i=0;i<NUM_DIGITS;++i,--dec)

{

Long d = doubleToLong(fcd.d);

*s++ = d + '0';

if (!dec)

*s++ = '.';

fcd.d = subDouble(fcd.d, longToDouble(d));

fcd.d = mulDouble(fcd.d, 10.0);

}

/*----------------------------------------------------------------*/

/* Remove trailing zeros and decimal point */

/*----------------------------------------------------------------*/

while (s[-1] == '0')

*--s = '\0';

if (s[-1] == '.')

*--s = '\0';

/*----------------------------------------------------------------*/

/* Append exponent */

/*----------------------------------------------------------------*/

if (sign)

{

*s++ = 'e';

*s++ = sign;

StrIToA(s, e);

}

else

*s = '\0';

}

}

The scanning function is too deeply interwoven with the rest of LispMe's scanner, I'll extract it when I've got more time!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有