* Honor dwindow settings immediately (avoids useless dline() calls)
* Bound to ymin/ymax instead of doing many useless cut computations
* Remove the need for floating-point operations and division
* Move logic around tracking transfers to asyncio.c.
* Add a "short buffer" holding 0-3 bytes between writes, so that the
driver performs only 4-byte writes in the FIFO and a short write in
the commit, if needed.
- This is partially due to me thinking at some point that degrading
writing size was impossible, but it might actually be possible by
writing to FIFO/FIFO+2 or FIFO/FIFO+1/FIFO+2/FIFO+3.
- In any case I think this new approach wins on performance.
* Get rid of unit_size since we now always use 4 bytes.
* Add a waiting function which is used in usb_close() (and once tested
should be used in world switches too).
* Eliminate some of the special cases for the DCP, though not all (in
particular I can't get the commit to rely on the BEMP interrupt yet,
nor can I properly clear PID to NAK when unbinding).
* Create a heap arena over the OS stack, large enough to hold two VRAMs
as was previously done, unless GINT_NO_OS_STACK is set at compile
time. (This replaces GINT_USER_VRAM.)
* Allocate a single VRAM in the heap at startup.
* Use double buffering by default as triple buffering is almost entirely
useless. dudpate() waits if both VRAMs are identical to prevent
corruption, but this can be bypassed with R61524 functions as usual.
This adds about 180 kB of heap data to any add-in using default
settings.
* Stop trying to be smart and generate repeats on the fly; this breaks
time consistency. Also if repeats are not handled in time this causes
infinite loops.
* Move rarely-used functions to external files, simplify stuff, get rid
of internal driver events; saves ~1 kB per add-in overall.
This changes fixes the way gint uses the FIFO controllers D0F and D1F
to access the FIFO. It previously used D0F in the main thread and D1F
during interrupt handling, but this is incorrect for several reasons,
mainly the possible change of controllers between a write and a commit,
and numerous instances of two FIFOs managing the same pipe caused by
the constant switching.
gint now treats FIFO controllers as resources allocated to pipes for
the duration of a commit-terminated sequence of writes. The same
controller is used for a single pipe in both normal and interrupt
modes, and released when the pipe is committed. If no controller is
available, asynchronous writes fail and synchronous ones wait.
The fxlink API is also added with a small amount of functions, namely
to transfer screenshots and raw text. Currently these are synchronous
and do not use the DMA, this will be improved later.
Finally:
* Removed pipe logic from src/usb/setup.c, instead letting pipes.c
handle the special case of the DCP (which might be regularized later)
* Removed the usb_pipe_mode_{read,write} functions as they're actually
about FIFo controllers and it's not clear yet how a pipe with both
read and write should be handled. This is left for the future.
* Clarified end-of-sequence semantics after a successful commit.
This change introduces new sleep_block() and sleep_unblock() functions
that control whether the sleep() function actually sleeps. This type of
behavior was already implemented in the DMA driver, since DMA access to
on-chip memory is paused when sleeping (on-chip memory being paused
itself), which would make waiting for a DMA transfer a freeze.
Because DMA transfers are now asynchronous, and USB transfers that may
involve on-chip memory are coming, this API change allows the DMA and
USB drivers to block the sleep() function so that user code can sleep()
for interrupts without having to worry about asynchronous tasks
requiring on-chip memory to complete.