Today, I made some progress in running code from the Prizm ILRAM and the other two on-chip RAM areas of the CPU. This work is based on the progress at http://www.cemetech.net/forum/viewtopic.php?t=8076&start=0 .

First, I successfully changed my linker script to include the new memory areas. Then I modified the crt0.S code on libfxcg, for it to copy the code from those sections on the g3a into the proper memory areas. And then, using GCC's section attribute features, I started specifying functions and global variables to run from these areas.

It works fine, as long as we don't move out of our add-in. If I start using timer hacks to have code run outside of my add-in (i.e. when it is not even mapped into memory), weird things start happening. But first I'll show my code...


Code:

char buffer1[10] __attribute__((section(".ocram"))); // this can't go on ilram along with the void below because it causes a "section type conflict"
void dbgtimerhandler() __attribute__((section(".ilram")));
void dbgtimerhandler() {
  DefineStatusMessage((char*)buffer1, 1, 0, 0);
}

The code above is the timer handler for the timer I'll be installing and starting on the snippet below.

Code:
strcpy(buffer1, "test msg");
int dtm = Timer_Install(3, dbgtimerhandler, 5000);
if (dtm > 0) { Timer_Start(dtm); }


As you can see, everything is set to be outside of the add-in stack or heap: a buffer goes on one of the on-chip ram areas and the timer handle goes on the ILRAM (both can't go on the ilram because then GCC will start complaining about section type conflicts. I think I understand why this happens, look up Google if you don't know).
On the timer handler, nothing is called that belongs to the add-in: DefineStatusMessage is a syscall and thus, supposedly it should be available from anywhere in the OS... right?
(by the way, yes we know for sure the OS doesn't mess with the ILRAM or the other on-chip RAM)
The timer is installed and started from the add-in stack, but that shouldn't matter. The timer is installed on slot 3 which is a "system" slot and doesn't get uninstalled on app change.

Now some good news: as long as we don't take the add-in out of the current stack mapping (that is, we can go to the Main Menu, as long as we don't open another app), the timer works fine and does what it's supposed to do.

Now the bad news: If we start another non-add-in app, well, we don't get a straight system error like we would get if we merely used the add-in stack as the place for the code (because by the time the timer would run, the memory contents would be different). But we get all sorts of weirdness. Sometimes the OS just locks up. With a more elaborate code on the timer handler (which involved using itoa and incrementing a variable on on-chip RAM), a funny thing would happen: the g3p file selection screen would pop up every time the timer ran, and the timer handler wouldn't do what it was supposed to...

If we (acting fast enough to avoid a system error due to so many Pict screens being open) return to the add-in we left, the our ILRAM-based timer handler works fine again. If we launch another add-in... I could only make the calculator reboot without error.

I'm unsure on which conclusion I should take:
- Outside of add-ins, syscalls aren't to be called like we usually call them, and lead to weirdness.
- Although I told GCC to put everything related to the timer handler on memory sections not related to my add-in, it is still linking these against my add-in for some reason, leading to the weirdness. Related to this: I understand this kind of investigation is much better done when coding entirely in assembly, so that we can be sure where the code goes and where it jumps to... but unfortunately I'm not knowledgeable enough with asm to do it.

Any suggestions on what I may be doing wrong, or other things to investigate?

EDIT:
I made the timer handle just increment the value of an integer variable located in one of the additional on-chip RAM areas*, and nothing else. With INSIGHT I inspected that area, and it appears the timer keeps running without problem, as the variable is incremented as it should.
So the problem is, I would say, with calling syscalls. I think I already know why: GCC is putting the syscall calling macro on the add-in-specific memory areas. I need to move that macro to ILRAM too, or else I won't be able to use syscalls in the timer handler.

* sorry, don't know what else to call it. On my setup I call these areas ocram and ocram2.

EDIT2: I'm already having some fun.

The "small" problem is, I had to change memory addresses directly in order to change the statusbar settings (hint: look near address 0x8804F48A), and even had to implement a separate strcpy to have it run from ILRAM, too, as the usual one is either a syscall or in libfxcg, and thus still unavailable for use.
In theory it should be possible to put the syscall calling macro on ILRAM too, but how?
gbl08ma wrote:


Code:

char buffer1[10] __attribute__((section(".ocram"))); // this can't go on ilram along with the void below because it causes a "section type conflict"
void dbgtimerhandler() __attribute__((section(".ilram")));
void dbgtimerhandler() {
  DefineStatusMessage((char*)buffer1, 1, 0, 0);
}

Declare subsections under .ilram. Something like this (note the .ilram.*).

Code:
.ilram : {
    _bilram = . ;
    *(.ilram) *(.ilram.*) *(COMMON);
    _eilram = . ;
} > ilram AT>rom

Code:
char foo[16] __attribute__((section(".ilram.data")));

void bar() __attribute__((section(".ilram.text"))) {
    for (int i = 0; i < sizeof(foo); i++)
        foo[i]++;
}
Thanks Tari, that definitely helped. I actually happened to have the linker script correctly set up, I just didn't know of the trick of adding the subsection after the section in the GCC section attribute.

Now I'm going to try to run code out of the unused (at least I believe they are unused) sections of RS memory. It would be very useful because it is retained on power off, meaning the timer will keep working even after a power off/on cycle. Let's hope the "unused" isn't actually used by the OS for the power off code...

EDIT: yes, I can run code from that section of RS memory I chose, and it appears that section of RS memory is also retained on reboot (at least, on the kind of reboot the emulator does). This is good because for restoring the effects is just a matter of setting a timer pointing to the same memory address; at the same time it's bad because if it messes with the OS, the only way to stop it is to take out the batteries while the calc is powered on, so that hopefully RS memory is cleared without backup.
I don't really understand all the technical stuff, but does this mean we could potentially have a clock in the status bar?
Not now that my Prizm broke due to these experiments.
woah. do you think you can send it to casio or did you void the warranty?
I'll send it to Casio as I don't think I voided the warranty. The functions in question were all int something Smile
OK, now seriously. I'll first wait for Simon to say something, then if he says nothing, I'll let my calc die and will try to send it for repairs through the store under the 2-year warranty. If they decide not to repair it (it's almost approaching the end of the two years), I'm not sure if I'll send it to Casio under the 3-year warranty: I'd probably have to pay shipping, and nothing says they'll repair or replace it. Furthermore, I need the calc probably earlier than they can get it back to me. So I'd need to buy a new one.
Right now I'm more inclined into buying a new one and eventually send this one for repairs, and if they repair it, the end result would be that I get two Prizms. Not really useful as I plan on withdrawing myself from Prizm development after this episode, but I could always sell both when I stop needing them, and get some money back.

Or I could auction my broken calc, as the calc that helped bring to light Utilities, Eigenmath and lots of knowledge about CASIOWIN, the OS. Wink Nah, better save that for when I am world-famous Very Happy
  
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