kernel: make gint_setrestart() reset everything

This commit is contained in:
Lephe 2022-09-02 22:29:19 +02:00
parent 9924dc4684
commit 3e5c45c5ad
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
3 changed files with 37 additions and 26 deletions

View file

@ -59,14 +59,23 @@ void gint_world_sync(void);
call to getkey(), but can also be called manually. */ call to getkey(), but can also be called manually. */
void gint_osmenu(void); void gint_osmenu(void);
/* gint_osmenu_native(): Like gint_osmenu() without the world switch
This is a replacement for gint_osmenu() which can be used when the current
kernel is already the native OS kernel. */
void gint_osmenu_native(void);
/* gint_setrestart(): Set whether to restart the add-in after exiting /* gint_setrestart(): Set whether to restart the add-in after exiting
An add-in that reaches the end of its code exits. On the calculator, except An add-in that returns from its main() function automatically exits to the
using OS-dependent settings, it cannot be started again unless another OS' main menu. However, when this happens the OS does not allow the add-in
application is launched first. to be restarted unless another add-in is launched first. (This is because
the OS tries to *resume* the current add-in, which then proceeds to exit
again immediately.)
This setting allows the add-in to restart by calling gint_osmenu() instead This function enables a gint trick where after main() returns the add-in
of exiting. This can give a proper illusion of restarting if used correctly. will invoke the main menu with gint_osmenu() rather than exiting. If the
add-in is selected again, gint will jump back to the entry point, creating
the illusion that the add-in exited and was then restarted.
@restart 0 to exit, 1 to restart by using gint_osmenu() */ @restart 0 to exit, 1 to restart by using gint_osmenu() */
void gint_setrestart(int restart); void gint_setrestart(int restart);

View file

@ -23,7 +23,7 @@ static void __osmenu_handler(void)
__Timer_Deinstall(__osmenu_id); __Timer_Deinstall(__osmenu_id);
} }
static void __osmenu(void) void gint_osmenu_native(void)
{ {
__ClearKeyBuffer(); __ClearKeyBuffer();
@ -70,5 +70,5 @@ static void __osmenu(void)
/* gint_osmenu() - switch out of gint and call the calculator's main menu */ /* gint_osmenu() - switch out of gint and call the calculator's main menu */
void gint_osmenu(void) void gint_osmenu(void)
{ {
gint_world_switch(GINT_CALL(__osmenu)); gint_world_switch(GINT_CALL(gint_osmenu_native));
} }

View file

@ -94,11 +94,7 @@ static void callarray(void (**f)(void), void (**l)(void))
while(f < l) (*(*f++))(); while(f < l) (*(*f++))();
} }
/* start(): Where it all starts static int start2(int isappli, int optnum)
Returns a status code. Invoking main menu is better than returning, see
gint_setrestart() for that. */
GSECTION(".text.entry")
int start(int isappli, int optnum)
{ {
/* We are currently in a dynamic userspace mapping of an add-in run /* We are currently in a dynamic userspace mapping of an add-in run
from the storage memory. We are running in privileged mode with one from the storage memory. We are running in privileged mode with one
@ -179,8 +175,6 @@ int start(int isappli, int optnum)
hosted user application, which has its own constructors and hosted user application, which has its own constructors and
destructors to work with. */ destructors to work with. */
while(1)
{
/* Here, we use exit() to allow the standard library to do /* Here, we use exit() to allow the standard library to do
what it wants in exit() after main() finishes executing */ what it wants in exit() after main() finishes executing */
if(!setjmp(gint_exitbuf)) { if(!setjmp(gint_exitbuf)) {
@ -191,10 +185,6 @@ int start(int isappli, int optnum)
callarray(&bdtors, &edtors); callarray(&bdtors, &edtors);
} }
if(!gint_restart) break;
gint_osmenu();
}
/* Before leaving the application, we need to clean everything we /* Before leaving the application, we need to clean everything we
changed to hardware settings and peripheral modules. The OS is bound changed to hardware settings and peripheral modules. The OS is bound
to be confused (and hang, or crash, or any other kind of giving up) to be confused (and hang, or crash, or any other kind of giving up)
@ -206,6 +196,18 @@ int start(int isappli, int optnum)
return gint_exitcode; return gint_exitcode;
} }
GSECTION(".text.entry")
int start(int isappli, int optnum)
{
int rc;
while(1) {
rc = start2(isappli, optnum);
if(!gint_restart) break;
gint_osmenu_native();
}
return rc;
}
/* Standard _Exit, used by the fxlibc exit() to leave control */ /* Standard _Exit, used by the fxlibc exit() to leave control */
void _Exit(int rc) void _Exit(int rc)
{ {