Hi all.

I want to be able to run one app from another. I know this is possible with built in apps via syscalls such as as APP_FINANCE but what about other addins?
If there isn't a syscall for this would it be possible to directly load the program into memory?
Yes, there is! Use Syscall 0x1E5B: int OpenAddin(0, 0, index, 0), where index is the index of that app on the main menu. Have a read through my C equivalent if you want to try and figure out what the three zeroes mean: https://bible.planet-casio.com/drcarlos/Syscalls/OpenAddin.c

Also note that I've only tested it on OS 3.60, so if you want to run it on a newer OS I can't guarantee anything.
Nice. What other functions from https://bible.planet-casio.com/drcarlos/Syscalls/ do I need to include to get OpenAddin to compile?
Sorry, I didn't explain that very well.
You need to use Syscall 0x1E5B. Here is an example program which should open the 7th addin on the menu:

Code:

int OpenAddin(int zero1, int zero2, unsigned short index, int zero3);
__asm__(".text; .align 2; .global _OpenAddin; "
               "_OpenAddin: mov.l sc_addr, r2; mov.l OpenAddin_Number, r0; "
               "jmp @r2; nop; "
               "OpenAddin_Number: .long 0x1e5b; "
               "sc_addr: .long 0x80020070");

int main(void) {
  OpenAddin(0, 0, 6, 0); // Index starts at 0, so 7th item is 6
  return 0;
}


If you want to investigate the internal workings of this function, you can check out https://bible.planet-casio.com/drcarlos/Syscalls/OpenAddin.c
The referenced functions are all either located in https://bible.planet-casio.com/drcarlos/Syscalls/ or will require using a disassembler to investigate personally.

Let me know if you have any issues.
Thanks dr-carlos. Your code worked as intended. As I understand it a syscall involves moving a syscall number to r0 and then jumping to 0x80020070. In your assembly you haven't referenced 'index' ie the addin number. I guess the syscall knows what the addin number is since this the third argument to a function ends up being copied to r6.

Could an addin be run by reading the g3a from 0x7000 and copying into memory then jumping to the start of what we copied?
I would like to investigate some syscalls myself. I have extracted the 11MB binary from the updater. What disassembler do you use for SH4?
pipman wrote:
Thanks dr-carlos. Your code worked as intended. As I understand it a syscall involves moving a syscall number to r0 and then jumping to 0x80020070. In your assembly you haven't referenced 'index' ie the addin number. I guess the syscall knows what the addin number is since this the third argument to a function ends up being copied to r6.

Could an addin be run by reading the g3a from 0x7000 and copying into memory then jumping to the start of what we copied?
I would like to investigate some syscalls myself. I have extracted the 11MB binary from the updater. What disassembler do you use for SH4?


Yes, the syscall I run isn't actually the addin itself, but the syscall which the main menu uses to open addins from a certain 'index'. This allows it to do all the setup stuff that you will probably need to do if you want to jump straight to the g3a to run it (though I haven't investigated this specifically and don't know how possible it is).

I use Lephenixnoir's fxos disassembler: https://git.planet-casio.com/Lephenixnoir/fxos/

I'd also recommend having a quick read through my guide on SuperH 4 assembly if you're not too familiar with it: https://bible.planet-casio.com/drcarlos/Assembly.html
When I look at your decompiled syscalls and I look at the code and see functions like Address80365196(0), are these other syscalls or just a jump to the address? How do I find the syscall number from the address so that I can call them?
These are just jumps to the address. In that specific example there is 0 in r4 (the first parameter).
Most addresses on the calculator do not have syscalls associated with them, so you can't call them like that. Instead, if you want to call that address, i suggest using a function similar to this, which looks through the instructions in a syscall which references that address and then jumps to it:

Code:

static void SaveAndOpenMainMenu(void) {
  int addr;

  // get the pointer to the syscall table
  addr = *(unsigned int *)0x8002007C;

  // now addr has the address of the syscall table in it

  if (addr < (int)0x80020070)
    return;
  if (addr >= (int)0x81000000)
    return;

  // get the pointer to syscall 1E58 - SwitchToMainMenu
  addr += 0x1E58 * 4;
  if (addr < (int)0x80020070)
    return;
  if (addr >= (int)0x81000000)
    return;

  addr = *(unsigned int *)addr;
  if (addr < (int)0x80020070)
    return;
  if (addr >= (int)0x81000000)
    return;

  // Now addr has the address of the first operation in %1e58

  // Run up to 150 times (300/2). OS 3.60's is 59 instructions, so this should
  // be plenty, but will let it stop if nothing is found
  for (unsigned short *currentAddr = (unsigned short *)addr;
       (unsigned int)currentAddr < ((unsigned int)addr + 300); currentAddr++) {
    // MOV.L GetkeyToMainFunctionReturnFlag, r14
    if (*(unsigned char *)currentAddr != 0xDE)
      continue;

    // MOV #3, 2
    if (*(currentAddr + 1) != 0xE203)
      continue;

    // BSR <SaveAndOpenMainMenu>
    if (*(unsigned char *)(currentAddr + 2) != 0xB5)
      continue;

    // MOV.B r2, @r14
    if (*(currentAddr + 3) != 0x2E20)
      continue;

    // BRA <some addr>
    if (*(currentAddr + 4) != 0xAFFB)
      continue;

    // NOP
    if (*(currentAddr + 5) != 0x0009)
      continue;

    unsigned short branchInstruction = *(currentAddr + 2);

    // Clear first 4 bits (BSR identifier)
    branchInstruction <<= 4;
    branchInstruction >>= 4;

    // branchInstruction is now the displacement of BSR

    // Create typedef so we can cast the pointer
    typedef void (*voidFunc)(void);

    // JMP to disp*2 + PC + 4
    ((voidFunc)((unsigned int)branchInstruction * 2 +
                (unsigned int)currentAddr + 4 + 4))();

    return;
  }
}
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement