
Exchange Data Between Two Addin Applications
#1
Posted 22 December 2008 - 01:17 PM
I need to exchange data between two SDK addin applications. My idea is to avoid creating files in storage memory or the SD card, because storage memory has limited life time, and this data exchange might happen very often. So I want to use the main memory for this.
I have analyzed and used the function to create files in the MM "Bfile_CreateMainMemory()", it works fine. However, files created are stored in the MM under a folder name that contains the name of the addin. For example, the text editor program saves the configuration settings in a file named EDIT.CFG that can be seen with the memory explorer under a folder named "<@EDIT>".
So it seems that each addin is creating files in the main memory under its own folder name. Unfortunately, the folder name cannot be changed, functions Bfile_OpenMainMemory(), Bfile_CreateMainMemory(), etc, do not allow to set folder name in the file name (it says so in the documentation).
Therefore, it looks like that is not possible to exchange data with files in the main memory between two addins, because a different folder name will be used and it is fixed.
Does someone have an idea how we can exchange data between two addins using the main memory?
Thanks for your help,
Diego.
#2
Posted 22 December 2008 - 07:22 PM
Or, you can try system call 0x463 which first and only argument takes a pointer to a 9-byte string that contains the new name.
Create a file and add it to the project:
setappname.src:
.section P, code .export _SetAppName _SetAppName: mov.l #h'80010070, r2 jmp @r2 mov.l #h'0463, r0
Then try calling it in your code like
SetAppName("@EDIT");
And let me know if it does what you want.
Edited by Andreas B, 22 December 2008 - 10:42 PM.
#3
Posted 22 December 2008 - 11:45 PM
How do you know all of this stuff? I mean system calls and things like that.
Do you have documentation about system calls?
#4
Posted 23 December 2008 - 12:24 AM
Change the MenuMode setting like this:
MenuMode=0
(restart your SDK if already open)
Then in the Project->Edit dialog, you can choose the tab "Main Menu" and set the "System management name" to whatever you like.
edit:
SimonLothar/SimLo and I have been disassembling parts of the OS to figure out undocumented but handy functions. Check http://downloads.sou...erse-docs-1.pdf for the first version of our own documentation on this.How do you know all of this stuff? I mean system calls and things like that.
Do you have documentation about system calls?
Edited by Andreas B, 23 December 2008 - 12:28 AM.
#5
Posted 24 December 2008 - 09:27 AM
I have reviewed your documentation about the dissasembled code for Fx-9860g. I also have been doing dissasembling for 8086 applications and I know the difficulty of this. What you have done it is a great job, congratulations!

Watching the assembler code for system call 0x463 (I could not find syscall 0x463, it in your documentation, by the way), I do not understand it propperly. In your documentation, the system calls are refered to be called like this:
mov.l syscall_number , r0 mov.l #h'80010070 , r2 jmp @r2 nop
Whereas in your sample code above you placed the instruction to put the syscall number in r0 as the last instruction not as the first one.
.section P, code .export _SetAppName _SetAppName: mov.l #h'80010070, r2 jmp @r2 mov.l #h'0463, r0
A short question about the calling convention: Why an inconditional jump is used? I would have expected a subroutine call or an interrupt call (like in the 8086 assembler).
In the documentation it is said that first four arguments are passed through registers r4 to r7. For SetAppName(), as the argument is a 9-Byte string, Should r4 point to a ascii-z string before the system call right? I ask so because I think that the system call should have also a prototype in my C source code, right?
What are the steps for calling 0x463 then:
- Create file *.scr with assembler code and add it to the proyect in the SDK.
- Put a propper function prototype in the C source code (like -> void SetAppName(char *); )
- Call the function.
In the these sequence of steps I do not see how the compiler knows that it must place arguments from r4 to r7 and then to the stack. Should we do this directly ourselves?
A last question: I see that you have documented system calls for the built-in applications on the calculator (App_RUNMAT(), App_STAT(), App_RECUR(), etc). Did you figure out how to call addin applications as well? Or just how to switch between them?
It is a lot of questions, I know.

Thank you,
Diego.
#6
Posted 24 December 2008 - 09:57 PM
Don't forget SimLo/SimonLothar, he has done lots, but thanksHello Andreas,
I have reviewed your documentation about the dissasembled code for Fx-9860g. I also have been doing dissasembling for 8086 applications and I know the difficulty of this. What you have done it is a great job, congratulations!

