binghelingxi 发表于 2008-1-18 08:45:32

构建标准的中文转换程序gb2ws和ws2gb(讨论)

构建标准的中文转换程序GB&WS

以along当时写的code.c即cnfont.dat为基础。严重感谢along1976大侠。

我的设想如下:
cnfont.dat直接刷入flash。
gb2ws,ws2gb(原along用ascii2ws,ws2ascii,由于这两个函数俄国人用过了,在65上被用作了API函数,0xAD,0xAE)这两个也让它用作为swilib的函数,序号大约为0x242,0x243,我去和俄国人商量一下,应该没什么大问题。

补丁和cnfont.dat占用的空白地址我差不多找到了。
NEWSGOLD/ELKA,0x01568000-0x015681FF用作补丁数据,0x01568200-0x0157A24F用作cnfont.dat
SGOLD,0x00FE0000-0x00FE01FF用作补丁数据,0x00FE0200-0x00FF224F用作cnfont.dat

补丁的工程文件已经传到了http://sieelf.googlecode.com/svn/SieELF/gb2ws
VKP补丁下载:http://sieelf.googlecode.com/svn/SieELF/gb2ws/vkp

还请各路高手来观摩观摩。
我们要让代码尽量简洁,而效率又要是是尽量的高。

补丁代码用的是16位的THUMB模式,比起32位的ARM模式代码简短,效率相对较高。
但是由于调用到了序号为0x126的CutWSTR,超出了THUMB模式的SWI调用范围(0-0xFF)
于是我直接用汇编代码写了一个ARM模式的函数CutWSTRT来做调用。THUMB模式和ARM模式是可以无缝切换的,还好还好^_^。
我不大熟悉这个CutWSTR函数,如果能用简短的代码把它替换掉,就替换之。

弟兄们说说想法啊。

binghelingxi 发表于 2008-1-18 08:55:25

现在的代码,code.c:#include "..\inc\swilib.h"


#ifdef NEWSGOLD
#define CODEMAP_ADDR 0xA1568200//-0xA157A24F
#else
#define CODEMAP_ADDR 0xA0FE0200
#endif

extern CutWSTRT(WSHDR *,int );

#pragma swi_number=0x0A0
__swi        __arm        int wsprintf_2 (WSHDR *,const char *format,...);

__thumb void ws2ascii(WSHDR *ws, char *s, int maxlen)
{
unsigned short *codemap=(unsigned short *)CODEMAP_ADDR;
int len=ws->wsbody;
if(maxlen != 0 && len > maxlen)
    len = maxlen;
if(codemap == 0)
{
    ws_2str(ws, s, len);
    return;
}
int i,j=0;
unsigned short temp;
for(i=1; i<=len; i++)
{
    temp=ws->wsbody;
    if(temp < 256)
      s = (unsigned char)temp;
    else if(temp >= 0x4E00 && temp <= 0x9FA5)
    {
      s = (unsigned char)(codemap>>8);
      s = (unsigned char)((codemap<<8)>>8);
    }
    else
      s = '?';
}
s = 0;
}

__thumb void ascii2ws(WSHDR *ws, const char *s, int maxlen)
{
unsigned short *codemap=(unsigned short *)CODEMAP_ADDR;
if(codemap == 0)
{
    wsprintf_2(ws, "%t", s);
    return;
}
char *p=(char *)s;
unsigned char uc,uc2;
//CutWSTR(ws,0);
CutWSTRT(ws,0);
while((uc=*s++) && (maxlen == 0 || s-p<=maxlen))
{
    if(uc <= 128)
      wsAppendChar(ws,uc);
    else
    {
      uc2=*s++;
      if(uc2 < 128)
      wsAppendChar(ws, uc2);
      else
      wsAppendChar(ws, codemap[(uc-129)*127+(uc2-128)]);
    }
}
}

#pragma diag_suppress=Pe177
__root static const int SWILIB_242_GB2WS @ "SWILIB_242_GB2WS" = (int)ascii2ws;
#pragma diag_default=Pe177

#pragma diag_suppress=Pe177
__root static const int SWILIB_243_WS2GB @ "SWILIB_243_WS2GB" = (int)ws2ascii;
#pragma diag_default=Pe177这里我做了一句修改:
while((uc=*s++) && (maxlen == 0 || s-p<=maxlen))
原为。。: while((uc=*s++) && (maxlen == 0 || s-p<maxlen))
之前的代码会使第一个英文字母消失掉,不知道这样改有没有道理。http://mobile.0110.cn/images/smilies/default/beg.gif
arm_swi.asm:    RSEG    CODE
    PUBLICCutWSTRT
    CODE32
