cnCalc计算器论坛

 找回密码
 注册
搜索
查看: 11629|回复: 10

[fx-9860/9750] 【SDK教程】syscall的使用

[复制链接]
发表于 2012-8-10 18:14:34 | 显示全部楼层 |阅读模式
本帖最后由 Wudy 于 2012-8-11 14:29 编辑

这几天论坛的9860SDK开发好像又热闹起来了,我奉上我的处女教程贴~

官方提供的SDK虽然可以满足一般需要,但是还有很多更强大的功能没有被记录,比如...
打开其他add-in,模拟按键,获取设置文件,获取变量,获取电池电量,传输数据,执行对Storage Mem的opt等等。
这些功能都用一句简单的syscall来实现,本文就将教大家如何在add-in编写中用c语言使用syscall。方法来自
http://martin.poupe.org/casio/tsr/index.html提供的示例代码。

先看一段代码:
  1. const int SysCallWrapper[] = { 0xD201422B, 0x60F20000, 0x80010070 };
  2. const int (*iSysCallFuncPtr)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallWrapper;

  3. #define App_RUN_MAT() (int)(*iSysCallFuncPtr)( 0, 0, 0, 0, 0xAAE )

  4. int AddIn_main(int isAppli, unsigned short OptionNum)
  5. {
  6.         unsigned int key;

  7.          // 显示提示字符
  8.          locate( 1, 1 );
  9.          Print( "Press Any key to go" );
  10.          locate( 1, 2 );
  11.          Print( "to RUN.MAT..." );
  12.          GetKey( &key );

  13.          // 使用syscall进入RUN.MAT
  14.          App_RUN_MAT();

  15.          return 1;
  16. }
复制代码
打开add-in后,按下任意键,你就会神奇地进入到了RUN.MAT里!下面来简单分析一下这段代码。
SysCallWrapper就是调用syscall的机器码的封装,然后用一个函数指针iSysCallFuncPtr指向SysCallWrapper,就相当于在C中嵌入了一个机器码编的函数。
iSysCallFuncPtr的前4个参数R4,R5,R6,R7就是寄存器4,5,6,7用来放syscall的参数。
iSysCallFuncPtr的最后一个参数FNo是syscall的编号(应该是类似中断向量的东西)。

在本例中,打开RUN.MAT这个syscall的编号就是0xAAE,它不需要任何参数,所以可以定义如下一个宏来使用它。
#define App_RUN_MAT() (int)(*iSysCallFuncPtr)( 0, 0, 0, 0, 0xAAE )
或者写成一个函数也可以
void App_RUN_MAT( void )
{
        (int)(*iSysCallFuncPtr)( 0, 0, 0, 0, 0xAAE );
}
写成函数的优点是如果syscall有参数,可以让编译器为你进行类型检查。宏定义的优点是方便和速度(SDK好像不支持内联函数)

接下来就可以到文档里查找需要的syscall然后让你的add-in功能更强大(文档是老外写的,见附件里的chm文件)!
在这里列举一些有用或好玩的syscall..

0x03B: int RTC_GetTicks( void )
返回从0点开始的秒数的128倍,可用于做随机数种子。

0x0AE8: int CatalogDialog( void )
打开目录,和shift+7的那个一样,返回选择的项目的opcode

0x0645: int CalculateExpression( char**expression, char*c, TBCDvalue*value, int mode )
好像可以计算表达式,我还没仔细研究

0x4DF: char *Alpha_GetData(char variablecode, char *datadest)
获取main memory中字母变量的值

0x4DC: char Setup_GetEntry(uint index);
0x4DD: char *Setup_SetEntry(uint index, char setting);
设置、获取shift-menu里的设置

0x3F4: void PowerOff( int mode )
关机,可以选择显示或不显示logo

0x236: void RebootOS( void )
重启

0x0A6A: int App_Optimization( void )
执行对Storage Mem的opt

0x136: unsigned char *GetCharacterGlyph(short character);
0x137: unsigned char *GetCharacterMiniGlyph(short character, short*width);
获取内置字体的位图,mini模式还可以获取宽度

0x0804: int CLIP_Store( unsigned char*buffer, in length )
复制字符到剪切板

0x135: Bdisp_GetVRAMPtr()
获取显存地址,可以更底层地绘图