We have not published nearly all of the system calls we 'know about', we try to include it in the docs when we figure out complete 'sets' of functions.Watching the assembler code for system call 0x463 (I could not find syscall 0x463, it in your documentation, by the way),
Yes, because of the processor architecture, some instructions (like jmp and some of the branch instructions) have a delay slot, where the instruction following it is executed /before/ the jump is made. In this case, the syscall number is moved into r0 in time for the jump.I do not understand it propperly. In your documentation, the system calls are refered to be called like this:
mov.l syscall_number , r0 mov.l #h'80010070 , r2 jmp @r2 nop
Whereas in your sample code above you placed the instruction to put the syscall number in r0 as the last instruction not as the first one..section P, code .export _SetAppName _SetAppName: mov.l #h'80010070, r2 jmp @r2 mov.l #h'0463, r0
The calling code (above) is executed with a subroutine call. It jumps to code at 0x80010070 which then looks up function number 0x463 in a table, which it then jumps to. When the wanted function returns, it returns directly to the code that made the first "subroutine call".A short question about the calling convention: Why an inconditional jump is used? I would have expected a subroutine call or an interrupt call (like in the 8086 assembler).
Yes, and yes. It would be:In the documentation it is said that first four arguments are passed through registers r4 to r7. For SetAppName(), as the argument is a 9-Byte string, Should r4 point to a ascii-z string before the system call right? I ask so because I think that the system call should have also a prototype in my C source code, right?
int SetAppName(char *name);
It will always return 0.
Well, the compiler sees a reference to SetAppName, used as a function. Placing arguments in registers r4 to r7 (and stack) is a part of what's called the ABI for this OS, and is a convention i assume is created by Hitachi/Renesas (CPU designer). The compiler uses this as the default way to pass arguments to a function. All functions follow this convention.What are the steps for calling 0x463 then:
- Create file *.scr with assembler code and add it to the proyect in the SDK.
- Put a propper function prototype in the C source code (like -> void SetAppName(char *); )
- Call the function.
In the these sequence of steps I do not see how the compiler knows that it must place arguments from r4 to r7 and then to the stack. Should we do this directly ourselves?
We don't know how to execute addins, if it is possible.A last question: I see that you have documented system calls for the built-in applications on the calculator (App_RUNMAT(), App_STAT(), App_RECUR(), etc). Did you figure out how to call addin applications as well? Or just how to switch between them?
Happy holidays.
Edited by Andreas B, 25 December 2008 - 12:49 AM.
#7
Posted 25 December 2008 - 09:44 PM

So you are creating a non-official SDK for fx-9860G?
What is the status of your work?
What will be the differences with the standard SDK?
#8
Posted 25 December 2008 - 11:18 PM
See what is available at fxsdk.sf.net. It is unlikely that there will be any simulator (by me at least).Thanks a lot Andreas, for all your answers and happy christmas, also
![]()
So you are creating a non-official SDK for fx-9860G?
What is the status of your work?
What will be the differences with the standard SDK?
Edited by Andreas B, 25 December 2008 - 11:19 PM.
#9
Posted 26 December 2008 - 05:22 PM
I just had a look. It seems to be possible....Did you figure out how to call addin applications as well? Or just how to switch between them?...
// first some universal syscall wrapper // this codepiece has to be 4-aligned, hence it is an int array const int SysCallWrapper[] = {0xD201422B,0x60F20000,0x80010070}; // additionally declare an int function pointer: const int (*iSysCallFuncPtr)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallWrapper; // declare the two syscalls needed int GetAddinHeaderAddr( int addinno, int offset, void*result ) { return (*iSysCallFuncPtr)( addinno, offset, (int)result, 0, 0x000A ); } int StartAnyApp( int appno ) { return (*iSysCallFuncPtr)( 0, 0, appno, 0, 0x049A ); } // int AddIn_main(int isAppli, unsigned short OptionNum) { int i = 0, index = -1; unsigned char*appname; // the following loop searches an addin by name (omit ".G1A"). // GetAddinHeaderAddr with offset=0x1D4 retrieves the name of the addin with index i from storage memory while ( GetAddinHeaderAddr( i, 0x1D4, &appname ) ){ if ( strcmp( appname, "EXAMPLE" ) == 0 ){ index = i; break; } i++; } // if the addin has been found, start it if ( index != -1 ) StartAnyApp( index + 15 ); }
#10
Posted 27 December 2008 - 07:27 PM
I do not totally understand your source code.
You call syscalls by function pointer iSysCallFuncPtr, as far as I see from your code it looks to me that this function pointer is direcly executing the binary code contained in integer array SysCallWrapper, but I am not sure. I have never user function pointers like this.
If you dissasemble the binary code in SysCallWrapper what instructions you get?
#11
Posted 28 December 2008 - 06:29 AM
The SDK C compiler places the 5th parameter on the stack. So the wrapper fetches the function number from @r15 (line 8)....what instructions you get?...
Parameters 1..4 (registers r4..r7) are passed to the syscall without change.
The benefit is, that it is not nessessary to write an assembler piece for every single syscall you need.
You can use this wrapper for every syscall, which uses not more than 4 parameters.
this is the corresponding .LST-output of SDK's asmsh.
/* for reference
4 4 ; parameters: r4, r5, r6, r7, functionno; returns r0
5 00000000 5 _SystemCall:
6 00000000 D201 6 mov.l #h'80010070, r2
7 00000002 422B 7 jmp @r2
8 00000004 60F2 8 mov.l @r15, r0
9 9
10 10
11 ***** BEGIN-POOL *****
12 00000006 0000 ALIGNMENT CODE
13 00000008 80010070 DATA FOR SOURCE-LINE 6
14 ***** END-POOL *****
15 11 .END
*/
Never try syscall numbers of unknown functionality!
#12
Posted 28 December 2008 - 10:29 AM
Another question more or less related to this:
Did you find syscalls to read the directory entries in the main memory?
#13
Posted 06 January 2009 - 02:54 PM
At present, we know about 20 main-memory related syscallsDid you find syscalls to read the directory entries in the main memory?
(like search, create, rename, write, delete directories or directory items).
But there are still more.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users