* 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.
(*) O_APPEND is *not* functional yet, this is just a hack for write-only
streams. Currently O_APPEND does not reposition the cursor at the end of
the file before every write.
There is no evidence that BFile_Create() keeps the address and writes
to it later on, but I'd rather be overly careful than have to debug a
stack corruption problem in half a year :)
I'm pretty sure it makes no difference because the OS does not rely on
interrupts for most (if not all) of its DMA operations, but it's better
to keep it clean anyway.
This helped locate some bugs:
* read() could read past EOF due to BFile_Read() allowing you to read up
until the end of the last sector, beyond the file size
* pread() did not restore the file offset because the negative seek at
the end is not relative (that was the CASIOWIN fs API), so pread()
could not actually be written without knowing the current position
* lseek() would clamp you to EOF but still return its out-of-bounds
arguments, as a direct result of BFile_Seek() doing that
Benefits:
* Made pread() a generic function