Hello everyone,
Sorry but this needs a bit of context, hang with me please:
I am working on a sort of mod for my calculator (Casio FX CG-50). I have already managed to develop my own little add-in that is a sort of animation on the screen with user input affecting it, using the PrizmSDK.

Now, the final thing I want to add is to be able to mod my calculator to add a rainbow changing frame using the DrawFrame function. This works flawlessly within my add in using a user timer. The thing with these (user timers) is that they\'re limited to the child process you\'re in. Since by entering another app I terminate the old child process (my app) it then automatically deletes it and the RAM my app was using is cleared. Also, exiting to the main menu instantly pauses it.

A way around this is using system timers (I\'ve read the documentation on Wiki Prizm and I know it\'s dangerous, but I\'m ok with it - it\'s only supposed to be a cool trick to show to my friends). By doing that, if I exit into the main menu the rainbow function continues which I presume to be because the RAM isn\'t cleared yet and it\'s a global timer so the handler I have set for the timer is still accessible even though I\'m outside the app, which is exactly what I want, and it is quite cool to see (so at least I confirmed it can work until there). If I enter another app, though, it is cleared so I get a system error since that pointer to the function now points nowhere: System Error Address(R), and the memory address provided keeps changing in line with how quick I set the timer to update. All system timers do this except 4 which is non-changeable as it\'s reserved by the OS.

I have tried a lot of things to try and remedy this. One of them was trying to place the pointer in a non volatile spot. While searching through other projects I came across some instances where people did things like:


Code:
void backupOCRAM2(void* buffer) {
  memcpy(buffer, (char*)0xE5017000, 8192);
} //This is from an image processing application


(https://github.com/gbl08ma/imageviewer/blob/master/src/imageGUI.cpp#L53)
to write to a non volatile spot for Prizm apps. I suspect that these addresses have changed because trying to change the linker script to include another spot in memory and then adding that to my C code proved to be unsuccessful. On the WikiPrizm (https://prizm.cemetech.net/OS_Information/Processes/) there\'s information about the addresses for the stack and the heap, but not anything permanent. This is probably too hard and out of my current capabilities but I would greatly appreciate it if anyone who knew anything about system timers and/or non volatile memory locations that would persist even when leaving the app could provide a bit of input. It seems hard, but seeing some other projects doing some stuff such as the code excerpt I provided gives me a bit of hope that such a thing is possible.

Thanks a lot
I don't really know anything about system timers, but if you're looking for non-volatile memory, have a look at https://bible.planet-casio.com/lephenixnoir/en/sh7305/calc/memory (Lephe's map of all the fundamental memory regions on the calculator).

I think that example is trying to use YRAM, which makes a lot of sense since the OS doesn't interact with it. But, the PrizmSDK already has ILRAM mapped, which is seemingly unused by the calc according to Lephe's map, so I'd probably just use that - unless you're going to need more than 4K of memory.
Hi!

Yes, ilram actually does seem to be perfect because it's already mapped by the PrizmSDK and it's seemingly not used by the OS and it's non volatile so thanks for letting me know. My code is only 2 lines long so 4k is more than enough. I'm not sure if I've done something wrong, though, because when setting it there, upon entering the add-in and calling the function I instantly get an "Illegal Code Err" with Target = 00000000 and PC = 00000000. By the way this is without any system timers at this point, just calling the method. This makes me thing it's not actually being set anywhere/properly so that's why the address is just empty, so it's an "illegal operation" because it's calling it at that address of only zeroes. It was my limited understanding that to actually place it in ilram all I had to do was add an attribute flag on the top of my method as such:
attribute__((section(".ilram"))) void frame(void)
But I feel that that's not actually setting it correctly. Probably there's more to it than that. Do you have any idea? The linker script has been left as default
ilram (rwx) : o = 0xE5200000, l = 4k /* According to http://www.cemetech.net/forum/viewtopic.php?t=9334 */
and
.ilram : {
_ilramld = LOADADDR(.data) ;
_silram = . ;
*(.ilram)
*(.ilram.*)
_eilram = . ;
} > ilram AT> rom
So it's loaded from rom into ilram? Doesn't seem wrong. Maybe I need to run the compiler with special flags?

Please forgive my lack of knowledge on this matter if it's a very quick fix. Thanks a lot!
Just spent a couple hours investigating this, here's a few answers:

1. The linker script:

Code:

MEMORY
{
        ...
        ilram (rwx) : o = 0xE5200000, l = 4k // This creates a memory address variable named "ilram" - it's rwx (readable and writable) and 4KiB long
}

SECTIONS
{
        ...
        .ilram : { // Creates a section named ".ilram"
                _ilramld = LOADADDR(.data) ; // Exports a variable to the user named _ilramld, equal to the address the .data section is loaded to
                _silram = . ; // Exports a variable to the user named _silram, equal to the address the ".ilram" section starts at
                *(.ilram) // Include all code under the ".ilram" section here
                *(.ilram.*) // Include all code under sections starting with ".ilram." here
                _eilram = . ; // Exports a variable to the user named _eilram, equal to the address the ".ilram" section ends at
        } > ilram AT> rom // Save the section code into the G3A file (rom) and tell the linker that this code will be located at the "ilram" address from earlier (0xE5200000) so it can determine addresses and the like
        ...
}


So, it seems like the .ilram section should save your function to ILRAM? Well, no. I can't seem to get this to work at all (without a SYSTEM Error as you mentioned), nor find any code that actually implements the copying of function code from ROM into the ILRAM addresses where the linker thinks they are located.

2. Let's use assembly

The only way I think of to definitely get ILRAM code to work is to write some assembly. I have other work to do now, so I can't do more testing for the moment to determine if there's an easier way to do this. But the thinking that I went with that definitely worked was:
- Write a test function in assembly
- Write another function in assembly which copies the test function into ILRAM
- Copy the test function into ILRAM
- Run the test function (optional)
- In an entirely separate app, load and run the test function from ILRAM

My test function:

Code:

__asm__(".text; "
    ".align 2;"
    ".global _test;"
    "_test: mov #3, r4; mov #4, r5; mov.l casiowin, r6; mov #2, r7;"
    "mov.l sc_addr, r2; mov.l PrintPixXY_NormallerRows, r0; jmp @r2; nop; " // Equivalent to PrintXY(3, 4, "CASIOWIN", 0, 0);

    ".align 4;"
    "PrintPixXY_NormallerRows: .long 0x18f8;"
    "sc_addr: .long 0x80020070;"
    "casiowin: .long 0xfd80131e;" // Is "CASIOWIN" on the fx-CG 50 Emulator; swap this to 0x80000e98 (or the address of any other chosen string) if running on hardware
);


Then, to copy the test into ILRAM:

Code:

__asm__(".text;"
        ".align 2;"
        ".global _test_copy;"
        "_test_copy: mov.l memcpy_addr, r2; mov.l ilram_addr, r4; mov.l test_addr, r5; "
        "mov #40, r6; jmp @r2; nop;" // Equivalent to memcpy(0xe5200000, test, 40);

        ".align 4;"
        "test_addr: .long _test;" // The address of the test function
        "memcpy_addr: .long _memcpy;" // The address of the memcpy function
        "ilram_addr: .long 0xe5200000;" // The start address of ILRAM
);


Then to copy the test function and run it to verify it works:

Code:

int main(void) {
  char *buf = (char *)malloc(10);
  memcpy(buf, "  Test", 7);
  PrintXY(1, 5, buf, 0, 0); // This code is arbitrary, but very important. If you do not reference memcpy in your program, in a way that forces it to be included in the compiled product (and not just optimised out by GCC), then you will not be able to reference _memcpy in the _test_copy function above and you will not be able to actually copy the test function into ILRAM.

  test_copy(); // Copy the test function into ILRAM

  void (*ilram)(void) = (void (*)(void))0xe5200000; // Get pointer to the test function
  ilram(); // Run and test it

}


Here's the code all up:

Code:

#include <fxcg/display.h>
#include <fxcg/keyboard.h>
#include <stdlib.h>
#include <string.h>

void test_copy();

__asm__(".text;"
        ".align 2;"
        ".global _test_copy;"
        "_test_copy: mov.l memcpy_addr, r2; mov.l ilram_addr, r4; mov.l "
        "test_addr, r5; mov #40, r6; jmp @r2; nop;"

        ".text; "
        ".align 2;"
        ".global _test;"
        "_test: mov #3, r4; mov #4, r5; mov.l casiowin, r6; mov #2, r7;"
        "mov.l sc_addr, r2; mov.l PrintPixXY_NormallerRows, r0; jmp @r2; nop; "

        ".align 4;"
        "PrintPixXY_NormallerRows: .long 0x18f8;"
        "sc_addr: .long 0x80020070;"
        "casiowin: .long 0xfd80131e;"
        "test_addr: .long _test;"
        "memcpy_addr: .long _memcpy;"
        "ilram_addr: .long 0xe5200000;");

int main(void) {
  char *buf = (char *)malloc(10);
  memcpy(buf, "  Hi", 5);
  PrintXY(1, 5, buf, 0, 0);

  test_copy();

  void (*ilram)(void) = (void (*)(void))0xe5200000;
  ilram();

  int key;
  while (1)
    GetKey(&key);

  return 0;
}


And the code for a separate application to test loading the ILRAM function:

Code:

#include <fxcg/keyboard.h>

int main(void) {
  void (*ilram)(void) = (void (*)(void))0xe5200000;
  ilram();

  int key;
  while (1)
    GetKey(&key);

  return 0;
}


Let me know if that makes sense and if you have any further questions!
Woah, going back to good ol' assembly.

After some very quick investigation, it works!!! I greatly appreciate the work you've done here. It definitely takes someone smart to be able to figure all this out.

And for everyone seeing this, some quick experiments show that user timers DO in fact work. This whole time I was banking on the fact that even if I could store the code in a non-volatile spot the user timers wouldn't just go ahead and mess it up straight away since the OS would request them. However, (just with the limited amount of time I've tried this out) it seems to be working fine. Only issue is that when you turn it off you immediately get the same Illegal Code Err because ilram is cleared when you turn it off so before it gets to shut down it fires and the same thing happens all over again. Not to fret though as this can be fixed but giving control back to the OS by simply using Timer_Deinstall before shutting it down. Maybe there's a better way but for now this is more than good enough. I'll also reply again to this post once I get more experimentation done to see if any timers are better than others and if there's ways to deinstall automatically etc.

Thanks a lot man!
I've been trying all day long but I can't seem to get it Neutral

I have managed to call one of the methods I wanted to, namely DrawFrame. This works very well and I'm happy to see it's applied globally with the system timers. The assembly code for it is as follows:

Code:
__asm__(
    //memcopy to copy DrawFrame into ilram
    ".text;"
    ".align 2;"
    ".global _asm_memcopy;"
    "_asm_memcopy: mov.l memcpy_addr, r2; mov.l ilram_addr, r4; mov.l "
    "draw_frame_addr, r5; mov #40, r6; jmp @r2; nop;"

    //DrawFrame function
    ".text; "
    ".align 2;"
    ".global _draw_frame;"
    "_draw_frame: mov.l PINK, r3;"
    "mov.l sc_addr, r2; mov.l DrawFrame, r0; jmp @r2; nop; "

    //Global variables
    ".align 4;"
    "DrawFrame: .long 0x02A8;"
    "PINK: .long 0xFE19;"
    "sc_addr: .long 0x80020070;"
    "draw_frame_addr: .long _draw_frame;"
    "memcpy_addr: .long _memcpy;"
    "ilram_addr: .long 0xe5200000;"
);


Thing is I only managed to do this basing myself off the code you gave me (it's my first time writing assembly lol ). It's a simple function that only takes in one parameter so it's not a big deal. In C it would be

Code:
void pinkFrame(void)
{
    DrawFrame(COLOR_PINK);
}


The complicated part is the second thing I want to do. I want to display my own mini logo in the status bar. I spent a very long time trying out different methods and concluded that Bdisp_SetPoint_VRAM would be the best way to do so. This sets pixels individually in VRAM but I'll loop through an array and set them. I know it would be way better to just copy in a sprite from the get-go, however, that (Bdisp_WriteGraphVRAM(struct display_graph* gd), has a massive 20 argument struct you had to pass along to it and I could not for the life of me figure out how to do that in assembly. Then the struct also needs a pointer to where the sprite data is stored so that's another problem. Too hard imo. At one point I even thought about just making it with lots of small rectangles (Bdisp_Rectangle) but that method, unfortunately, doesn't draw inside of the status area. Thus, the only solution (probably not the best one) I could come up with was the array idea I mentioned.

Luckily I've confirmed memcpy does work if I'm just writing an array of ints to it

Code:
memcpy(0xe5200000, logo, 1408); //logo is an array of ints

Since my logo is just two colours I've decided to display it in 1s or 0s, with 1s being red and 0s being black. In C I could quite easily do this as such:

Code:
void drawLogo()
{
    volatile unsigned int* ptr = (int*)0xe5200000;                                     
    for (int i = 0; i < 30; i++)
    {
        for (int j = 0; j < 16; j++)
        {
            if (ptr[(i * 16) + j] == 1)
            {
                Bdisp_SetPoint_VRAM(j + 310, i, 0xF800);
            }
            else
            {
                Bdisp_SetPoint_VRAM(j + 310, i, 0x0000);
            }
        }
    }
    Bdisp_PutDisp_DD();
    //This code works under normal circumstances, but obviously not outside of the add in.
}

But in assembly it's a totally different story. I looked up some tutorials on how to do for loops in assembly but it didn't seem to work. It would be a lot to ask for you to write this in assembly since I know how complicated it is, so I'd understand if you couldn't. If you can't, would you please direct me to where you learnt how to write assembly for the Prizms? Or where you'd go next with this? I haven't had much luck finding resources for this online. It's very fascinating but it's a niche part of an already somewhat niche community.

As for the timers if anyone wants to know they all seem to, remarkably enough, not be used by the OS. The code for installing one is

Code:
void timerStart(void)
{
    void (*ilram_func)(void) = (void (*)(void))0xe5200000; //I'd have to change this to after my array of ints. So I guess 0xe5200000+1409. But if your method is right at the beginning then leave it that way. Credit goes to dr-carlos for figuring it out.
    int cursorTimerID = Timer_Install(2, ilram_func, 500);
    Timer_Start(cursorTimerID);
}

I used timerID 2 but 1,2 and 3 all work the same in my testing and don't affect anything. 4 can't be used. There'll be no error but it just won't let you. From 5 onwards it's user timers. However safe it may seem, I am not responsible if something happens, after all on WikiPrizm it mentions
Quote:
Using system timers is almost always a bad idea and can lead to a permanent brick

But yeah no problems on my end. The OS might have some weird quirk where it randomly requires it and then something bad could happen so be careful.

Thanks.!
Good to see your code working!

Writing that function in assembly is very doable but also a bit of work, and not very useful long-term as you'll want to be able to write more and more complex functions.

So, I went and investigated further why our .ilram section C code wasn't working.
It turns out the crt0.S which runs to initialise the addin on startup was never copying the data into ILRAM. This was a simple fix, plus I've written a Python script (this is very important) to analyse the dependencies (Bdisp_SetPoint_VRAM, etc.) and include them in the ILRAM as well.

I was self-taught in assembly, but if you're interested in learning about it, I have some notes to explain how the SuperH 4 assembly works over on Planete-Casio: https://bible.planet-casio.com/drcarlos/Assembly.html

I've used your code to draw a QR code (it's a rick roll) to the screen over all other apps, and included all the code here: https://gitlab.com/dr_carlos/global-code

As mentioned in the repo, I wouldn't recommend just mindlessly running this code on your actual Prizm given the issues with system timers, etc. But it's been working well in the emulator! I think the issue with system timers has mostly to do with them being used in file operations - not something you want to mess with!

Let me know if you have any questions!
Hi!

Thank you so much for looking into it. You've devised a very clever solution to it. Installing your .g3a from what you uploaded on GitLab works perfectly and I can now go to the main menu with the QR (or shall we say RickRoll Laughing ) showing.

The only problem I have now is trying to make it myself and recompiling the SDK. This is probably common sense as the instructions are simple, but I must be doing something wrong because it doesn't work. From my understanding what you've done is change the crt0.s file which are the start-up instructions for the add-in. I downloaded just the libfxcg folder and found the original crt0.s file and compared them and saw the section you added for ilram.

Until now I've just been using the pre-compiled SDK as I am on Windows (https://github.com/Jonimoose/libfxcg/releases/tag/v0.6). When you go to download it, it also gives you the option to download only the .a files (namely libc.a and libfxcg.a), so I assume this is what I will need to replace in my SDK's lib folder which already contains those two files so that I can update the SDK. I first added my SDK installation as an enviroment variable. Afterwards, using the MakeFiles I found in libfxcg-master\libfxcg and libfxcg-master\libc and then dragging all the files to PrizmSDK-win-0.6\bin (while updating the crt0.s file in misc) and finally running make.exe, I could make the two new .a files (libc.a and libfxcg.a). I then moved these to PrizmSDK-win-0.6\lib and replaced the old ones. This didn't make a difference and it still crashes upon entering another app. Is there another file I have to make and replace? Or did I do something wrong?

The output of the python script gives me this:

python ../link_script.py sh3eb-elf-gcc ilram.o main.o -mb -m4a-nofpu -mhitachi -nostdlib -Wl,-static -Wl,-gc-sections -LD:\Downloads\PrizmSDK-win-0.6\PrizmSDK-win-0.6/lib -lc -lfxcg -lgcc -o D:/Downloads/PrizmSDK-win-0.6/PrizmSDK-win-0.6/projects/global-code-main/global-code-main.bin
Memory region Used Size Region Size %age Used
rom: 7096 B 1 MB 0.68%
ram: 6400 B 64 KB 9.77%
ilram: 4 B 4 KB 0.10%
mkg3a -n basic:GlobalCode -i uns:../unselected.bmp -i sel:../selected.bmp D:/Downloads/PrizmSDK-win-0.6/PrizmSDK-win-0.6/projects/global-code-main/global-code-main.bin D:/Downloads/PrizmSDK-win-0.6/PrizmSDK-win-0.6/projects/global-code-main/global-code-main.g3a

Only 4b is too low, so I'm assuming that's the problem. The python script is working it's just that it's not being placed into ilram I'm guessing.

Sorry again if this isn't supposed to be this complicated!!
I've also checked out your notes and it clears a few things up. Most notably the registers as online all I could find was x86 stuff. Great work with that!
Well I just realised why I wasn't sure what was going on. I had previously downloaded the release instead of the source code on git hub so that's why I had to manually change everything and the folders weren't where they were supposed to be. Stupid mistake... Now it makes much more sense with the .bat files in each directory, but it's the same thing I've done before just simpler - so my problem still persists.

What I did was this:
1. Added an enviroment variable called FXCGSDK in Control Panel. (D:\Downloads\PrizmSDK-master\PrizmSDK-master)
2. Added the new crt0.s file to D:\Downloads\PrizmSDK-master\libfxcg\misc, in the process overwriting the old, faulty one.
3. Ran clean.bat, then make.bat
4. Went back to projects and in there is a copy of yours. So I ran make.bat.
This generates the files but they're not placed in ilram, as the output I posted earlier indicates. If I add __attribute__((section(".ilram"))) at the top of the methods that have to go there the output reflects this (goes up to like 300 bytes). But this doesn't work and it isn't the way to do it.

Sorry for the inconvenience.
thunker12 wrote:
Hi!

Thank you so much for looking into it. You've devised a very clever solution to it. Installing your .g3a from what you uploaded on GitLab works perfectly and I can now go to the main menu with the QR (or shall we say RickRoll 0x5 ) showing.


Good to know!

thunker12 wrote:

The output of the python script gives me this:


Code:
python ../link_script.py sh3eb-elf-gcc   ilram.o main.o -mb -m4a-nofpu -mhitachi -nostdlib -Wl,-static -Wl,-gc-sections  -LD:\Downloads\PrizmSDK-win-0.6\PrizmSDK-win-0.6/lib -lc -lfxcg -lgcc -o D:/Downloads/PrizmSDK-win-0.6/PrizmSDK-win-0.6/projects/global-code-main/global-code-main.bin
Memory region         Used Size  Region Size  %age Used
             rom:        7096 B         1 MB      0.68%
             ram:        6400 B        64 KB      9.77%
           ilram:           4 B         4 KB      0.10%
mkg3a -n basic:GlobalCode -i uns:../unselected.bmp -i sel:../selected.bmp D:/Downloads/PrizmSDK-win-0.6/PrizmSDK-win-0.6/projects/global-code-main/global-code-main.bin D:/Downloads/PrizmSDK-win-0.6/PrizmSDK-win-0.6/projects/global-code-main/global-code-main.g3a


Only 4b is too low, so I'm assuming that's the problem. The python script is working it's just that it's not being placed into ilram I'm guessing.


Yep, you're right on the money there. Here's what my output looks like:

Code:
sh3eb-elf-gcc -MMD -MP -MF /home/me/Prizm/GlobalCode/build/ilram.d -DTARGET_PRIZM=1   -I/home/me/Prizm/GlobalCode/build -I/home/me/libfxcg/include -mb -m4a-nofpu -mhitachi -nostdlib -Og -Wall -ffunction-sections -fdata-sections -c /home/me/Prizm/GlobalCode/src/ilram.c -o ilram.o
sh3eb-elf-gcc -MMD -MP -MF /home/me/Prizm/GlobalCode/build/main.d -DTARGET_PRIZM=1   -I/home/me/Prizm/GlobalCode/build -I/home/me/libfxcg/include -mb -m4a-nofpu -mhitachi -nostdlib -Og -Wall -ffunction-sections -fdata-sections -c /home/me/Prizm/GlobalCode/src/main.c -o main.o
python ../link_script.py sh3eb-elf-gcc   ilram.o main.o -mb -m4a-nofpu -mhitachi -nostdlib -Wl,-static -Wl,-gc-sections  -L/home/me/libfxcg/lib -lc -lfxcg -lgcc -o /home/me/Prizm/GlobalCode/GlobalCode.bin
Memory region         Used Size  Region Size  %age Used
             rom:        7032 B         1 MB      0.67%
             ram:        6400 B        64 KB      9.77%
           ilram:         160 B         4 KB      3.91%
mkg3a -n basic:GlobalCode -i uns:../unselected.bmp -i sel:../selected.bmp /home/me/Prizm/GlobalCode/GlobalCode.bin /home/me/Prizm/GlobalCode/GlobalCode.g3a


This means that the linker script isn't outputting everything into ilram as it should - it has no relation to the crt0.S or anything else in libfxcg. There's a number of reasons this could be the case, so for better debugging I'd ask if you could run make.bat and then put the contents of the file in build\link_script.x into a paste bin (e.g. https://pastebin.com/) so I can see what is happening in the linking?

thunker12 wrote:

I've also checked out your notes and it clears a few things up. Most notably the registers as online all I could find was x86 stuff. Great work with that!


Great to hear! Most of the stuff you see online is definitely x86, or ARM, or similar so it's useful to have a reference.

thunker12 wrote:
Well I just realised why I wasn't sure what was going on. I had previously downloaded the release instead of the source code on git hub so that's why I had to manually change everything and the folders weren't where they were supposed to be. Stupid mistake... Now it makes much more sense with the .bat files in each directory, but it's the same thing I've done before just simpler - so my problem still persists.

What I did was this:
1. Added an enviroment variable called FXCGSDK in Control Panel. (D:\Downloads\PrizmSDK-master\PrizmSDK-master)
2. Added the new crt0.s file to D:\Downloads\PrizmSDK-master\libfxcg\misc, in the process overwriting the old, faulty one.
3. Ran clean.bat, then make.bat
4. Went back to projects and in there is a copy of yours. So I ran make.bat.
This generates the files but they're not placed in ilram, as the output I posted earlier indicates. If I add __attribute__((section(".ilram"))) at the top of the methods that have to go there the output reflects this (goes up to like 300 bytes). But this doesn't work and it isn't the way to do it.

Sorry for the inconvenience.


Good to hear that you fixed up the crt0.S problem.
There is absolutely no need to manually use the .ilram section - this is the whole point of the link_script.py script. If you could send through a pastebin of the created build/link_script.x (as explained above) that would be wonderful!
Here's the pastebin with both the full output and the contents of the link_script.x https://pastebin.com/bRT602FN

I have a feeling it's because I haven't placed a file where it's supposed to be, or the MakeFile is not pointing to the correct files. 4 bytes tell me that it's just including the header, but no data itself so the ilram.o and ilram.d files aren't being included. Just to be clear, where is your libfxcg.a file? Mine is at D:\Downloads\PrizmSDK-master\PrizmSDK-master\libfxcg\libfxcg.a. So in the root directory and then going to libfxcg. However looking at the link_script.x I see *lib\libfxcg.a:Bdisp_PutDisp_DD.o (.text). So is it supposed to be in lib? I've moved the file there but still nothing. This leads me to believe my SDK structure isn't set up properly so there's probably other things.

Mine is set up this way from root:
lib has libc.a and libfxcg.a
libfxcg has misc,proj and syscalls.

Thank you again.
thunker12 wrote:
Here's the pastebin with both the full output and the contents of the link_script.x https://pastebin.com/bRT602FN

I have a feeling it's because I haven't placed a file where it's supposed to be, or the MakeFile is not pointing to the correct files. 4 bytes tell me that it's just including the header, but no data itself so the ilram.o and ilram.d files aren't being included. Just to be clear, where is your libfxcg.a file? Mine is at D:\Downloads\PrizmSDK-master\PrizmSDK-master\libfxcg\libfxcg.a. So in the root directory and then going to libfxcg. However looking at the link_script.x I see *lib\libfxcg.a:Bdisp_PutDisp_DD.o (.text). So is it supposed to be in lib? I've moved the file there but still nothing. This leads me to believe my SDK structure isn't set up properly so there's probably other things.

Mine is set up this way from root:
lib has libc.a and libfxcg.a
libfxcg has misc,proj and syscalls.

Thank you again.


Thank you for sending through your output!
The issue as far as I can see is because I am running Linux and you are running Windows, so my script wasn't properly designed to work on Windows. I now have a proper path implementation (that doesn't assume '/' delimited paths instead of '\' delimited), so if you could update your copy of the GlobalCode repo, it should be fixed.

If it still doesn't work, could you also send through the file build/output.map? That will allow me to see exactly how the linker is interpreting the created link script.
That unfortunately didn't work.
Looking at the output.map file, though, reveals some interesting things. From what I can tell only the variable _yram (which is the pointer present in ilram.h and ilram.c) is being placed in ilram. Or maybe that's something else but that's what I think it is
ilram.o(.data.*)
.data.yram 0xe5200000 0x4 ilram.o
0xe5200000 _yram
The rest, (drawLogo) seems to be going to 0x003001a0 which I believe to be ROM - this explains why it doesn't work. But I'm stumped as to why it is going to ROM but the yram pointer isn't.
Here is a dropbox link to my entire SDK:
https://www.dropbox.com/scl/fo/bc99noopqren02c64q1ws/AHyBwMsVG49cf-UJIqOQJQ0?rlkey=g4rwc9mtjty6rlm94u81bqwja&st=i0f4x5f1&dl=0
But to skip straight to output.map:
https://www.dropbox.com/scl/fi/to21e9vv6tbfjxilpult5/output.map?rlkey=v6llti5sbimqye8v7tcmmaxyq&st=66x09p9g&dl=0
I think I've figured it out!

In my version of GCC (11.1.0) and binutils (2.39), the two .text section specifications in the link map are treated separately, whereas in the older versions provided on Windows, the sections are combined, thus putting the *(*.text) command into the .text section before .ilram is able to capture the relevant objects/code.

Thus, I have relabled the first section specification to name it '.pretext' and your project now compiles properly in my wine setup. Please update your GlobalCode repo, re-make, and see if the fix works for you!
Last piece of the puzzle... SOLVED!

Can't believe you found that out. I wish to be able to be like you one day; being able to give back to the community.

Thanks a lot man. This will probably be useful for others too as I've seen examples of people backing stuff up (such as the image buffer example) but never runnning code from outside, so it seems like relatively untouched territory.

Thanks again, and have a good day Very Happy
And thinking about it too, even if it's little, ilram (or yram) is supposed to be much quicker to access. You don't have to necessarily display something. In other words, some simple calculations could be done in the background if space and peformance permit. Just some thoughts, but I think this has some potential for the community. Some fantastic work you've done here.
thunker12 wrote:
Last piece of the puzzle... SOLVED!

Can't believe you found that out. I wish to be able to be like you one day; being able to give back to the community.

Thanks a lot man. This will probably be useful for others too as I've seen examples of people backing stuff up (such as the image buffer example) but never runnning code from outside, so it seems like relatively untouched territory.

Thanks again, and have a good day Very Happy


No worries at all!

thunker12 wrote:
And thinking about it too, even if it's little, ilram (or yram) is supposed to be much quicker to access. You don't have to necessarily display something. In other words, some simple calculations could be done in the background if space and peformance permit. Just some thoughts, but I think this has some potential for the community. Some fantastic work you've done here


You're totally right here - this has massive implications! Thank you for coming up with this idea.

If you'd like to see another potential application - have a look at the 'clock' branch: https://gitlab.com/dr_carlos/global-code/-/tree/clock
This shows a real-time clock in the status bar throughout all apps!

You may need utilities to set the time of your clock if you are running on a real calculator: https://github.com/ComputerNerd/utilities , but if you are using the emulator it should already be set Smile
I've gone ahead and downloaded the clock .g3a and that's some really cool stuff!

Also, utilities is very powerful. I've used Insight and the test mode before, but never utilities. I had heard of it before but never downloaded it. It's seriously capable though.

I'm just getting started with this whole embedded/calculator programming thing but it's definitely very fun and I've got lots to learn, which I'm looking forward to!
thunker12 wrote:
And thinking about it too, even if it's little, ilram (or yram) is supposed to be much quicker to access. You don't have to necessarily display something. In other words, some simple calculations could be done in the background if space and peformance permit. Just some thoughts, but I think this has some potential for the community. Some fantastic work you've done here.


This is used in the Azur engine by Lephe to speed up rendering: https://git.planet-casio.com/Lephenixnoir/Azur

Since the whole screen doesn't fit it renders in segments and then copies each one to the screen, which is also how modern mobile GPUs work (https://en.wikipedia.org/wiki/Tiled_rendering)
  
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 2
» 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