mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
kernel: more options in System ERROR screen
* Add options to RESET, go to menu, or abort() * Define weak symbols for driver functions so that low-level debugging add-ins can be linked with minimal drivers (CPU/INTC/MMU)
This commit is contained in:
parent
42853103aa
commit
db50c9b192
7 changed files with 104 additions and 19 deletions
3
TODO
3
TODO
|
@ -12,11 +12,10 @@ Extensions on existing code:
|
|||
* kernel: better restore to userspace before panic (ensure BL=0 IMASK=0)
|
||||
* project: add license file
|
||||
* kernel: group linker script symbols in a single header file
|
||||
* core: try to leave add-in without reset in case of panic
|
||||
* core: use cmp/str for memchr()
|
||||
* r61524: brightness control and clean the file
|
||||
* core: review forgotten globals and MPU addresses not in <gint/mpu/*.h>
|
||||
* core: run destructors when a task-switch results in leaving the app
|
||||
* fs: support read-only files backed with GetBlockAddress() on fx-CG
|
||||
|
||||
Future directions:
|
||||
* Audio playback using TSWilliamson's libsnd method
|
||||
|
|
|
@ -2,16 +2,43 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/clock.h>
|
||||
#include <gint/mpu/dma.h>
|
||||
#include <gint/drivers/keydev.h>
|
||||
#include <gint/defs/attributes.h>
|
||||
#include <gint/hardware.h>
|
||||
#include <gint/gint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void __Reset(void);
|
||||
|
||||
#define dprint(x, y, ...) dprint(x, y, C_BLACK, __VA_ARGS__)
|
||||
#define dtext(x, y, str) dtext (x, y, C_BLACK, str)
|
||||
|
||||
/* Weak implementation of driver functions, which are used if the keyboard and
|
||||
display drivers are not linked in. This allows add-ins to not link in these
|
||||
drivers (which is useful for low-level debugging). */
|
||||
GWEAK void _WEAK_dupdate(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
GWEAK keydev_t *_WEAK_keydev_std(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
GWEAK bool _WEAK_keydev_keydown(GUNUSED keydev_t *d, GUNUSED int key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GWEAK key_event_t _WEAK_keydev_unqueue_event(GUNUSED keydev_t *d)
|
||||
{
|
||||
return (key_event_t){ .type = KEYEV_NONE };
|
||||
}
|
||||
|
||||
/* gint_panic_default(): Default panic handler */
|
||||
GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
||||
{
|
||||
uint32_t TEA, TRA;
|
||||
keydev_t *kd = _WEAK_keydev_std();
|
||||
|
||||
if(isSH3())
|
||||
{
|
||||
|
@ -31,9 +58,9 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
|||
if(isSH4()) __asm__("stc sgr, %0" : "=r"(SGR));
|
||||
|
||||
dfont(NULL);
|
||||
dclear(C_WHITE);
|
||||
|
||||
#ifdef FX9860G
|
||||
memset(gint_vram, 0, 1024);
|
||||
dtext(1, 0, "Exception! (SysERROR)");
|
||||
for(int i = 0; i < 32; i++) gint_vram[i] = ~gint_vram[i];
|
||||
|
||||
|
@ -55,16 +82,23 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
|||
if(name[0]) dtext(1, 9, name);
|
||||
else dprint(1, 9, "%03x", code);
|
||||
|
||||
dprint(1, 17, " PC :%08x", PC);
|
||||
dprint(1, 25, "TEA :%08x", TEA);
|
||||
dprint(1, 33, "TRA :%08x", TRA);
|
||||
if(isSH4()) dprint(1, 41, "SGR :%08x", SGR);
|
||||
dprint(1, 17, " PC:%08x TRA:%d", PC, TRA);
|
||||
dprint(1, 25, "TEA:%08x", TEA);
|
||||
|
||||
dtext(1, 49, "The add-in crashed.");
|
||||
dtext(1, 57, "Please reset the calc");
|
||||
dtext(1, 33, "The add-in crashed.");
|
||||
if(kd == NULL) {
|
||||
dtext(1, 41, "Please reset the calc");
|
||||
}
|
||||
else {
|
||||
dtext(1, 41, "[EXIT]:Quit add-in");
|
||||
dtext(1, 49, "[MENU]:Main menu");
|
||||
dtext(1, 57, "[F1]+[F6]: RESET calc");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FXCG50
|
||||
/* Don't require the DMA driver just for a clear */
|
||||
memset(gint_vram, 0xff, DWIDTH*DHEIGHT*2);
|
||||
dtext(6, 3, "An exception occured! (System ERROR)");
|
||||
|
||||
uint32_t *long_vram = (void *)gint_vram;
|
||||
|
@ -99,21 +133,27 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
|||
dprint(38, 75, "= %#x", TRA);
|
||||
dtext(281, 75, "(Trap number)");
|
||||
|
||||
dtext(6, 95, "An unrecoverable error occurred in the add-in.");
|
||||
dtext(6, 108, "Please press the RESET button to restart the");
|
||||
dtext(6, 121, "calculator.");
|
||||
dtext(6, 95, "The add-in crashed!");
|
||||
if(kd == NULL) {
|
||||
dtext(6, 108, "Please press the RESET button to restart the");
|
||||
dtext(6, 121, "calculator.");
|
||||
}
|
||||
else {
|
||||
dtext(6, 121, "[EXIT]: Exit the program with abort()");
|
||||
dtext(6, 134, "[MENU]: Leave to main menu");
|
||||
dtext(6, 147, "[F1]+[F6]: RESET the calculator");
|
||||
}
|
||||
|
||||
/* DMA address error handler */
|
||||
if(code == 0x1020)
|
||||
{
|
||||
#define DMA SH7305_DMA
|
||||
dprint(6, 141, "SAR0: %08x DAR0: %08x TCR0: %08x",
|
||||
dprint(6, 167, "SAR0: %08x DAR0: %08x TCR0: %08x",
|
||||
DMA.DMA0.SAR, DMA.DMA0.DAR, DMA.DMA0.TCR);
|
||||
dprint(6, 154, "CHCR0: %08x", DMA.DMA0.CHCR);
|
||||
dprint(6, 167, "SAR1: %08x DAR1: %08x TCR1: %08x",
|
||||
dprint(6, 180, "CHCR0: %08x", DMA.DMA0.CHCR);
|
||||
dprint(6, 193, "SAR1: %08x DAR1: %08x TCR1: %08x",
|
||||
DMA.DMA1.SAR, DMA.DMA1.DAR, DMA.DMA1.TCR);
|
||||
dprint(6, 180, "CHCR1: %08x", DMA.DMA1.CHCR);
|
||||
dprint(6, 193, "DMAOR: %04x", DMA.OR);
|
||||
dprint(6, 206, "CHCR1: %08x DMAOR:%04x", DMA.DMA1.CHCR, DMA.OR);
|
||||
#undef DMA
|
||||
}
|
||||
/* Illegal instruction handler */
|
||||
|
@ -125,8 +165,31 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
|||
}
|
||||
#endif
|
||||
|
||||
dupdate();
|
||||
while(1) sleep();
|
||||
_WEAK_dupdate();
|
||||
|
||||
/* Make sure relevant keys are released before taking in events; we don't
|
||||
want the user to RESET through this screen by holding a key */
|
||||
bool has_released = false;
|
||||
|
||||
while(1) {
|
||||
while(_WEAK_keydev_unqueue_event(kd).type != KEYEV_NONE) {}
|
||||
|
||||
bool exit = _WEAK_keydev_keydown(kd, KEY_EXIT);
|
||||
bool menu = _WEAK_keydev_keydown(kd, KEY_MENU);
|
||||
bool f1 = _WEAK_keydev_keydown(kd, KEY_F1);
|
||||
bool f6 = _WEAK_keydev_keydown(kd, KEY_F6);
|
||||
|
||||
if(has_released && exit)
|
||||
abort();
|
||||
if(has_released && menu)
|
||||
gint_osmenu();
|
||||
if(has_released && f1 && f6)
|
||||
__Reset();
|
||||
if(!exit && !menu && !f1 && !f6)
|
||||
has_released = true;
|
||||
|
||||
sleep();
|
||||
}
|
||||
}
|
||||
|
||||
/* Panic handler */
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
.global ___ConfigureStatusArea
|
||||
.global ___SetQuitHandler
|
||||
|
||||
/* Reset */
|
||||
.global ___Reset
|
||||
|
||||
#define syscall_(id, syscall_table) \
|
||||
mov.l syscall_table, r2 ;\
|
||||
mov.l 1f, r0 ;\
|
||||
|
@ -115,6 +118,11 @@ ___GetVRAMAddress:
|
|||
___SetQuitHandler:
|
||||
syscall(0x494)
|
||||
|
||||
/* Reset */
|
||||
|
||||
___Reset:
|
||||
syscall(0x236)
|
||||
|
||||
syscall_table:
|
||||
.long 0x80010070
|
||||
|
||||
|
@ -188,6 +196,11 @@ ___SetQuitHandler:
|
|||
___SpecialMatrixCodeProcessing:
|
||||
syscall(0x1e60)
|
||||
|
||||
/* Reset */
|
||||
|
||||
___Reset:
|
||||
syscall(0x1187)
|
||||
|
||||
syscall_table:
|
||||
.long 0x80020070
|
||||
|
||||
|
|
|
@ -205,6 +205,8 @@ key_event_t keydev_unqueue_event(keydev_t *d)
|
|||
|
||||
return ev;
|
||||
}
|
||||
__attribute__((alias("keydev_unqueue_event")))
|
||||
key_event_t _WEAK_keydev_unqueue_event(keydev_t *d);
|
||||
|
||||
/* keydev_keydown(): Check if a key is down according to generated events */
|
||||
bool keydev_keydown(keydev_t *d, int key)
|
||||
|
@ -214,6 +216,8 @@ bool keydev_keydown(keydev_t *d, int key)
|
|||
|
||||
return (d->state_queue[row] & col) != 0;
|
||||
}
|
||||
__attribute__((alias("keydev_keydown")))
|
||||
bool _WEAK_keydev_keydown(keydev_t *d, int key);
|
||||
|
||||
//---
|
||||
// Event transforms
|
||||
|
|
|
@ -33,6 +33,8 @@ keydev_t *keydev_std(void)
|
|||
{
|
||||
return &keysc_dev;
|
||||
}
|
||||
__attribute__((alias("keydev_std")))
|
||||
keydev_t *_WEAK_keydev_std(void);
|
||||
|
||||
/* keysc_scan(): Scand the keyboard */
|
||||
static void keysc_scan(uint8_t *scan)
|
||||
|
|
|
@ -18,3 +18,5 @@ void dupdate(void)
|
|||
/* Switch buffers if triple buffering is enabled */
|
||||
dvram_switch();
|
||||
}
|
||||
__attribute__((alias("dupdate")))
|
||||
void _WEAK_dupdate(void);
|
||||
|
|
|
@ -31,3 +31,5 @@ void dupdate(void)
|
|||
gint_call_t hook = dupdate_get_hook();
|
||||
if(hook.function) gint_call(hook);
|
||||
}
|
||||
__attribute__((alias("dupdate")))
|
||||
void _WEAK_dupdate(void);
|
||||
|
|
Loading…
Reference in a new issue