CutWSTRT:
    STMFD   SP!, {LR}
    SWI   0x126 //CutWSTR
    LDMFD   SP!, {PC}
    END俄国论坛已发帖:http://forum.siemens-club.org/viewtopic.php?TopicID=57264&page=20,见笑。http://mobile.0110.cn/images/smilies/default/ee.gif

along1976 发表于 2008-1-18 09:09:25

严重支持以补丁方式支持ANSI编码,这样不仅可以节省内存,还可以提高转码效率。

个人认为CutWSTR实现很简单:
voidCutWSTR (void *WSHDR,int len)
{
WSHDR *wshdr=WSHDR;
wshdr->wsbody = len;
}

binghelingxi 发表于 2008-1-18 09:37:02

效率肯定是会提高的。。。内存肯定省了,就是空白地址占了一大段,~_~,貌似还够用。
CutWSTR(ws,0);
就是相当于ws->wsbody=0;?

另外就是ELFLoader采用哪种方式的问题?
对gb2312,IAR支持好,中文两字节,占用空间小
对utf8,IAR编辑器中不能直接显示,中文三字节,占用空间相对较大

但是无论哪种方式,其实在我们平时制作ELF时,用到的并不是太频繁,差不多只有在软键,菜单中用到。
其它地方的中文支持基本和ELFLoader无关。
所以,关键还是看效率。

如果有简单的代码可以加以判断,两种编码都支持也无妨。

[ 本帖最后由 binghelingxi 于 2008-1-18 09:39 编辑 ]

jpg001 发表于 2008-1-18 09:39:43

个人认为仍旧使用原来的函数序号。。这样除了一些欧洲文字的显示会有问题以外(就算正常又有谁看的懂么。。),别的都不会是问题。。

这种区域性的函数,不会有冲突的函数,我觉得直接替换即可,没必要占用新位置。

swi 0x100以上的问题,这是mp处理这个问题的宏代码(keil):
CallLib   macro   num
            if num &lt; 0x100//晕,这地方是小于号
            SWI   #num
            else
            SWI   #199
            dw      num
            endif
endm

binghelingxi 发表于 2008-1-18 09:45:14

http://mobile.0110.cn/images/smilies/default/beg.gif

大大方方地占它两个位置也没什么关系啦。。。
SWILIB的空间绝对够的。
http://mobile.0110.cn/images/smilies/default/desk.gif
如那个帖里面benj9说的、

along1976 发表于 2008-1-18 09:55:31

个人认为是的,可以测试一下:
CutWSTR(ws,0);
就是相当于ws->wsbody=0;


另外,空白地址的选取也很重要。

S6CV53的0x00FE0200地址不是空白的或是已经被占用。

binghelingxi 发表于 2008-1-18 10:05:33

回复 7# 的帖子

我测试了,那样写就可以了。

哦,晕,不知道被什么补丁占用了。

我用空白fullflash测试的,和区号秀也没有冲突的。

0x00FE4200如何?

[ 本帖最后由 binghelingxi 于 2008-1-18 10:11 编辑 ]

along1976 发表于 2008-1-18 10:36:43

S6CV53:0x00FE5400应该没有问题。
我的S6CV53是这样,不知道其他人的如何?

jpg001 发表于 2008-1-18 10:41:50

没必要的事情就不要去做了,HZ和我一个看法

。。而且程序结构写的好的话,可能不同语言还有希望可以直接通用

记得有个75的sgpld机型地址跟别的sg不一样。也就是说,是没办法完全统一数据地址的,打包作为一个单独的API好了,或者直接放到lib的后面。

binghelingxi 发表于 2008-1-18 10:51:00

不是是否必要的问题。若论绝对必要,swilib中很多函数都可以删掉了。
是需要的问题。如果某天他们吧那两个函数废掉了呢。。。
我们明明是两个独立的函数,为什么不要两个独立的位置。
占用两个函数的位置也不是什么大不了的事。也不能说国外原来的函数是绝对没用的。虽然在NEWSGOLD机型上这两个函数已经不用了,但是位置一直还留着。

看其他人的意见吧。

那是国外的C75v22,中文C7Cv22没问题

[ 本帖最后由 binghelingxi 于 2008-1-18 11:08 编辑 ]

regspy 发表于 2008-1-18 11:23:25

还是增加函数的好, 替换 别人的函数好像明点不尊重原作者的味道:/lkh

binghelingxi 发表于 2008-1-18 13:06:30

我用空白FULLFLAH测试。。。0x00FE5600 CODEMAP只有CX7Av25不能通过。
不过可能是因为我的FULLFLASH有问题。。。

