gint: add power-off feature and shortcut in getkey()

This commit is contained in:
Lephe 2024-01-16 11:42:49 +01:00
parent 5655699cd8
commit fd5a70e21b
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
7 changed files with 64 additions and 19 deletions

View file

@ -80,6 +80,14 @@ void gint_osmenu_native(void);
@restart 0 to exit, 1 to restart by using gint_osmenu() */
void gint_setrestart(int restart);
/* gint_poweroff(): World switch and power off the calculator
Shows the CASIO logo / poweroff screen if show_logo is true. The program
will resume execution normally after powering on again. Don't call this
function with show_logo=false as a result of pressing AC/ON because the
calculator will restart immediately unless the user releases the AC/ON key
extremely quickly. */
void gint_poweroff(bool show_logo);
/* gint_set_onchip_save_mode(): Specify memory save policy for world switches
World switches can cause corruption in on-chip memory in two ways. First, if

View file

@ -258,11 +258,13 @@ enum {
GETKEY_MENU_DUPDATE = 0x0100,
/* After coming back from the main menu, send a KEYEV_OSMENU event */
GETKEY_MENU_EVENT = 0x0200,
/* Enable power off with SHIFT + AC/ON */
GETKEY_POWEROFF = 0x0400,
/* No modifiers */
GETKEY_NONE = 0x0000,
/* Default settings of getkey() */
GETKEY_DEFAULT = 0x01df,
GETKEY_DEFAULT = 0x05df,
};
/* getkey_feature_t: Custom feature function

View file

@ -8,6 +8,10 @@
/* gint_load_onchip_sections(): Initialize on-chip memory sections */
void gint_load_onchip_sections(void);
/* gint_copy_vram(): Copy gint's VRAM to the OS to avoid flickering during
certain world switches. */
void gint_copy_vram(void);
/* kinit(): Install and start gint */
void kinit(void);

View file

@ -2,6 +2,7 @@
#include <gint/display.h>
#include <gint/hardware.h>
#include <gint/keyboard.h>
#include "kernel.h"
#include <string.h>
@ -12,7 +13,6 @@ int __Timer_Deinstall(int id);
int __PutKeyCode(int row, int column, int keycode);
int __GetKeyWait(int *col,int *row,int type,int time,int menu,uint16_t *key);
void __ClearKeyBuffer(void); /* ? */
void *__GetVRAMAddress(void);
void __ConfigureStatusArea(int mode);
void __SetQuitHandler(void (*callback)(void));
@ -95,28 +95,12 @@ static os_menu_function_t *find_os_menu_function(void)
void gint_osmenu_native(void)
{
__ClearKeyBuffer();
#ifdef FX9860G
memcpy(__GetVRAMAddress(), gint_vram, 1024);
#endif
gint_copy_vram();
#ifdef FXCG50
/* Unfortunately ineffective (main menu probably reenables it)
__ConfigureStatusArea(3); */
/* TODO: Improve copied VRAM behavior in gint_osmenu() on fxcg50 */
uint16_t *vram1, *vram2;
dgetvram(&vram1, &vram2);
uint16_t *dst = __GetVRAMAddress();
uint16_t *src = (gint_vram == vram1) ? vram2 + 6 : vram1 + 6;
for(int y = 0; y < 216; y++, dst+=384, src+=396)
for(int x = 0; x < 384; x++)
{
dst[x] = src[x];
}
/* Try to use the internal function directly if we could figure out its
address by dynamically disassembling */
os_menu_function_t *fun = find_os_menu_function();

View file

@ -45,6 +45,7 @@
.global ___SetQuitHandler
/* Reset */
.global ___PowerOff
.global ___Reset
#define syscall_(id, syscall_table) \
@ -120,6 +121,8 @@ ___SetQuitHandler:
/* Reset */
___PowerOff:
syscall(0x3f4)
___Reset:
syscall(0x236)
@ -198,6 +201,8 @@ ___SpecialMatrixCodeProcessing:
/* Reset */
___PowerOff:
syscall(0x1839)
___Reset:
syscall(0x1187)

View file

@ -4,6 +4,7 @@
#include <gint/exc.h>
#include <gint/defs/call.h>
#include <gint/hardware.h>
#include <gint/display.h>
#include "kernel.h"
#include <stdlib.h>
@ -214,3 +215,34 @@ int gint_get_onchip_save_mode(void **ptr)
*ptr = onchip_save_buffer;
return onchip_save_mode;
}
void gint_copy_vram(void)
{
void *__GetVRAMAddress(void);
#ifdef FX9860G
memcpy(__GetVRAMAddress(), gint_vram, 1024);
#endif
#ifdef FXCG50
/* TODO: Improve copied VRAM behavior in gint_osmenu() on fxcg50 */
uint16_t *vram1, *vram2;
dgetvram(&vram1, &vram2);
uint16_t *dst = __GetVRAMAddress();
uint16_t *src = (gint_vram == vram1) ? vram2 + 6 : vram1 + 6;
for(int y = 0; y < 216; y++, dst+=384, src+=396)
for(int x = 0; x < 384; x++)
{
dst[x] = src[x];
}
#endif
}
void gint_poweroff(bool show_logo)
{
void __PowerOff(int show_logo);
gint_copy_vram();
gint_world_switch(GINT_CALL(__PowerOff, (int)show_logo));
}

View file

@ -75,6 +75,16 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
e.type = KEYEV_OSMENU;
}
/* Poweroff */
if((opt & GETKEY_POWEROFF) && e.type == KEYEV_DOWN &&
e.key == KEY_ACON && e.shift && !e.alpha)
{
gint_poweroff(true);
if(opt & GETKEY_MENU_DUPDATE)
dupdate();
continue;
}
if(e.type != KEYEV_NONE || e.type != KEYEV_UP)
{
/* Custom global features */