* Change gint_inth_callback()
* Add intc_handler_function() to use C functions as handlers instead of
writing assembler, and use it in the RTC and USB
* Revisit the TMU handlers, which after moving out the callbacks, now
fit into 3 gates (great!), and adapt the ETMU handler
* Improve the timer driver (less code = better code, removed magic
constants assuming the VBR layout on SH3/SH4, etc.)
* Remove 2 gates and a gap from the compact scheme on SH3
* Define timer_configure() to replace timer_setup(), which could not be
cleanly updated to support GINT_CALL()
* Replace rtc_start/stop_timer with rtc_periodic_enable/disable, which
is less confusing because of ETMU being "RTC timers"
This change adds a new TMU function timer_spinwait() which waits for a
timer to raise its UNF flag. This makes it possible to wait even when
interrupts are disabled.
This is used by the new CPG function sleep_us_spin() which waits for a
given delay without using interrupts. This is currently used in SPU
initialization.
This commit minimally changes the signature of timer_setup() to greatly
simplify timer management, allowing to user to let the library choose
available timers dynamically depending on the settings.
This change enables interrupts within timer callbacks, making it
possible to load pages to MMU while handling a timer underflow. The call
to TLB_LoadPTEH() has been moved directly into the VBR handler to avoid
jumping to ILRAM for a short call on SH4.
The TMU and ETMU handlers have been changed to callback through a new
function gint_inth_callback() that saves the user bank and a few
registers, then invokes the callback with interrupts enabled and in user
bank; until now, callbacks were invoked with interrupts disabled and in
kernel bank. Note that IMASK is still set so a callback can only be
interrupted by a high-priority interrupt.
A timer_wait() function has also been added to simplify tests that
involve timers. Finally, the priority level of the TMU0 underflow
interrupt has been set to 13 (as per the comments) instead of 7.
This version is the first stable version that handles TLB misses
transparently for large add-ins. It is suitable for every gint
application.
* 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.
This commit introduces three timer driver changes:
* Export the definitions of the timer structures to a detailed header at
<gint/mpu/tmu.h>, and re-use them in the driver.
This integration is still limited as the driver keeps its own address
definitions and event codes.
* Clean the timer stop routine that is used in the interrupt handler. Up
until now the interrupt handler would only stop TSTR, which is not
enough to cleanly leave the timer (need TCOR=TCNT=-1) and is not even
sound with respect to gint's semantics as UNIE stays enabled so the
timer is not made available again.
The interrupt handler now calls into C code when the timer stop
condition is met (callback returns non-zero) to keep this clean. This
unsurprisingly solves problems that occurred in certain situations
when a timer was used repeatedly.
* Expose timer addresses using a timer_address() function, compensating
for the lack of address definitions in <gint/mpu/tmu.h>. This
interface is likely to evolve in the future to better integrate the
address in the MPU headers and move them out of the driver.