已调整,请大家测试。,

————————————
通过。。。FUBU问题。。。

zhangxxx 发表于 2008-1-22 19:48:29

我的S65要换成0x00FE5800才行
之前有个不知道什么补丁占用了部分地址

jpg001 发表于 2008-1-23 08:42:49

我仔细观察了下65的占用区域分布,FE0000处为eelite的区域,所以不同的人会出现不同占用的情况。。。

相同情况的比如EL71的80000以后那一部分区域,也是eep区域。

Name= S65
Type= Chaos BootPatch
Comments = Siemens S65 Phone (connecting, using Chaos patched bootcore)
Boots= Connect, GoBoot.bin, ChaosBoot_Patch.bin, ChaosKey1.bin, ChaosKey2.bin
MCUMemFuBu = fullflash,      0xA0000000, 0x02000000
MCUMemArea01 = bootcore,         0xA0000000, 0x00020000, bootcore
MCUMemArea02 = CODE1,            0xA0020000, 0x001E0000
MCUMemArea03 = EXIT,             0xA0200000, 0x00020000
MCUMemArea04 = EEFULL,         0xA0220000, 0x00040000
MCUMemArea05 = FFS_B,            0xA0260000, 0x00080000
MCUMemArea06 = FFS_C,            0xA02E0000, 0x00200000
MCUMemArea07 = FFS_A1,         0xA04E0000, 0x00320000
MCUMemArea08 = XCORE,            0xA0800000, 0x00020000
MCUMemArea09 = CODE2,            0xA0820000, 0x007C0000
MCUMemArea10 = EELITE,         0xA0FE0000, 0x00020000
MCUMemArea11 = CODE3,            0xA1000000, 0x00800000
MCUMemArea12 = FFS_A2,         0xA1800000, 0x00800000

所以目前可用的大片空白区域有两块,在F60000-FC0000(X65相同)和16B59E8(S6Cv53,其他机型不同)-1800000。

根据X65补丁空白占用表(点击查看),后面一块很多补丁都有占用,前一块貌似也有部分机型区号秀占用。我认为有必要将区号秀数据库搬迁至后一块区域,把前一块地址释放出来做为公共地址补丁占用区域,各位一起来讨论下。

我现在手头只有s6c、sl6c和sk6c的fubu。其他人确认下,把占用此区域的补丁写在下面吧。

jpg001 发表于 2008-1-23 09:58:49

根据X65补丁空白占用表,总结F60000-FC0000处补丁情况:
C6Cv53,SL6Cv50
区号秀V1.2数据库   F60000-F9FFFF
SK6Cv43:
E2D280-F7FFFF    | ★★★ 空白 ★★★
F80000-FBFFFF    |区号秀V1.2数据库
sk6cv50表里未见,估计是一样的。。

cx6cv50,cx7cv50,s6cv53,M6cv50空白

X75貌似此区域空白:http://mobile.0110.cn/viewthread.php?tid=227184


我的意见是,使用FA0000地址,仅SK6C需搬迁数据库地址。


若为以后方便考虑,可整理整个F60000-FC0000区域,仅三个机型需动迁区号秀。

有其他发现请跟贴

binghelingxi 发表于 2008-1-23 10:34:07

哦。。。

SK的0xE30000地址段长得还不错,稍微有点不足的话,还可以往前挪一点。。。
奇怪。。。VK竟然没吧数据完全刷到FUBU里面去。。。
SK空白地址差不多也就是那样。从e21104开始的。。。

补丁占用空白地址表。。。ROM: http://mobile.0110.cn/thread-293802-1-1.html

俺快要没得上网了。。。这里靠你了。。。

jpg001 发表于 2008-1-23 10:45:32

好,暂时就让幻芯换个地址重新编译下sk的区号秀。

这里先定下来使用FA0000地址,FA0000-FBFFFF暂时定为公共用途。

高极名功 发表于 2008-1-23 18:30:46

把其他语言占用的那一块能不能占用了
只留中文简体和英文
猜测!

zhangxxx 发表于 2008-1-23 18:38:15

我觉得既然都将cnfont.dat刷进系统了,为什么不干脆直接在elfloader修改呢,这样可以直接修改中文了,而现在这样,由utf8兼容过来,就要兼顾2种格式,感觉就是浪费....................
最理想的还是由elfloader支持gb中文,这样就不用那么麻烦了,而且覆盖面更加的广,,,,,,,,,,,,,,,,,,,,,,,,,,
页: [1] 2
查看完整版本: 构建标准的中文转换程序gb2ws和ws2gb(讨论)