mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-06-05 02:15:10 +02:00
Compare commits
16 commits
2ef2c7de27
...
3ade0894d8
Author | SHA1 | Date | |
---|---|---|---|
|
3ade0894d8 | ||
|
377aa3745d | ||
|
191a5ebccf | ||
|
cdcf880006 | ||
|
ff17b8c22c | ||
|
e44e4fa14e | ||
|
87fff59527 | ||
|
232a4195d2 | ||
|
7ac9668dfd | ||
|
7a479e4f45 | ||
|
a62ba8a026 | ||
|
f953efdc82 | ||
|
1df334110e | ||
|
09ad6b0b31 | ||
|
a324ce792a | ||
|
45139d13b5 |
24 changed files with 408 additions and 135 deletions
|
@ -70,11 +70,11 @@ SECTIONS
|
|||
|
||||
_gint_exch_start = . ;
|
||||
KEEP(*(.gint.exch))
|
||||
_gint_exch_size = ABSOLUTE(. - _gint_exch_start);
|
||||
_gint_exch_end = . ;
|
||||
|
||||
_gint_tlbh_start = . ;
|
||||
KEEP(*(.gint.tlbh))
|
||||
_gint_tlbh_size = ABSOLUTE(. - _gint_tlbh_start);
|
||||
_gint_tlbh_end = . ;
|
||||
|
||||
*(.text .text.*)
|
||||
*(C P)
|
||||
|
|
|
@ -59,11 +59,11 @@ SECTIONS
|
|||
|
||||
_gint_exch_start = . ;
|
||||
KEEP(*(.gint.exch))
|
||||
_gint_exch_size = ABSOLUTE(. - _gint_exch_start);
|
||||
_gint_exch_end = . ;
|
||||
|
||||
_gint_tlbh_start = . ;
|
||||
KEEP(*(.gint.tlbh))
|
||||
_gint_tlbh_size = ABSOLUTE(. - _gint_tlbh_start);
|
||||
_gint_tlbh_end = . ;
|
||||
|
||||
*(.text .text.*)
|
||||
} > rom
|
||||
|
|
|
@ -68,12 +68,12 @@ SECTIONS
|
|||
. = ALIGN(0x10);
|
||||
_gint_exch_start = . ;
|
||||
*(.gint.exch)
|
||||
_gint_exch_size = ABSOLUTE(. - _gint_exch_start);
|
||||
_gint_exch_end = . ;
|
||||
|
||||
. = ALIGN(0x10);
|
||||
_gint_tlbh_start = . ;
|
||||
*(.gint.tlbh)
|
||||
_gint_tlbh_size = ABSOLUTE(. - _gint_tlbh_start);
|
||||
_gint_tlbh_end = . ;
|
||||
|
||||
*(.text .text.*)
|
||||
} > ram AT> bin
|
||||
|
|
|
@ -35,6 +35,7 @@ typedef struct
|
|||
int Bphi_div;
|
||||
int Iphi_div;
|
||||
int Pphi_div;
|
||||
int Sphi_div;
|
||||
|
||||
union {
|
||||
int CKIO_f;
|
||||
|
@ -44,6 +45,7 @@ typedef struct
|
|||
int Bphi_f;
|
||||
int Iphi_f;
|
||||
int Pphi_f;
|
||||
int Sphi_f;
|
||||
|
||||
} clock_frequency_t;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define GINT_DEFS_CALL
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <gint/defs/attributes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -184,6 +184,8 @@ typedef struct {
|
|||
|
||||
/* Candidate key for repeats (or 0 if no key is candidate yet) */
|
||||
int16_t rep_key;
|
||||
/* Matrix code for rep_key, if rep_key is not 0. */
|
||||
uint8_t rep_row, rep_col;
|
||||
/* Number of repeats already sent */
|
||||
int16_t rep_count;
|
||||
/* Time since key was first pressed (us) */
|
||||
|
|
|
@ -111,6 +111,8 @@ void hw_detect(void);
|
|||
#define HWCALC_FX9860G_SLIM 7
|
||||
/* fx-CP 400 */
|
||||
#define HWCALC_FXCP400 8
|
||||
/* fx-CG 100, successor to the CG-50 in the Prizm family. Also Graph Math+ */
|
||||
#define HWCALC_FXCG100 9
|
||||
|
||||
/*
|
||||
** Keyboard
|
||||
|
|
|
@ -114,16 +114,25 @@ extern "C" {
|
|||
* 0xffff is "just before" 0x0000, not "long after". */
|
||||
typedef struct
|
||||
{
|
||||
uint time :16; /* Time of event, unique over short periods */
|
||||
/* Time of event, unique over short periods */
|
||||
u16 time;
|
||||
|
||||
uint :2; /* Reserved for future use */
|
||||
|
||||
uint mod :1; /* Whether modifiers are used */
|
||||
uint shift :1; /* If mod=1, whether SHIFT was pressed */
|
||||
uint alpha :1; /* If mod=1, whether ALPHA was pressed */
|
||||
|
||||
uint type :3; /* Type of key event */
|
||||
uint key :8; /* Hit key */
|
||||
|
||||
/* Key that was pressed or released. */
|
||||
u8 key;
|
||||
|
||||
// The following attributes will be union'd with touch info on the CP.
|
||||
|
||||
/* Matrix code: physical location of the key being it. */
|
||||
u8 row, col;
|
||||
|
||||
/* Reserved for future use. */
|
||||
uint :16;
|
||||
|
||||
} GPACKED(4) key_event_t;
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Raw matrix codes */
|
||||
enum {
|
||||
KEY_F1 = 0x91,
|
||||
KEY_F2 = 0x92,
|
||||
|
@ -87,7 +86,23 @@ enum {
|
|||
KEY_EQUALS = 0xa5,
|
||||
KEY_CLEAR = KEY_EXIT,
|
||||
|
||||
/* Key aliases (handle with care =D) */
|
||||
/* Key codes for the CG-100 */
|
||||
KEY_ON = 0xa6,
|
||||
KEY_HOME = KEY_MENU,
|
||||
KEY_PREVTAB = 0xa7,
|
||||
KEY_NEXTTAB = 0xa8,
|
||||
KEY_PAGEUP = 0xa9,
|
||||
KEY_PAGEDOWN = 0xaa,
|
||||
KEY_SETTINGS = 0xab,
|
||||
KEY_BACK = KEY_EXIT,
|
||||
KEY_OK = 0xac,
|
||||
KEY_CATALOG = 0xad,
|
||||
KEY_TOOLS = KEY_OPTN,
|
||||
KEY_FORMAT = KEY_FD,
|
||||
KEY_SQRT = 0xae,
|
||||
KEY_EXPFUN = 0xaf,
|
||||
|
||||
/* Key aliases (deprecated--no more will be added) */
|
||||
KEY_X2 = KEY_SQUARE,
|
||||
KEY_CARET = KEY_POWER,
|
||||
KEY_SWITCH = KEY_FD,
|
||||
|
|
34
include/gint/mpu/keysc.h
Normal file
34
include/gint/mpu/keysc.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
//---
|
||||
// gint:mpu:keysc - Key Scan Controller
|
||||
//---
|
||||
|
||||
#ifndef GINT_MPU_KEYSC
|
||||
#define GINT_MPU_KEYSC
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <gint/defs/attributes.h>
|
||||
#include <gint/defs/types.h>
|
||||
|
||||
typedef volatile struct {
|
||||
uint16_t KIUDATA[6];
|
||||
uint16_t KIUCNTREG;
|
||||
uint16_t KIAUTOFIXREG;
|
||||
uint16_t KIUMODEREG;
|
||||
uint16_t KIUSTATEREG;
|
||||
uint16_t KIUINTREG;
|
||||
uint16_t KIUWSETREG;
|
||||
uint16_t KIUINTERVALREG;
|
||||
uint16_t KOUTPINSET;
|
||||
uint16_t KINPINSET;
|
||||
} GPACKED(4) sh7305_keysc_t;
|
||||
|
||||
#define SH7305_KEYSC (*(sh7305_keysc_t *)0xa44b0000)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINT_MPU_KEYSC */
|
|
@ -84,10 +84,12 @@ static void sh7305_probe(void)
|
|||
int divb = CPG.FRQCR.BFC;
|
||||
int divi = CPG.FRQCR.IFC;
|
||||
int divp = CPG.FRQCR.P1FC;
|
||||
int divs = CPG.FRQCR.SFC;
|
||||
|
||||
freq.Bphi_div = 1 << (divb + 1);
|
||||
freq.Iphi_div = 1 << (divi + 1);
|
||||
freq.Pphi_div = 1 << (divp + 1);
|
||||
freq.Sphi_div = 1 << (divs + 1);
|
||||
|
||||
/* Deduce the input frequency of divider 1 */
|
||||
int base = 32768;
|
||||
|
@ -99,6 +101,7 @@ static void sh7305_probe(void)
|
|||
freq.Bphi_f = base >> (divb + 1);
|
||||
freq.Iphi_f = base >> (divi + 1);
|
||||
freq.Pphi_f = base >> (divp + 1);
|
||||
freq.Sphi_f = base >> (divs + 1);
|
||||
}
|
||||
|
||||
#undef CPG
|
||||
|
|
|
@ -433,6 +433,66 @@ static struct cpg_overclock_setting const settings_fxcg50[5] = {
|
|||
.CS5aWCR = 0x000203C1 },
|
||||
};
|
||||
|
||||
// TODO: These structures are big and many settings overlap. Make it smaller.
|
||||
// This is fxcg50[0,1,2,3,3].
|
||||
static struct cpg_overclock_setting const settings_fxcg100[5] = {
|
||||
/* CLOCK_SPEED_F1 */
|
||||
{ .FLLFRQ = 0x00004000 + 900,
|
||||
.FRQCR = 0x0F011112,
|
||||
.CS0BCR = 0x36DA0400,
|
||||
.CS2BCR = 0x36DA3400,
|
||||
.CS3BCR = 0x36DB4400,
|
||||
.CS5aBCR = 0x17DF0400,
|
||||
.CS0WCR = 0x000003C0,
|
||||
.CS2WCR = 0x000003C0,
|
||||
.CS3WCR = 0x000024D1,
|
||||
.CS5aWCR = 0x000203C1 },
|
||||
/* CLOCK_SPEED_F2 */
|
||||
{ .FLLFRQ = 0x00004000 + 900,
|
||||
.FRQCR = (SH4_PLL_16x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_8,
|
||||
.CS0BCR = 0x24920400,
|
||||
.CS2BCR = 0x24923400,
|
||||
.CS3BCR = 0x24924400,
|
||||
.CS5aBCR = 0x17DF0400,
|
||||
.CS0WCR = 0x00000340,
|
||||
.CS2WCR = 0x000003C0,
|
||||
.CS3WCR = 0x000024D1,
|
||||
.CS5aWCR = 0x000203C1 },
|
||||
/* CLOCK_SPEED_F3 */
|
||||
{ .FLLFRQ = 0x00004000 + 900,
|
||||
.FRQCR = (SH4_PLL_26x<<24)+(SH4_DIV_4<<20)+(SH4_DIV_8<<12)+(SH4_DIV_8<<8)+SH4_DIV_8,
|
||||
.CS0BCR = 0x24920400,
|
||||
.CS2BCR = 0x24923400,
|
||||
.CS3BCR = 0x24924400,
|
||||
.CS5aBCR = 0x17DF0400,
|
||||
.CS0WCR = 0x00000240,
|
||||
.CS2WCR = 0x000003C0,
|
||||
.CS3WCR = 0x000024D1,
|
||||
.CS5aWCR = 0x000203C1 },
|
||||
/* CLOCK_SPEED_F4 */
|
||||
{ .FLLFRQ = 0x00004000 + 900,
|
||||
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_2<<20)+(SH4_DIV_4<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
|
||||
.CS0BCR = 0x24920400,
|
||||
.CS2BCR = 0x24923400,
|
||||
.CS3BCR = 0x24924400,
|
||||
.CS5aBCR = 0x17DF0400,
|
||||
.CS0WCR = 0x000002C0,
|
||||
.CS2WCR = 0x000003C0,
|
||||
.CS3WCR = 0x000024D1,
|
||||
.CS5aWCR = 0x000203C1 },
|
||||
/* CLOCK_SPEED_F5 is made identical to CLOCK_SPEED_F4 because clearly the
|
||||
Graph Math+ cannot handle the higher bus speed. */
|
||||
{ .FLLFRQ = 0x00004000 + 900,
|
||||
.FRQCR = (SH4_PLL_32x<<24)+(SH4_DIV_2<<20)+(SH4_DIV_4<<12)+(SH4_DIV_8<<8)+SH4_DIV_16,
|
||||
.CS0BCR = 0x24920400,
|
||||
.CS2BCR = 0x24923400,
|
||||
.CS3BCR = 0x24924400,
|
||||
.CS5aBCR = 0x17DF0400,
|
||||
.CS0WCR = 0x000002C0,
|
||||
.CS2WCR = 0x000003C0,
|
||||
.CS3WCR = 0x000024D1,
|
||||
.CS5aWCR = 0x000203C1 },
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct cpg_overclock_setting const *get_settings(void)
|
||||
|
@ -451,6 +511,8 @@ static struct cpg_overclock_setting const *get_settings(void)
|
|||
return settings_prizm;
|
||||
if(gint[HWCALC] == HWCALC_FXCG50)
|
||||
return settings_fxcg50;
|
||||
if(gint[HWCALC] == HWCALC_FXCG100)
|
||||
return settings_fxcg100;
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -80,6 +80,7 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
|||
if(code == 0x1060) name = "Memory init failed";
|
||||
if(code == 0x1080) name = "Stack overflow";
|
||||
if(code == 0x10a0) name = "UBC in bank 1 code";
|
||||
// if(code == 0x10c0) name = "Missing syscall"; // not on FX
|
||||
|
||||
if(name[0]) dtext(1, 9, name);
|
||||
else dprint(1, 9, "%03x", code);
|
||||
|
@ -121,6 +122,7 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
|
|||
if(code == 0x1060) name = "Memory initialization failed (heap)";
|
||||
if(code == 0x1080) name = "Stack overflow during world switch";
|
||||
if(code == 0x10a0) name = "UBC break in register bank 1 code";
|
||||
if(code == 0x10c0) name = "Missing syscall for this OS version";
|
||||
|
||||
dprint(6, 25, "%03x %s", code, name);
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <gint/config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "kernel.h"
|
||||
|
||||
/* Holds information about the current platform */
|
||||
GBSS uint32_t gint[HW_KEYS];
|
||||
|
@ -126,10 +127,28 @@ void hw_detect(void)
|
|||
gint[HWCPUVR] = PVR;
|
||||
gint[HWCPUPR] = PRR;
|
||||
|
||||
/* Tell Prizms apart from fx-CG 50 by checking the stack address*/
|
||||
uint32_t stack;
|
||||
__asm__("mov r15, %0" : "=r"(stack));
|
||||
gint[HWCALC] = (stack < 0x8c000000) ? HWCALC_PRIZM : HWCALC_FXCG50;
|
||||
char const *version = (void *)0x80020020;
|
||||
char const *osdate = (void *)0x80b5ffe0;
|
||||
|
||||
/* Tell Prizms apart from fx-CG 50 by checking the stack address*/
|
||||
if(stack < 0x8c000000) {
|
||||
gint[HWCALC] = HWCALC_PRIZM;
|
||||
}
|
||||
/* Tell Math+/fx-CG 100 apart from CG-50 by checking OS version + date.
|
||||
CG-50 OS versions use OS 3. Math+, for some reason, rewinds back to OS 1
|
||||
and got updated to OS 2 in late 2024. We decide that we are on a CG-50 OS
|
||||
if the version is 3 and the date is 201x-2024. */
|
||||
else {
|
||||
/* All known CG-50 versions have date at this address due to the footer
|
||||
location. WARNING: not a future-proof address! */
|
||||
char d0 = osdate[0], d1 = osdate[1], d2 = osdate[2], d3 = osdate[3];
|
||||
bool cg50 = version[1] == '3' && d0 == '2' && d1 == '0' &&
|
||||
(d2 == '1' || (d2 == '2' && d3 <= '4'));
|
||||
gint[HWCALC] = cg50 ? HWCALC_FXCG50 : HWCALC_FXCG100;
|
||||
}
|
||||
|
||||
gint[HWFS] = HWFS_FUGUE;
|
||||
|
||||
/* Tell the fx-CG emulator apart using the product ID */
|
||||
|
|
|
@ -40,6 +40,18 @@ void *gint_stack_top = NULL;
|
|||
/* kinit(): Install and start gint */
|
||||
void kinit(void)
|
||||
{
|
||||
/* Figure out which CASIOWIN API to use based on the OS type. */
|
||||
#if GINT_OS_CG
|
||||
char *version = (void *)0x80020020;
|
||||
if(!memcmp(version, "01.00", 5))
|
||||
gint_set_CASIOWIN_API(1);
|
||||
else if(gint[HWCALC] == HWCALC_FXCG100 && !memcmp(version, "02.00", 5))
|
||||
gint_set_CASIOWIN_API(2);
|
||||
else
|
||||
gint_set_CASIOWIN_API(0);
|
||||
#endif
|
||||
|
||||
|
||||
#if GINT_HW_FX
|
||||
/* On fx-9860G, VBR is loaded at the end of the user RAM. On SH4, the
|
||||
end of the user RAM hosts the stack, for which we leave 12 kB
|
||||
|
@ -76,9 +88,15 @@ void kinit(void)
|
|||
#endif
|
||||
|
||||
/* Event handler entry points */
|
||||
extern uint32_t gint_exch_start;
|
||||
extern uint32_t gint_exch_end;
|
||||
extern uint32_t gint_tlbh_start;
|
||||
extern uint32_t gint_tlbh_end;
|
||||
void *inth_entry = isSH3() ? gint_inth_7705 : gint_inth_7305;
|
||||
uint32_t exch_size = (uint32_t)&gint_exch_size;
|
||||
uint32_t tlbh_size = (uint32_t)&gint_tlbh_size;
|
||||
uint32_t exch_size = \
|
||||
(uint32_t)&gint_exch_end - (uint32_t)&gint_exch_start;
|
||||
uint32_t tlbh_size = \
|
||||
(uint32_t)&gint_tlbh_end - (uint32_t)&gint_tlbh_start;
|
||||
|
||||
/* Load the event handler entry points into memory */
|
||||
memcpy((void *)VBR + 0x100, gint_exch, exch_size);
|
||||
|
@ -102,16 +120,18 @@ void kinit(void)
|
|||
|
||||
/* Create an arena in the OS stack as well, for VRAM and more data */
|
||||
#if GINT_HW_CG && !defined(GINT_NO_OS_STACK)
|
||||
static kmalloc_arena_t os_stack = { 0 };
|
||||
os_stack.name = "_ostk";
|
||||
os_stack.is_default = true;
|
||||
if(gint[HWCALC] == HWCALC_PRIZM || gint[HWCALC] == HWCALC_FXCG_MANAGER)
|
||||
os_stack.start = (void *)0x880f0000;
|
||||
else
|
||||
os_stack.start = (void *)0x8c0f0000;
|
||||
os_stack.end = os_stack.start + (350 * 1024);
|
||||
kmalloc_init_arena(&os_stack, true);
|
||||
kmalloc_add_arena(&os_stack);
|
||||
if(gint[HWCALC] != HWCALC_FXCG100) {
|
||||
static kmalloc_arena_t os_stack = { 0 };
|
||||
os_stack.name = "_ostk";
|
||||
os_stack.is_default = true;
|
||||
if(gint[HWCALC] == HWCALC_PRIZM || gint[HWCALC] == HWCALC_FXCG_MANAGER)
|
||||
os_stack.start = (void *)0x880f0000;
|
||||
else
|
||||
os_stack.start = (void *)0x8c0f0000;
|
||||
os_stack.end = os_stack.start + (350 * 1024);
|
||||
kmalloc_init_arena(&os_stack, true);
|
||||
kmalloc_add_arena(&os_stack);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate world buffers for the OS and for gint */
|
||||
|
|
|
@ -18,4 +18,7 @@ void kinit(void);
|
|||
/* kquit(): Quit gint and give back control to the system */
|
||||
void kquit(void);
|
||||
|
||||
/* Select the CASIOWIN API for syscalls. */
|
||||
void gint_set_CASIOWIN_API(int API);
|
||||
|
||||
#endif /* GINT_CORE_KERNEL */
|
||||
|
|
|
@ -13,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 __ConfigureStatusArea(int mode);
|
||||
void __SetQuitHandler(void (*callback)(void));
|
||||
|
||||
#if !GINT_OS_CP
|
||||
|
@ -96,15 +95,17 @@ static os_menu_function_t *find_os_menu_function(void)
|
|||
|
||||
void gint_osmenu_native(void)
|
||||
{
|
||||
#if GINT_OS_CG
|
||||
if(gint[HWCALC] == HWCALC_FXCG100)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// TODO: OS menu on fx-CP
|
||||
#if !GINT_OS_CP
|
||||
__ClearKeyBuffer();
|
||||
gint_copy_vram();
|
||||
|
||||
#if GINT_OS_CG
|
||||
/* Unfortunately ineffective (main menu probably reenables it)
|
||||
__ConfigureStatusArea(3); */
|
||||
|
||||
/* 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();
|
||||
|
@ -122,11 +123,6 @@ void gint_osmenu_native(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Mysteriously crashes when coming back; might be useful another time
|
||||
instead of GetKeyWait()
|
||||
int C=0x04, R=0x09;
|
||||
__SpecialMatrixCodeProcessing(&C, &R); */
|
||||
|
||||
__osmenu_id = __Timer_Install(0, __osmenu_handler, 0 /* ms */);
|
||||
if(__osmenu_id <= 0) return;
|
||||
__Timer_Start(__osmenu_id);
|
||||
|
|
|
@ -42,8 +42,9 @@ int8_t gint_restart = 0;
|
|||
/* gint_setrestart(): Set whether to restart the add-in after exiting */
|
||||
void gint_setrestart(int restart)
|
||||
{
|
||||
/* There is now return-to-menu so no restart on CP */
|
||||
gint_restart = restart && !GINT_OS_CP;
|
||||
/* No restart on the machines for which there is no return-to-menu, i.e. on
|
||||
fx-CP and on the fx-CG 100. */
|
||||
gint_restart = restart && !GINT_OS_CP && gint[HWCALC] != HWCALC_FXCG100;
|
||||
}
|
||||
|
||||
/* Return value of main() */
|
||||
|
|
|
@ -144,82 +144,128 @@ syscall_table:
|
|||
#endif /* GINT_OS_FX */
|
||||
|
||||
#if GINT_OS_CG
|
||||
#define CASIOWIN_API_VERSIONS 3
|
||||
.global _gint_set_CASIOWIN_API
|
||||
.global _gint_get_CASIOWIN_API
|
||||
|
||||
/* Dynamic allocation */
|
||||
/* System for dynamically selecting between the syscall and fixed version of
|
||||
each function based on the OS version.
|
||||
@r0: Internal function ID (from table below) */
|
||||
_CASIOWIN_call:
|
||||
mov #CASIOWIN_API_VERSIONS, r1
|
||||
mulu.w r0, r1
|
||||
mov.l 3f, r0
|
||||
mov.l @r0, r2
|
||||
sts macl, r1
|
||||
add r2, r1
|
||||
shll2 r1
|
||||
|
||||
___malloc:
|
||||
syscall(0x1f44)
|
||||
___free:
|
||||
syscall(0x1f42)
|
||||
___realloc:
|
||||
syscall(0x1f46)
|
||||
/* API version 0 is the normal syscall table */
|
||||
tst r2, r2
|
||||
mova .CASIOWIN_TABLE, r0
|
||||
bt.s .syscall
|
||||
mov.l @(r0, r1), r0
|
||||
|
||||
/* BFile driver */
|
||||
/* Other API versions are the direct calls */
|
||||
tst r0, r0
|
||||
bt .missingCall
|
||||
|
||||
_BFile_Remove:
|
||||
syscall(0x1db4)
|
||||
_BFile_Rename:
|
||||
syscall(0x1db3)
|
||||
_BFile_Create:
|
||||
syscall(0x1dae)
|
||||
_BFile_Open:
|
||||
mov #0, r6
|
||||
syscall(0x1da3)
|
||||
_BFile_Close:
|
||||
syscall(0x1da4)
|
||||
_BFile_Size:
|
||||
syscall(0x1da6)
|
||||
_BFile_Seek:
|
||||
syscall(0x1da9)
|
||||
_BFile_GetPos:
|
||||
syscall(0x1dab)
|
||||
_BFile_Write:
|
||||
syscall(0x1daf)
|
||||
_BFile_Read:
|
||||
syscall(0x1dac)
|
||||
_BFile_FindFirst:
|
||||
syscall(0x1db6)
|
||||
_BFile_FindNext:
|
||||
syscall(0x1db8)
|
||||
_BFile_FindClose:
|
||||
syscall(0x1dba)
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
/* Return to menu */
|
||||
.missingCall:
|
||||
mov.l .gint_panic, r0
|
||||
mov.w 2f, r4
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
___Timer_Install:
|
||||
syscall(0x8d9)
|
||||
___Timer_Start:
|
||||
syscall(0x8db)
|
||||
___Timer_Stop:
|
||||
syscall(0x8dc)
|
||||
___Timer_Deinstall:
|
||||
syscall(0x8da)
|
||||
___PutKeyCode:
|
||||
syscall(0x12c6)
|
||||
___GetKeyWait:
|
||||
syscall(0x12bf)
|
||||
___ClearKeyBuffer:
|
||||
syscall(0x12c7)
|
||||
___GetVRAMAddress:
|
||||
syscall(0x1e6)
|
||||
___ConfigureStatusArea:
|
||||
syscall(0x2b7)
|
||||
___SetQuitHandler:
|
||||
syscall(0x1e6e)
|
||||
.syscall:
|
||||
mov.l 1f, r1
|
||||
jmp @r1
|
||||
nop
|
||||
|
||||
.global ___SpecialMatrixCodeProcessing
|
||||
___SpecialMatrixCodeProcessing:
|
||||
syscall(0x1e60)
|
||||
2: .word 0x10c0
|
||||
.balign 4
|
||||
1: .long 0x80020070
|
||||
.gint_panic:
|
||||
.long _gint_panic
|
||||
|
||||
/* Reset */
|
||||
_gint_set_CASIOWIN_API:
|
||||
mov.l 3f, r0
|
||||
rts
|
||||
mov.l r4, @r0
|
||||
|
||||
___PowerOff:
|
||||
syscall(0x1839)
|
||||
___Reset:
|
||||
syscall(0x1187)
|
||||
_gint_get_CASIOWIN_API:
|
||||
mov.l 3f, r0
|
||||
rts
|
||||
mov.l @r0, r0
|
||||
|
||||
syscall_table:
|
||||
.long 0x80020070
|
||||
.balign 4
|
||||
3: .long .CASIOWIN_API
|
||||
|
||||
.CASIOWIN_TABLE:
|
||||
.long 0x1f44, 0x8025e0fc, 0x80366708 /* malloc */
|
||||
.long 0x1f42, 0x8025dec8, 0x803664d4 /* free */
|
||||
.long 0x1f46, 0x8025ec3c, 0x803672c8 /* realloc */
|
||||
.long 0x1db4, 0x802404d2, 0x80334212 /* BFile_Remove */
|
||||
.long 0x1db3, 0x80240482, 0x803341c2 /* BFile_Rename */
|
||||
.long 0x1dae, 0x802401b0, 0x80333ef0 /* BFile_Create */
|
||||
.long 0x1da3, 0x8023fb90, 0x803338d0 /* BFile_Open */
|
||||
.long 0x1da4, 0x8023fd0e, 0x80333a4e /* BFile_Close */
|
||||
.long 0x1da6, 0x8023fdc4, 0x80333b04 /* BFile_Size */
|
||||
.long 0x1da9, 0x8023ff2c, 0x80333c6c /* BFile_Seek */
|
||||
.long 0x1dab, 0x8024003c, 0x80333d7c /* BFile_GetPos */
|
||||
.long 0x1daf, 0x8024025e, 0x80333f9e /* BFile_Write */
|
||||
.long 0x1dac, 0x80240082, 0x80333dc2 /* BFile_Read */
|
||||
.long 0x1db6, 0x80240888, 0x803345c8 /* BFile_FindFirst */
|
||||
.long 0x1db8, 0x80240b06, 0x80334846 /* BFile_FindNext */
|
||||
.long 0x1dba, 0x80240c10, 0x80334950 /* BFile_FindClose */
|
||||
.long 0x08d9, 0x800b130c, 0x8010de28 /* Timer_Install */
|
||||
.long 0x08db, 0x800b1456, 0x8010df72 /* Timer_Start */
|
||||
.long 0x08dc, 0x800b14b2, 0x8010dfce /* Timer_Stop */
|
||||
.long 0x08da, 0x800b13d4, 0x8010def0 /* Timer_Deinstall */
|
||||
.long 0x12c6, 0, 0 /* PutKeyCode */
|
||||
.long 0x12bf, 0x8017be56, 0x802382fe /* GetKeyWait */
|
||||
.long 0x12c7, 0, 0 /* ClearKeyBuffer */
|
||||
.long 0x01e6, 0x8004579a, 0x8007569e /* GetVRAMAddress */
|
||||
.long 0x1e6e, 0, 0 /* SetQuitHandler */
|
||||
.long 0x1839, 0, 0 /* PowerOff */
|
||||
.long 0x1187, 0, 0 /* Reset */
|
||||
|
||||
#define casiowin_call(id) bra _CASIOWIN_call; mov id, r0
|
||||
|
||||
___malloc: casiowin_call(#0)
|
||||
___free: casiowin_call(#1)
|
||||
___realloc: casiowin_call(#2)
|
||||
_BFile_Remove: casiowin_call(#3)
|
||||
_BFile_Rename: casiowin_call(#4)
|
||||
_BFile_Create: casiowin_call(#5)
|
||||
_BFile_Open: mov #0, r6; casiowin_call(#6)
|
||||
_BFile_Close: casiowin_call(#7)
|
||||
_BFile_Size: casiowin_call(#8)
|
||||
_BFile_Seek: casiowin_call(#9)
|
||||
_BFile_GetPos: casiowin_call(#10)
|
||||
_BFile_Write: casiowin_call(#11)
|
||||
_BFile_Read: casiowin_call(#12)
|
||||
_BFile_FindFirst: casiowin_call(#13)
|
||||
_BFile_FindNext: casiowin_call(#14)
|
||||
_BFile_FindClose: casiowin_call(#15)
|
||||
___Timer_Install: casiowin_call(#16)
|
||||
___Timer_Start: casiowin_call(#17)
|
||||
___Timer_Stop: casiowin_call(#18)
|
||||
___Timer_Deinstall: casiowin_call(#19)
|
||||
___PutKeyCode: casiowin_call(#20)
|
||||
___GetKeyWait: casiowin_call(#21)
|
||||
___ClearKeyBuffer: casiowin_call(#22)
|
||||
___GetVRAMAddress: casiowin_call(#23)
|
||||
___ConfigureStatusArea: casiowin_call(#24)
|
||||
___SetQuitHandler: casiowin_call(#25)
|
||||
___PowerOff: casiowin_call(#26)
|
||||
___Reset: casiowin_call(#27)
|
||||
|
||||
.data
|
||||
.CASIOWIN_API:
|
||||
.long 0
|
||||
|
||||
#endif /* GINT_OS_CG */
|
||||
|
||||
|
|
|
@ -11,8 +11,4 @@ void gint_tlbh(void);
|
|||
void gint_inth_7705(void);
|
||||
void gint_inth_7305(void);
|
||||
|
||||
/* Size of exception and TLB handlers */
|
||||
extern char gint_exch_size;
|
||||
extern char gint_tlbh_size;
|
||||
|
||||
#endif /* GINT_CORE_VBR */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <gint/drivers/keydev.h>
|
||||
#include <gint/defs/types.h>
|
||||
#include <gint/defs/util.h>
|
||||
#include <gint/hardware.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -45,14 +46,49 @@ static void keycode_to_keymatrix(int keycode, int *row, int *col)
|
|||
*col = 0;
|
||||
}
|
||||
#else
|
||||
static GINLINE int keymatrix_to_keycode(int row, int col)
|
||||
static uint8_t const CG100_keymap[] = {
|
||||
KEY_ON, KEY_HOME, KEY_PREVTAB, KEY_UP, KEY_NEXTTAB, KEY_PAGEUP,
|
||||
KEY_SETTINGS, KEY_BACK, KEY_LEFT, KEY_OK, KEY_RIGHT, KEY_PAGEDOWN,
|
||||
KEY_SHIFT, KEY_ALPHA, KEY_VARS, KEY_DOWN, KEY_CATALOG, KEY_TOOLS,
|
||||
KEY_XOT, KEY_FRAC, KEY_SQRT, KEY_POWER, KEY_SQUARE, KEY_EXPFUN,
|
||||
KEY_COMMA, KEY_SIN, KEY_COS, KEY_TAN, KEY_LEFTP, KEY_RIGHTP,
|
||||
};
|
||||
static int keymatrix_to_keycode(int row, int col)
|
||||
{
|
||||
if(gint[HWCALC] == HWCALC_FXCG100) {
|
||||
if(row >= 7 && row <= 9)
|
||||
return CG100_keymap[6 * (9-row) + (6-col)];
|
||||
if(row == 1 && col == 3)
|
||||
return KEY_FORMAT;
|
||||
}
|
||||
return (row << 4) + (7 - col);
|
||||
}
|
||||
static GINLINE void keycode_to_keymatrix(int keycode, int *row, int *col)
|
||||
static void keycode_to_keymatrix(int keycode, int *row, int *col)
|
||||
{
|
||||
if(gint[HWCALC] == HWCALC_FXCG100) {
|
||||
if(keycode == KEY_FORMAT) {
|
||||
*row = 1;
|
||||
*col = 3;
|
||||
return;
|
||||
}
|
||||
for(int i = 0; i < (int)sizeof(CG100_keymap); i++) {
|
||||
if(CG100_keymap[i] == keycode) {
|
||||
*row = 9 - i / 6;
|
||||
*col = 6 - (i % 6);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*row = keycode >> 4;
|
||||
*col = 7 - (keycode & 7);
|
||||
|
||||
if(gint[HWCALC] == HWCALC_FXCG100 &&
|
||||
(*row > 4 || (*row == 1 && *col == 3))) {
|
||||
// key that doesn't exist
|
||||
*row = 0;
|
||||
*col = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -125,6 +161,8 @@ void keydev_process_state(keydev_t *d, uint8_t scan[12])
|
|||
|
||||
for(int mask = 0x80, col = 7; mask; mask >>= 1, col--)
|
||||
{
|
||||
ev.row = row;
|
||||
ev.col = col;
|
||||
ev.key = keymatrix_to_keycode(row, col);
|
||||
/* Update state only if the push succeeds */
|
||||
if((diff & mask) && keydev_queue_push(d, ev))
|
||||
|
@ -173,6 +211,8 @@ key_event_t keydev_repeat_event(keydev_t *d)
|
|||
|
||||
ev.type = KEYEV_HOLD;
|
||||
ev.key = d->rep_key;
|
||||
ev.row = d->rep_row;
|
||||
ev.col = d->rep_col;
|
||||
return ev;
|
||||
}
|
||||
|
||||
|
@ -188,11 +228,11 @@ void keydev_tick(keydev_t *d, uint us)
|
|||
/* Disable repeat if the repeating key was released */
|
||||
if(d->rep_key != 0)
|
||||
{
|
||||
int row, col;
|
||||
keycode_to_keymatrix(d->rep_key, &row, &col);
|
||||
if(!(d->state_now[row] & (1 << col)))
|
||||
if(!(d->state_now[d->rep_row] & (1 << d->rep_col)))
|
||||
{
|
||||
d->rep_key = 0;
|
||||
d->rep_row = 0;
|
||||
d->rep_col = 0;
|
||||
d->rep_count = -1;
|
||||
d->rep_time = -1;
|
||||
d->rep_delay = -1;
|
||||
|
@ -231,19 +271,27 @@ key_event_t keydev_unqueue_event(keydev_t *d)
|
|||
if(!queue_poll(d, &ev))
|
||||
return ev;
|
||||
|
||||
/* Compatibility combinations can transform the .key attribute */
|
||||
#if GINT_HW_CG
|
||||
if(gint[HWCALC] == HWCALC_FXCG100) {
|
||||
if(keydev_keydown(d, KEY_CATALOG) && ev.row == 6)
|
||||
ev.key = KEY_F1 + (6 - ev.col);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Update the event state accordingly */
|
||||
int row, col;
|
||||
keycode_to_keymatrix(ev.key, &row, &col);
|
||||
int mask = 1 << col;
|
||||
int mask = 1 << ev.col;
|
||||
|
||||
if(ev.type == KEYEV_DOWN)
|
||||
{
|
||||
d->state_queue[row] |= mask;
|
||||
d->state_flips[row] ^= mask;
|
||||
d->state_queue[ev.row] |= mask;
|
||||
d->state_flips[ev.row] ^= mask;
|
||||
/* Mark this key as the currently repeating one */
|
||||
if(d->rep_key == 0 && can_repeat(d, ev.key))
|
||||
{
|
||||
d->rep_key = ev.key;
|
||||
d->rep_row = ev.row;
|
||||
d->rep_col = ev.col;
|
||||
d->rep_count = -1;
|
||||
d->rep_time = 0;
|
||||
d->rep_delay = 0;
|
||||
|
@ -251,8 +299,8 @@ key_event_t keydev_unqueue_event(keydev_t *d)
|
|||
}
|
||||
else if(ev.type == KEYEV_UP)
|
||||
{
|
||||
d->state_queue[row] &= ~mask;
|
||||
d->state_flips[row] ^= mask;
|
||||
d->state_queue[ev.row] &= ~mask;
|
||||
d->state_flips[ev.row] ^= mask;
|
||||
}
|
||||
|
||||
return ev;
|
||||
|
|
|
@ -97,16 +97,15 @@ bool dvram_init(void)
|
|||
{
|
||||
int const MARGIN = 32;
|
||||
|
||||
char const *arena = NULL;
|
||||
if(kmalloc_get_arena("_ostk"))
|
||||
arena = "_ostk";
|
||||
|
||||
/* Leave MARGIN bytes on each side of the region; this enables some
|
||||
important optimizations in the image renderer. We also add another
|
||||
32 bytes so we can manually 32-align the region */
|
||||
uint32_t region = (uint32_t)kmalloc(DWIDTH*DHEIGHT*2 + MARGIN*2 + 32,
|
||||
#if !defined(GINT_NO_OS_STACK)
|
||||
"_ostk"
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
);
|
||||
uint32_t region =
|
||||
(uint32_t)kmalloc(DWIDTH*DHEIGHT*2 + MARGIN*2 + 32, arena);
|
||||
if(region == 0)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#if GINT_RENDER_RGB
|
||||
|
||||
/* gint_dhline(): Optimized horizontal line */
|
||||
void gint_dhline(int x1, int x2, int y, uint16_t color)
|
||||
void gint_dhline(int x1, int x2, int y, int color)
|
||||
{
|
||||
if(y < dwindow.top || y >= dwindow.bottom) return;
|
||||
if(x1 > x2) swap(x1, x2);
|
||||
|
@ -16,8 +16,13 @@ void gint_dhline(int x1, int x2, int y, uint16_t color)
|
|||
|
||||
/* Use longwords to do the copy, but first paint the endpoints to heed
|
||||
for odd x1 and x2. Checking the parity may be a waste of time. */
|
||||
gint_vram[offset + x1] = color;
|
||||
gint_vram[offset + x2] = color;
|
||||
if (color != C_INVERT) {
|
||||
gint_vram[offset + x1] = color;
|
||||
gint_vram[offset + x2] = color;
|
||||
} else {
|
||||
gint_vram[offset + x1] ^= 0xffff;
|
||||
gint_vram[offset + x2] ^= 0xffff;
|
||||
}
|
||||
|
||||
/* Now round to longword boundaries and copy everything in-between with
|
||||
longwords */
|
||||
|
@ -26,13 +31,17 @@ void gint_dhline(int x1, int x2, int y, uint16_t color)
|
|||
|
||||
uint32_t *start = (void *)(gint_vram + offset + x1);
|
||||
uint32_t *end = (void *)(gint_vram + offset + x2);
|
||||
uint32_t op = (color << 16) | color;
|
||||
|
||||
while(end > start) *--end = op;
|
||||
if (color != C_INVERT) {
|
||||
uint32_t op = (color << 16) | color;
|
||||
while(end > start) *--end = op;
|
||||
} else {
|
||||
while(end > start) *--end ^= 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
/* gint_dvline(): Optimized vertical line */
|
||||
void gint_dvline(int y1, int y2, int x, uint16_t color)
|
||||
void gint_dvline(int y1, int y2, int x, int color)
|
||||
{
|
||||
if(x < dwindow.left || x >= dwindow.right) return;
|
||||
if(y1 > y2) swap(y1, y2);
|
||||
|
@ -42,7 +51,11 @@ void gint_dvline(int y1, int y2, int x, uint16_t color)
|
|||
uint16_t *v = gint_vram + DWIDTH * y1 + x;
|
||||
int height = y2 - y1 + 1;
|
||||
|
||||
while(height-- > 0) *v = color, v += DWIDTH;
|
||||
if (color != C_INVERT) {
|
||||
while(height-- > 0) *v = color, v += DWIDTH;
|
||||
} else {
|
||||
while(height-- > 0) *v ^= 0xffff, v += DWIDTH;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,12 +11,12 @@
|
|||
/* gint_dhline(): Optimized horizontal line
|
||||
@x1 @x2 @y Coordinates of endpoints of line (both included)
|
||||
@color Any color suitable for dline() */
|
||||
void gint_dhline(int x1, int x2, int y, color_t color);
|
||||
void gint_dhline(int x1, int x2, int y, int color);
|
||||
|
||||
/* gint_dvline(): Optimized vertical line
|
||||
@y1 @y2 @x Coordinates of endpoints of line (both included)
|
||||
@color Any color suitable for dline() */
|
||||
void gint_dvline(int y1, int y2, int x, color_t color);
|
||||
void gint_dvline(int y1, int y2, int x, int color);
|
||||
|
||||
//---
|
||||
// Font rendering (topti)
|
||||
|
|
Loading…
Add table
Reference in a new issue