Commit graph

490 commits

Author SHA1 Message Date
Lephe
4c3fcf66a7
getkey: add a "feature function" to create application-wide shortcuts
This change introduces the global "feature function" that can be
enabled in getkey() to receive events, and use them for
application-wide features. This would be useful, for instance, to
toggle screen backlight with a different key combination that the
default, to capture screenshots, or to implement a catalog.

When enabled, the feature function is present with all new events and
can perform actions, then decide whether or not to return them from
getkey().
2021-05-12 09:17:24 +02:00
Lephe
dbba1d7b1d
defs: use auto instead of __auto_type in C++ 2021-05-12 09:17:24 +02:00
Lephe
78bf9dac7d
gray: expose pointers to the screen buffers 2021-05-12 09:17:24 +02:00
Lephe
c4ec06d6ab
display: fix bound checking in drect_border (#14)
Bounds would be moved before drawing the border, therefore displacing
the border. Since drect() already performs all the necessary checks,
this change doesn't try to save a couple of function calls and drops the
redundant checks.
2021-05-12 09:17:24 +02:00
Lephe
392d033e4a
usb: improve and expose the sync/async write API
* Properly define the callback time of a write/commit as the time when
  the pipe is available again for further writing.
* Refuse commits when writes are pending; instead, enforce a strict
  order of finishing writes before committing, which makes sense since
  consecutive writes are ordered this way already.
* Properly support callbacks for writes and for commits.
* Define the synchronous APIs in terms of waiting until the callbacks
  for equivalent asynchronous functions are invoked (plus initial
  waiting for pipes to be ready).
2021-05-12 09:17:24 +02:00
Lephe
4147236343
(minor changes) 2021-05-12 09:17:24 +02:00
Lephe
acc35d774f
dma: add an asynchronous API
This change adds asynchronous capabilities to the DMA API. Previously,
transfers would start asynchronously but could only be completed by a
call to dma_transfer_wait(). The API now supports a callback, as well
as the dma_transfer_sync() variant, to be consistent with the upcoming
USB API that has both _sync and _async versions of functions.

The interrupt handler of the DMA was changed to include a return to
userland, which is required to perform the callback.

* dma_transfer() is now an obsolete synonym for dma_transfer_async()
  with no callback.
* dma_transfer_noint() is now a synonym for dma_transfer_atomic(), for
  consistency with the upcoming USB API.
2021-05-12 09:17:24 +02:00
Lephe
42081c9968
intc: allow any call in intc_handler_function() 2021-05-12 09:17:24 +02:00
Lephe
0233088565
cmake: do not require a build from the gint tree (#15) 2021-05-12 09:16:14 +02:00
Lephe
58170b9e5b
cmake: lower minimum required version to 3.15 2021-05-12 09:16:11 +02:00
Lephe
f05a94ca15
bump version number 2021-04-27 16:20:09 +02:00
Lephe
c1e96173da
cmake: make OpenLibm a dependency
This is required for the floating-point printing with Grisu2b.
2021-04-27 15:24:24 +02:00
Lephe
74b2dbeb36
string: use __restrict instead of restrict for C++ compatibility 2021-04-27 14:48:34 +02:00
Lephe
50cbcd4ac1
usb: fix module not being restored after usb_close()
usb_close() would unpower the module and gint_world_switch_out()
assumed it was powered, so the context switch would fail.
2021-04-27 14:45:12 +02:00
Lephe
c37f150600
use GINT_CALL() in every API that has callbacks
* 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"
2021-04-27 14:29:38 +02:00
Lephe
85d30fa59b
kernel: specify the return values of standard GINT_CALLs
They return 0 by default, which corresponds to TIMER_CONTINUE when used
in timers. Add new *_STOP variables which return 1 (TIMER_STOP).
2021-04-26 22:01:14 +02:00
Lephe
89cab4f68e
add utility types BFile_FileType, off_t 2021-04-26 21:58:52 +02:00
Lephe
c9264a06d5
kernel: driver and world system overhaul
Changes in the driver and world system:

* Rewrite driver logic to include more advanced concepts. The notion of
  binding a driver to a device is introduced to formalize wait(); power
  management is now built-in instead of being handled by the drivers
  (for instance DMA). The new driver model is described in great detail
  in <gint/drivers.h>

* Formalized the concept of "world switch" where the hardware state is
  saved and later restored. As a tool, the world switch turns out to be
  very stable, and allows a lot of hardware manipulation that would be
  edgy at best when running in the OS world.

* Added a GINT_DRV_SHARED flag for drivers to specify that their state
  is shared between worlds and not saved/restored. This has a couple of
  uses.

* Exposed a lot more of the internal driver/world system as their is no
  particular downside to it. This includes stuff in <gint/drivers.h>
  and the driver's state structures in <gint/drivers/states.h>. This is
  useful for debugging and for cracked concepts, but there is no
  API stability guarantee.

* Added a more flexible driver level system that allows any 2-digit
  level to be used.

Feature changes:

* Added a CPU driver that provides the VBR change as its state save.
  Because the whole context switch relied on interrupts being disabled
  anyway, there is no longer an inversion of control when setting the
  VBR; this is just part of the CPU driver's configuration. The CPU
  driver may also support other features such as XYRAM block transfer
  in the future.

* Moved gint_inthandler() to the INTC driver under the name
  intc_handler(), pairing up again with intc_priority().

* Added a reentrant atomic lock based on the test-and-set primitive.
  Interrupts are disabled with IMASK=15 for the duration of atomic
  operations.

* Enabled the DMA driver on SH7305-based fx-9860G. The DMA provides
  little benefit on this platform because the RAM is generally faster
  and buffers are ultimately small. The DMA is still not available on
  SH3-based fx-9860G models.

* Solved an extremely obnoxious bug in timer_spin_wait() where the
  timer is not freed, causing the callback to be called when interrupts
  are re-enabled. This increments a random value on the stack. As a
  consequence of the change, removed the long delays in the USB driver
  since they are not actually needed.

Minor changes:

* Deprecated some of the elements in <gint/hardware.h>. There really is
  no good way to "enumerate" devices yet.

* Deprecated gint_switch() in favor of a new function
  gint_world_switch() which uses the GINT_CALL abstraction.

* Made the fx-9860G VRAM 32-aligned so that it can be used for tests
  with the DMA.

Some features of the driver and world systems have not been implemented
yet, but may be in the future:

* Some driver flags should be per-world in order to create multiple
  gint worlds. This would be useful in Yatis' hypervisor.
* A GINT_DRV_LAZY flag would be useful for drivers that don't want to
  be started up automatically during a world switch. This is relevant
  for drivers that have a slow start/stop sequence. However, this is
  tricky to do correctly as it requires dynamic start/stop and also
  tracking which world the current hardware state belongs to.
2021-04-23 20:44:08 +02:00
Lephe
770b4e0117
gint: rename the callbacks GINT_CALL, as there are synchronous ones
This will be useful for world switch calls which are not "callbacks" but
simply polymorphic function pointers.
2021-04-20 17:51:53 +02:00
Lephe
52bc1fc848
(typos and TODOs) 2021-04-20 12:19:24 +02:00
Lephe
9260925d5f
cmake: use POSIX sed only for BSD/Mac OS compatibility 2021-04-17 14:48:12 +02:00
Lephe
1315c26099
usb: USB 2.0 function driver (WIP)
* Add the power management functions (mostly stable even under
  overclock; requires some testing, but no known issue)

* Add a dynamic configuration system where interfaces can declare
  descriptors with arbitrary endpoint numbers and additional
  parameters, and the driver allocates USB resources (endpoints, pipes
  and FIFO memory) between interfaces at startup. This allows
  implementations of different classes to be independent from each
  other.

* Add responses to common SETUP requests.

* Add pipe logic that allows programs to write data synchronously or
  asynchronously to pipes, in a single or several fragments, regardless
  of the buffer size (still WIP with a few details to polish and the
  API is not public yet).

* Add a WIP bulk IN interface that allows sending data to the host.
  This will eventually support the fxlink protocol.
2021-04-11 19:04:54 +02:00
Lephe
2891a85338
cmake: CMAKE_INSTALL_MESSAGE=LAZY 2021-04-11 18:48:57 +02:00
Lephe
a2fd9e3351
kernel: add a generic callback mechanism
This mechanism allows callbacks to be defined with up to 4 32-bit
arguments, and could be extended later. This will hopefully replace the
timer_callback_t used in timers and RTC, and will be added to the DMA
and USB APIs -- the hard part is to not break source compatibility with
previous versions.
2021-04-11 18:47:17 +02:00
Lephe
fb8d1525f4
kernel: guarantee availability of drivers based on dependency levels
The question of how to handle a partially-restored world state begs for
an elegant symmetrical answer, but that doesn't work unless both kernels
do the save/restore for themselves. So far, things have worked out
because any order works since interrupts are disabled therefore
partially-restored drivers are inactive.

However the USB module requires waits that are best performed with
timers, so the order cannot be chosen arbitrarily. This commit enforces
a gint-centric order where code from a gint driver is only run when all
lower-level drivers are active. This solves some pretty bad freezes with
the USB module.
2021-04-11 18:36:07 +02:00
Lephe
18f9a18925
kmalloc: implement a custom segregated list allocator
The new allocator uses a segregated best-fit algorithm with exact-size
lists for all sizes between 8 bytes (the minimum) and 60 bytes, one list
for blocks of size 64-252 and one for larger blocks.

Arenas managed by this allocator have built-in statistics that track
used and free memory (accounting for block headers), peak memory, and
various allocation results.

In addition, the allocator has self-checks in the form of integrity
verifications, that can be enabled with -DGINT_KMALLOC_DEBUG=1 at
configuration time or with the :dev configuration for GiteaPC. This is
used by gintctl.

The kmalloc interface is extended with a new arena covering all unused
memory in user RAM, managed by gint's allocator. It spans about 4 kB on
SH3 fx-9860G, 16 kB on SH4 fx-9860G, and 500 kB on fx-CG 50, in addition
to the OS heap. This new arena is now the default arena for malloc(),
except on SH3 where some heap problems are currently known.
2021-03-15 15:04:24 +01:00
Lephe
162b11cc73
kmalloc: create the kmalloc interface
This change introduces a centralized memory allocator in the kernel.
This interface can call into multiple arenas, including the default OS
heap and planned arenas managed by a gint algorithm.

The main advantage of this method is that it allows the heap to be
extended over previously-unused areas of RAM such as the end of the
static RAM region (apart from where the stack resides). Not using the OS
heap is also sometimes a matter of correctness since on some OS versions
the heap is known to fragment badly and degrade over time.

I hope the deep control this interfaces gives over meomry allocation
will allow very particular applications like object-specific allocators
in fragmented SPU memory.

This change does not introduce any new algorithm or arena so programs
should behave exactly as before.
2021-03-12 17:24:49 +01:00
Lephe
910677f7ff
getkey: use the new keydev interface
The repeat filter was also changed in favor of a forward-acting
function, which determines repeat delays *before* the repeat actually
occurs.
2021-03-05 14:49:24 +01:00
Lephe
dd564f094a
keydev: add a keyboard device layer to abstract away globals
The new keyboard device (keydev) interface implements the kernel's view
of a keyboard providing input events. Its main role is to abstract all
the globals of the KEYSC driver and getkey functions into a separate
object: the "keyboard device".

The device implements event transformations such as modifiers and
repeats, instead of leaving them to getkey. While this can seem
surprising at first, a real keyboard controller is responsible for
repeats and modifier actions depend on the state of the keyboard which
is only tracked in real-time.

In this commit, getkey() has not changed yet apart from indirectly using
the keydev interface with pollevent(). It will be changed soon to use
event transforms in keydev_read(), and will be left in charge of
providing repeat profiles, handling return-to-menu, backlight changes
and timeouts, all of which are user convenience features.
2021-03-05 09:31:34 +01:00
Lephe
97ca5ba82f
display: add a dfont_default() function to get the default font 2021-02-28 22:28:12 +01:00
Lephe
bd40a0a41c
display: add more text size options dnsize() and drsize()
* dnsize() works like dsize() but a limit on the number of bytes is
  specified. This is useful to obtain the length of a substring.
* drsize() has a reverse limit; the input specifies a number of pixels
  and the function determines how much of the input fits. This is useful
  for word wrapping algorithms.
2021-02-22 16:43:02 +01:00
Lephe
a086510885
display: add a maximum size parameter to dtext_opt()
This parameter controls the maximum number of glyphs to print.

For backwards compatibility, it is automatically inserted by a macro in
older calls with only 7 parameters.
2021-02-15 18:37:06 +01:00
Lephe
cb2d067967
std/string: add strchr(), strrchr(), and strchrnul() 2021-02-15 17:28:11 +01:00
Lephe
553982a445
std/stdio: support asprintf() and vasprintf() 2021-02-15 09:48:10 +01:00
Lephe
3885f10ee1
kernel: move VBR at the end of the user RAM area on fx-9860G
This leaves more space available for the heap.
2021-02-15 09:46:59 +01:00
Lephe
2c9ff901d1
mmu: add an mmu_uram_size() function detecting static RAM size
This function performs a more rigorous analysis of the mapped region by
checking continuity. So far all pages mapped in userpsace have been
contiguous, so the results are identical to gint[HWURAM].

Page size is now optionnaly provided in mmu_translate() and its
subfunctions; programs that use this function need to add a second NULL
parameter.
2021-02-05 18:20:16 +01:00
Lephe
bbf6401213
kprint: add floating-point formatting based in Grisu2b 59,56 2021-02-02 22:18:15 +01:00
Lephe
023675d449
improve structure of sources and formatted printer
* Create an `src/3rdparty` folder for third-party code (to add the
  Grisu2B alfogithm soon).
* Split the formatted printer into gint's kprint (src/kprint), its
  extension and interface (include/gint/kprint.h), and its use in the
  standard stdio functions (src/std/print.c).
* Slightly improve the interface of kformat_geometry() to avoid relying
  on knowing format specifiers.
* Add a function to register more formatters, to allow floating-point
  formatters without requiring them.
2021-02-02 18:19:10 +01:00
Lephe
ee7b4f27b8
add a dynamic setting for keyboard scan frequency
The repeat delays of getkey() are adjusted automatically, however a
repeat that is currently going on might be affected.

Also, repeat delays are always approximated as a whole number of
keyboard scans so an increase in scan frequency can impact the speed at
which repeats are emitted.
2021-02-02 18:19:10 +01:00
Lephe
6440527527
rtc: add an rtc_ticks() function similar to RTC_GetTicks() 2021-02-02 18:19:08 +01:00
Lephe
7e1becbd79
cmake: only require version 3.16 2021-02-02 18:18:06 +01:00
Lephe
293532024d
kernel: fix gint[HWURAM] not being set on fx-9860G
When switching to dynamic TLB the counting of mapped memory was no
longer required at boot time. This was restored weirdly for fx-CG 50 and
not at all for fx-9860G; this is now fixed.
2021-02-02 18:18:02 +01:00
Lephe
dce5ade4e1
build: fix uninstall command for sh-based OSes 2021-02-02 18:17:36 +01:00
Lephe
deeaaa499f
update README 2021-01-29 18:22:55 +01:00
Lephe
e5a7d968a6
cmake: declare assets through the fxSDK utility 2021-01-27 20:48:59 +01:00
Lephe
815d479ab7
cmake: install FindGint.cmake (previously in the fxSDK) 2021-01-27 08:57:23 +01:00
Lephe
0ed5ead0a0
update README 2021-01-25 21:52:42 +01:00
Lephe
8157f4b2ab
cmake: restore options USER_VRAM and STATIC_GRAY 2021-01-25 19:06:42 +01:00
Lephe
0525b51ba5
switch build system to CMake
This factors the burden of compiler specification in the fxSDK while
providing substantially more support through CMake modules.
2021-01-25 15:31:20 +01:00
Lephe
15ec46d11c
add GiteaPC support 2021-01-16 18:29:32 +01:00