Compare commits

...

16 commits

Author SHA1 Message Date
Lephenixnoir
3ade0894d8 Merge pull request 'fix missing C_INVERT support in dline() for render-cg' (#37) from Yatis/gint:fix/dline_fxgc into dev
Reviewed-on: https://git.planet-casio.com/Lephenixnoir/gint/pulls/37
2025-02-19 16:19:22 +01:00
Yann MAGNIN
377aa3745d
fix missing C_INVERT support in dline() for render-cg 2025-02-19 16:11:44 +01:00
Lephenixnoir
191a5ebccf Merge pull request 'cpg: add superhyway clock frequency calculation' (#36) from CalcLoverHK/gint:dev into dev
Reviewed-on: https://git.planet-casio.com/Lephenixnoir/gint/pulls/36
2025-02-16 10:20:17 +01:00
CalcLoverHK
cdcf880006 cpg: add superhyway clock frequency calculation 2025-02-16 17:04:27 +08:00
Lephe
ff17b8c22c
kernel: syscall support for Math+ OS v2.00 2025-02-03 23:52:48 +01:00
Lephe
e44e4fa14e
keysc: add MPU module description for KEYSC 2025-02-03 23:52:48 +01:00
Lephe
87fff59527
keysc: fix keycodes mapping to multiple keys on Math+ 2025-02-03 23:52:48 +01:00
Lephe
232a4195d2
cpg: don't overclock beyond known limits on Math+ 2025-02-03 23:52:48 +01:00
Lephe
7ac9668dfd
keydev: add Catalog+4th row combo for F1...F6 on Math+ 2025-02-03 23:52:48 +01:00
Lephe
7a479e4f45
keydev: support for the Math+ layout and track row/col
key_event_t is now 8 bytes instead of 4, a change that was doomed to
happen anyway to deal with touch input (where it's not clear either
whether 8 bytes will be enough for double touch).
2025-02-03 23:52:48 +01:00
Lephe
a62ba8a026
kernel: further support for the Math+ in general
* Add a new HWCALC value HWCALC_FXCG100, detected based on being on an
  Area-3 RAM model and having OS version that's either less than 3 or
  3 and built after January 2025.
* Disable the _ostk heap arena, as the region might simply not exist,
  and improve the VRAM allocation code to account for this better than
  the hardcoded macro previously in place for the fx-CP 400.
* Disable gint_osmenu() which can't work with MPM right now.
* Add BFile_FindFirst() and GetVRAMAddress() syscalls.
2025-02-03 23:52:48 +01:00
Lephe
f953efdc82
kernel: partial support for Math+ OS 1.00 2025-02-03 23:52:47 +01:00
Lephe
1df334110e
kernel: allows syscalls to be called from fixed addresses 2025-02-03 23:52:44 +01:00
Lephenixnoir
09ad6b0b31
minor: add missing include in defs/call.h 2024-12-16 13:15:37 +01:00
Lephenixnoir
a324ce792a Merge pull request 'kernel: simplify PIE support' (#33) from Yatis/gint:dev into dev
Reviewed-on: https://git.planet-casio.com/Lephenixnoir/gint/pulls/33
2024-12-13 13:41:07 +01:00
Yann MAGNIN
45139d13b5
kernel: simplify PIE support 2024-12-13 13:38:59 +01:00
24 changed files with 408 additions and 135 deletions

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -12,6 +12,7 @@
#define GINT_DEFS_CALL
#include <stdbool.h>
#include <gint/defs/attributes.h>
#ifdef __cplusplus
extern "C" {

View file

@ -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) */

View file

@ -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

View file

@ -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;

View file

@ -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
View 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 */

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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);

View file

@ -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() */

View file

@ -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 */

View file

@ -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 */

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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)