Support powering off #26

Closed
opened 2023-05-07 01:02:39 +02:00 by Heath123 · 2 comments

It's possible to make powering off work, both directly through a syscall and in the menu, by backing up and restoring ILRAM, e.g.:

void world_switch_handler(void) {
    // Back up XYRAM
    u8* xyram = (u8*) 0xe500e000;
    memcpy(xyram_backup, xyram, 16 * 1024);
    // Back up ILRAM
    u8* ilram = (u8*) 0xe5200000;
    memcpy(ilram_backup, ilram, 4 * 1024);

    PowerOff(1);

    // Restore XYRAM
    memcpy(xyram, xyram_backup, 16 * 1024);
    // Restore ILRAM
    memcpy(ilram, ilram_backup, 4 * 1024);

    return;
}

Here I also backed up XRAM and YRAM in case they are used. It might make sense to only back up the amount of on-chip memory that is used?

It would be nice if gint did this in its menu handler and if it has a power off function using the PowerOff syscall too (ideally supporting the displayLogo parameter)

It's possible to make powering off work, both directly through a syscall and in the menu, by backing up and restoring ILRAM, e.g.: ```c void world_switch_handler(void) { // Back up XYRAM u8* xyram = (u8*) 0xe500e000; memcpy(xyram_backup, xyram, 16 * 1024); // Back up ILRAM u8* ilram = (u8*) 0xe5200000; memcpy(ilram_backup, ilram, 4 * 1024); PowerOff(1); // Restore XYRAM memcpy(xyram, xyram_backup, 16 * 1024); // Restore ILRAM memcpy(ilram, ilram_backup, 4 * 1024); return; } ``` Here I also backed up XRAM and YRAM in case they are used. It might make sense to only back up the amount of on-chip memory that is used? It would be nice if gint did this in its menu handler and if it has a power off function using the PowerOff syscall too (ideally supporting the displayLogo parameter)
Owner

I'm finally taking this up. After pondering the options and finding that stack cannot be used for this (main menu uses a ton, causing a stack overflow even if we use ~3500 bytes on fx-CG), I have decided on the following solution.

The default behavior will be to reinitialize on-chip areas by reloading the initial data that was there at program startup. This will mostly reload code (gint has interrupt stuff in ILRAM which is why it used to crash btw) and reset globals. This mode is relevant because we don't normally store long-term data here and it uses no memory. In fact it's basically the only reasonable option on fx-9860G where 20 kB is more than half the heap, and even more so on the G-III.

The option will also be given for the application to provide a suitably large buffer (here 20 kB) to save all areas, similar to your initial version above. Saving only what's needed is a very good idea but you need to reserve 20 kB in case it's all needed, making it difficult to exploit.

Though as always there will be the "third" option (which here is going to be to provide a buffer of size zero) to disable any action on the memory and allow the application to do their preferred thing, e.g. saving only ILRAM, using malloc() as best-effort if the data is droppable (e.g. a cache), etc.

I'm finally taking this up. After pondering the options and finding that stack cannot be used for this (main menu uses a ton, causing a stack overflow even if we use ~3500 bytes on fx-CG), I have decided on the following solution. The default behavior will be to reinitialize on-chip areas by reloading the initial data that was there at program startup. This will mostly reload code (gint has interrupt stuff in ILRAM which is why it used to crash btw) and reset globals. This mode is relevant because we don't normally store long-term data here and it uses no memory. In fact it's basically the only reasonable option on fx-9860G where 20 kB is more than half the heap, and even more so on the G-III. The option will also be given for the application to provide a suitably large buffer (here 20 kB) to save all areas, similar to your initial version above. Saving only what's needed is a very good idea but you need to reserve 20 kB _in case_ it's all needed, making it difficult to exploit. Though as always there _will_ be the "third" option (which here is going to be to provide a buffer of size zero) to disable any action on the memory and allow the application to do their preferred thing, e.g. saving only ILRAM, using `malloc()` as best-effort if the data is droppable (e.g. a cache), etc.
Owner

I forgot to tag this issue but I also pushed fd5a70e21b which adds the gint_poweroff() call which is similar to gint_osmenu() and has the parameter to show the logo.

Both getkey() and JustUI's main loop will now call it when pressing Shift+AC/ON by default; my tests with it are very encouraging, i.e. everything just works with the single caveat that we have to redraw after coming back, but this is fine as a default because triple buffering is no longer enabled on fx-CG by default.

Note that not displaying the logo doesn't work well when powering off with AC/ON because then the calculator powers back on immediately unless you release AC/ON really quickly. I figure that's part of the reason why the logo exists in the first place.

I'll close this as the original request has been fulfilled but feel free to reopen if you find any bugs or further developments to be made.

I forgot to tag this issue but I also pushed https://gitea.planet-casio.com/Lephenixnoir/gint/commit/fd5a70e21b4ac0538ed7452388e9ea84109eafab which adds the `gint_poweroff()` call which is similar to `gint_osmenu()` and has the parameter to show the logo. Both `getkey()` and JustUI's main loop will now call it when pressing Shift+AC/ON by default; my tests with it are very encouraging, i.e. everything just works with the single caveat that we have to redraw after coming back, but this is fine as a default because triple buffering is no longer enabled on fx-CG by default. Note that not displaying the logo doesn't work well when powering off with AC/ON because then the calculator powers back on immediately unless you release AC/ON really quickly. I figure that's part of the reason why the logo exists in the first place. I'll close this as the original request has been fulfilled but feel free to reopen if you find any bugs or further developments to be made.
Sign in to join this conversation.
No Label
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: Lephenixnoir/gint#26
No description provided.