gint/src/core/syscalls.S

147 lines
2.7 KiB
ArmAsm
Raw Normal View History

/*
** gint:core:syscalls - calls to CASIOWIN
**
2019-07-04 18:15:13 +02:00
** This file can be seen as a list of everywhere gint relies on the
** underlying OS. Although I wish to make gint free-standing, there are
2019-07-04 18:15:13 +02:00
** still a few hard questions, namely:
** * MMU management, because doing it wrong might break the calculator.
** * Dynamic allocation, because we can't trash the system heap.
** * File system, because it's a mess and we might ruin the ROM.
*/
/* Dynamic allocation */
.global _malloc
.global _free
.global _calloc
.global _realloc
/* Bfile driver */
2019-07-04 18:15:13 +02:00
.global _BFile_Remove
.global _BFile_Create
.global _BFile_Open
.global _BFile_Close
2020-01-13 15:44:04 +01:00
.global _BFile_Size
2019-07-04 18:15:13 +02:00
.global _BFile_Write
.global _BFile_Read
.global _BFile_FindFirst
.global _BFile_FindNext
.global _BFile_FindClose
core, tmu: add gint_switch(), return to menu, and improve timer code * Add the gint_switch() function which executes user-provided code from the system (CASIOWIN) context. * Added interrupt masks to the core context (should have been there long ago). * Added the gint_osmenu() function that switches out of gint to invoke GetKeyWait() and inject KEY_CTRL_MENU to trigger the main menu. This uses many CASIOWIN syscalls, but we don't care because gint is unloaded. Trickery is used to catch the key following the return in the add-in and/or display a new application frame before GetKeyWait() even finishes after coming back. This is only available on fx9860g for now. * Removed any public syscall definition to clear up interfaces. * Patched the DMA interruption problem in a weird way on fxcg50, a driver function will be used to do that properly eventually. * Changed the driver model to save driver contexts in preallocated spaces instead of on the stack for overall less risk. * Enabled return-to-menu with the MENU key on fx9860g in getkey(). * Changed the keyboard driver to emit releases before presses, as a return-to-menu acts as a press+release of different keys in a single driver frame, which confuses getkey(). * Fixed a really stupid bug in memcpy() that made the function really not work. Improvements in the timer driver: * Expose ETMU modules as SH7705_TMU and SH7305_TMU in <gint/mpu/tmu.h>. * Remove the timer_t structures, using SH*_ETMU and SH*_TMU instead. Only interrupt gate entries are left hardcoded. * Discovered that not only every write to the TCNT or TCR of an ETMU takes about 1/32k of a second (hinting at registers being powered by the same clock as the timer), but every write occuring while a previous write is pending is *lost*. This led to terrible bugs when switching ETMU contexts too fast in gint_switch(). * Removed an internal timer_address() function. * Overall simplified the handling of timers and the initialization step.
2020-05-10 14:03:41 +02:00
/* Return to menu */
.global ___Timer_Install
.global ___Timer_Start
.global ___Timer_Stop
.global ___Timer_Deinstall
.global ___PutKeyCode
.global ___GetKeyWait
.global ___ClearKeyBuffer
.global ___GetVRAMAddress
.section ".pretext"
#define syscall(id) \
mov.l syscall_table, r2 ;\
mov.l 1f, r0 ;\
jmp @r2 ;\
nop ;\
1: .long id
#ifdef FX9860G
/* Dynamic allocation */
_malloc:
syscall(0x0acd)
_free:
syscall(0x0acc)
_calloc:
syscall(0x0e6b)
_realloc:
syscall(0x0e6d)
2019-07-04 18:15:13 +02:00
/* BFile driver */
# int BFile_Remove(const uint16_t *file)
_BFile_Remove:
2019-07-17 00:34:10 +02:00
syscall(0x0439)
2019-07-04 18:15:13 +02:00
# int BFile_Create(uint16_t *file, enum { file = 1, folder = 5 }, int *size)
_BFile_Create:
2019-07-17 00:34:10 +02:00
syscall(0x0434)
2019-07-04 18:15:13 +02:00
# int BFile_Open(const uint16_t *file, int mode)
_BFile_Open:
2019-07-17 00:34:10 +02:00
syscall(0x042c)
2019-07-04 18:15:13 +02:00
# int BFile_Close(int handle)
_BFile_Close:
2019-07-17 00:34:10 +02:00
syscall(0x042d)
2019-07-04 18:15:13 +02:00
2020-01-13 15:44:04 +01:00
# int BFile_Size(int handle)
_BFile_Size:
syscall(0x042f)
2019-07-04 18:15:13 +02:00
# int BFile_Write(int handle, const void *ram_buffer, int even_size)
_BFile_Write:
2019-07-17 00:34:10 +02:00
syscall(0x0435)
2019-07-04 18:15:13 +02:00
# int BFile_Read(int handle, void *ram_buffer, int size, int whence)
_BFile_Read:
2019-07-17 00:34:10 +02:00
syscall(0x0432)
2019-07-04 18:15:13 +02:00
# int BFile_FindFirst(uint16_t const *search, int *shandle,
# uint16_t *foundfile, struct BFile_FileInfo *fileinfo)
_BFile_FindFirst:
syscall(0x043b)
# int BFile_FindNext(int shandle, uint16_t *foundfile,
# struct BFile_FileInfo *fileinfo)
_BFile_FindNext:
syscall(0x043c)
# int BFile_FindClose(int shandle)
_BFile_FindClose:
syscall(0x043d)
core, tmu: add gint_switch(), return to menu, and improve timer code * Add the gint_switch() function which executes user-provided code from the system (CASIOWIN) context. * Added interrupt masks to the core context (should have been there long ago). * Added the gint_osmenu() function that switches out of gint to invoke GetKeyWait() and inject KEY_CTRL_MENU to trigger the main menu. This uses many CASIOWIN syscalls, but we don't care because gint is unloaded. Trickery is used to catch the key following the return in the add-in and/or display a new application frame before GetKeyWait() even finishes after coming back. This is only available on fx9860g for now. * Removed any public syscall definition to clear up interfaces. * Patched the DMA interruption problem in a weird way on fxcg50, a driver function will be used to do that properly eventually. * Changed the driver model to save driver contexts in preallocated spaces instead of on the stack for overall less risk. * Enabled return-to-menu with the MENU key on fx9860g in getkey(). * Changed the keyboard driver to emit releases before presses, as a return-to-menu acts as a press+release of different keys in a single driver frame, which confuses getkey(). * Fixed a really stupid bug in memcpy() that made the function really not work. Improvements in the timer driver: * Expose ETMU modules as SH7705_TMU and SH7305_TMU in <gint/mpu/tmu.h>. * Remove the timer_t structures, using SH*_ETMU and SH*_TMU instead. Only interrupt gate entries are left hardcoded. * Discovered that not only every write to the TCNT or TCR of an ETMU takes about 1/32k of a second (hinting at registers being powered by the same clock as the timer), but every write occuring while a previous write is pending is *lost*. This led to terrible bugs when switching ETMU contexts too fast in gint_switch(). * Removed an internal timer_address() function. * Overall simplified the handling of timers and the initialization step.
2020-05-10 14:03:41 +02:00
/* Return to menu */
___Timer_Install:
syscall(0x118)
___Timer_Start:
syscall(0x11a)
___Timer_Stop:
syscall(0x11b)
___Timer_Deinstall:
syscall(0x119)
___PutKeyCode:
syscall(0x24f)
___GetKeyWait:
syscall(0x247)
___ClearKeyBuffer:
syscall(0x241)
___GetVRAMAddress:
syscall(0x135)
syscall_table:
.long 0x80010070
#endif /* FX9860G */
#ifdef FXCG50
/* Dynamic allocation */
_malloc:
syscall(0x1f44)
_free:
syscall(0x1f42)
_calloc:
syscall(0x1f40)
_realloc:
syscall(0x1f46)
syscall_table:
.long 0x80020070
#endif /* FXCG50 */