diff --git a/TODO b/TODO index e4f9be6..bb3dff0 100644 --- a/TODO +++ b/TODO @@ -13,7 +13,6 @@ Extensions on existing code: * core: review forgotten globals and MPU addresses not in * build: make the build system simpler (two targets are enough by default) * core: run destructors when a task-switch results in leaving the app -* core: invoke main menu instead of returning after main() ends * core rtc: use qdiv10 to massively improve division performance * topti: let the font specify letter and word spacing diff --git a/include/gint/gint.h b/include/gint/gint.h index 8046b6e..65907e0 100644 --- a/include/gint/gint.h +++ b/include/gint/gint.h @@ -43,6 +43,18 @@ void gint_switch(void (*function)(void)); call to getkey(), but can also be called manually. */ void gint_osmenu(void); +/* 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 + using OS-dependent settings, it cannot be started again unless another + application is launched first. + + This setting allows the add-in to restart by calling gint_osmenu() instead + of exiting. This can give a proper illusion of restarting if used correctly. + + @restart 0 to exit, 1 to restart by using gint_osmenu() */ +void gint_setrestart(int restart); + /* gint_inthandler(): Install interrupt handlers This function installs (copies) interrupt handlers in the VBR space of the diff --git a/src/core/start.c b/src/core/start.c index 19cc2e7..344d9d1 100644 --- a/src/core/start.c +++ b/src/core/start.c @@ -36,6 +36,15 @@ extern void (*bdtors)(void), (*edtors)(void); /* User-provided main() function */ int main(int isappli, int optnum); +/* Whether to restart main through the OS menu rather than returning */ +int gint_restart = 0; + +/* gint_setrestart(): Set whether to restart the add-in after exiting */ +void gint_setrestart(int restart) +{ + gint_restart = restart; +} + /* regcpy(): Copy a memory region using symbol information @l Source pointer (load address) @s Size of area (should be a multiple of 16) @@ -77,8 +86,9 @@ static void callarray(void (**f)(void), void (**l)(void)) while(f < l) (*(*f++))(); } -/* start() - this is where it all starts - Returns a status code. Invoking main menu is better than returning! */ +/* start(): Where it all starts + 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) { @@ -126,7 +136,15 @@ int start(int isappli, int optnum) destructors to work with. */ callarray(&bctors, &ectors); - int ret = main(isappli, optnum); + + int ret; + while(1) + { + ret = main(isappli, optnum); + if(!gint_restart) break; + gint_osmenu(); + } + callarray(&bdtors, &edtors); /* Before leaving the application, we need to clean everything we @@ -137,7 +155,5 @@ int start(int isappli, int optnum) /* Unload gint and give back control to the system. Driver settings will be restored while interrupts are disabled */ kquit(); - - /* TODO: Invoke main menu so that add-in can restart? */ return ret; }