Thanks for all this info. I’d like to add some thoughts about the new library. I think one of the main use cases for this kind of memory is reading. So maybe we can put focus on that. Another main use case is to reduce PROGMEM usage for data so we can use it for more code. So what is used for PROGMEM?
First, all data that is explicitly put in PROGMEM. Here I think we can mode the Arduboy2 library to load all this data from external flash (e.g. display init data).
Second, all variables that are in the data section. E.g.
uint8_t state = 1;
That would cause the value 1 to be stored in PROGMEM and during boot the variables in the .data section would be initialized with values from PROGMEM. I think also most games will have some kind of constructor that is doing something like:
void Blah::Blah()
{
instance_var = 1;
instance_var2 = 5;
memset(some_instance_struct, value, ...)
}
And so on. So if the interface we are defining would wrap this nicely for less experienced users that would be a plus. E.g. the class could use a struct with all its state variables and then just load all the init values with a sequencial read:
struct state { ...} state;
<now in the constructor>
flash_read(&state, sizeof(state))
And the whole instance variables would be initialized with very little code/data in PROGMEM. Just thoughts…
Now concerning my game the most benefit would be reading textures and the like from external flash. Reading each byte, waiting for it and then using it would be very slow. So my thought here would be we can just use the SPI hardware better. Say I need a byte from the texture. Usually I read it and do something with it. While I am doing something with this byte I could read the next one already. So maybe we can do something like a stream of bytes…
stream_start(... blah blah address page stuff)
(above we do an addressing of the flash)
stream_request()
(above we write(0) to read one byte but do not wait for finish)
<now do something else in game logic>
stream_get() <1>
(above we actually get the byte from the SPI register, assuming the bytes is already received, maybe we need a safe/unsafe version, safe version would check if byte is already received, function can request next byte already)
<use byte in game logic and repeat <1>>
Something like this. I not very into C++ but maybe we can do something like a stream or something similar. The basic idea is to trigger the SPI to clock in a byte while we do other things. That way, ignoring the initial overhead it could be even faster than PROGMEM read (it always take 3 cycles, whereas the SPI register read+write could be faster (maybe)).
As I said, just some thoughts…
Also we might need to thing about how to nicely create a data file.