还有很多MSC_开头的是操作main memory里的文件的函数
还有很多Serial_开头的,可能是操作串口的
还有很多Comm_开头的,与通信有关,具体可以看那个pdf。
还有很多XXX...


fx_calculators_SuperH_based.part1.rar

511 KB, 下载次数: 263

fx_calculators_SuperH_based.part2.rar

511 KB, 下载次数: 332

fx_calculators_SuperH_based.part3.rar

293.98 KB, 下载次数: 235

评分

参与人数 4金钱 +9 收起 理由
croptree + 2 优秀文章
ExAcler + 2 相当不错!
GWHBOB + 2 wowo
diameter + 3 优秀文章

查看全部评分

 楼主| 发表于 2012-8-10 18:21:02 | 显示全部楼层
还有一个比较有用的syscall
0x0910 : int Keyboard_PutKeycode( int keycode )
它的功能是把一个按键加入到按键队列里,就相当于模拟按键,可以做个按键精灵之类的!下面的示例程序是到RUN.MAT模式里输入一段字符串,因为执行过程中到了RUN.MAT,程序会被暂停,所以要用定时器来实现按键。
  1. const int SysCallWrapper[] = { 0xD201422B, 0x60F20000, 0x80010070 };
  2. const int (*iSysCallFuncPtr)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallWrapper;
  3. #define App_RUN_MAT() (int)(*iSysCallFuncPtr)( 0, 0, 0, 0, 0xAAE )

  4. int Keyboard_PutKeycode( int keycode )
  5. {
  6.         return (int)(*iSysCalleycode, keycode<256, 0, 0, 0x0910 );
  7. }

  8. // 字符按键的代码就是ASCII码
  9. const char *text = "Hello World!";

  10. int index = 0;
  11. void TimerHandler( void )
  12. {
  13.         int key = text[index++];

  14.         // 模拟按键
  15.         Keyboard_PutKeycode( key );
  16.         // 所有按键都被模拟了,关闭定时器
  17.         if( key == '\0' )
  18.                 KillTimer( 1 );
  19. }

  20. int AddIn_main(int isAppli, unsigned short OptionNum)
  21. {
  22.         // 设置定时器
  23.         SetTimer( 1, 250, TimerHandler );

  24.         // 进入RUN.MAT
  25.         App_RUN_MAT();
  26.         return 0;
  27. }
复制代码
发表于 2012-8-10 18:34:06 | 显示全部楼层
用syscall确实很方便,可是在新版的9860怎么办?
有点蛋疼..
 楼主| 发表于 2012-8-10 19:52:07 | 显示全部楼层
3# diameter
是一个问题。不过syscall都是SDK实现不了的功能,有总比没有好。
发表于 2012-8-11 00:36:43 | 显示全部楼层
我一直很好奇这些玩意怎么被发现的……
发表于 2012-8-11 11:35:41 | 显示全部楼层
怎样获取list 1数据
是否可以给casio的basic添加函数或其他功能
 楼主| 发表于 2012-8-11 14:34:30 | 显示全部楼层
不过要是有能够直接用计算器内置函数的syscall就好了
ExAcler 发表于 2012-8-11 11:27

可以看一下
0x0645: int CalculateExpression( char**expression, char*c, TBCDvalue*value, int mode )
不过具体我也不知道,文档已经附件上传!


怎样获取list 1数据
是否可以给casio的basic添加函数或其他功能
chuxianbing 发表于 2012-8-11 11:35


可以给basic添加功能!
最简单的(就是那个网址里的例子),比如那A这个变量当函数标号,用你的add-in进到prgm模式,然后让用户执行一个程序,设置定时器不断检查a的值然后提供相应的功能。
list 1的值肯定是可以获取的,我还没研究完,你自己看一下吧。
发表于 2012-8-11 14:48:40 | 显示全部楼层
Tbcd value 肯定是一种类型,如果能和谐的话对我们的自然书写会有很大帮助
发表于 2013-5-4 11:29:08 | 显示全部楼层
真是大神啊,弱弱地问一下,调用App_RUN_MAT()后该如何返回?
发表于 2013-5-4 16:09:35 | 显示全部楼层
9860 GII SD 一运行就死机,Version 02.02.0201,有没有办法解决?
发表于 2014-12-21 18:35:44 | 显示全部楼层
要是能读取LIST、MAT就好了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|cnCalc计算器论坛

GMT+8, 2024-12-22 01:24 , Processed in 0.085658 second(s), 26 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表