Something odd is happening. I've finally been able to flash xbasic into the SPI flash on my C3 board and it ran the first time I downloaded it using payload. I then tried typing "payload Flash_Boot" to write the boot program into EEPROM and after that completed xbasic worked too. However, if I press the reset button, even though xbasic comes up, the SD card file I/O doesn't seem to work and I can't load 'test.bas' from the SD card. Any idea why it would behave differently after reset than after it was initially loaded?
That is a bit odd. One possibility - if you just said "payload Flash_Boot" without the -e switch, you didn't actually program it into EEPROM. So on reboot you may be using an old version (perhaps one without the Hub Flash loader fix?).
That is a bit odd. One possibility - if you just said "payload Flash_Boot" without the -e switch, you didn't actually program it into EEPROM. So on reboot you may be using an old version (perhaps one without the Hub Flash loader fix?).
Ross.
Yes, that's what I did. I left out the -e switch. I copied my command line from the C3 tutorial you wrote in an earlier message but failed to notice that it was just restarting the program in flash not programming the EEPROM. Thanks for pointing that out!
Good. So is everything now working correctly? Are you still having problems programming the Flash?
Ross.
It seems to be working now although I still sometimes get errors programming the flash. It always seems to stop at the same point too. I'm sure I haven't erased the flash on my C3 enough times that it should be starting to fail. I'm pretty sure you can do at least 100k erase cycles and I didn't do anywhere near that many. Also, sometimes when it starts up it fails to read the SD card. It seems like maybe the SD card mount failed.
It seems to be working now although I still sometimes get errors programming the flash. It always seems to stop at the same point too. I'm sure I haven't erased the flash on my C3 enough times that it should be starting to fail. I'm pretty sure you can do at least 100k erase cycles and I didn't do anywhere near that many. Also, sometimes when it starts up it fails to read the SD card. It seems like maybe the SD card mount failed.
You might have a slightly duff sector in your SPI chip. Andre suggested elswehere it might become necessary to program the flash more than once. If I have enough space in the caching driver I will add an option to do a read check after programming each sector, and to erase it and program it again if it fails. This might take me a few days.
I don't know if this could also be causing the SD card failure. I haven't had any instances of that on my C3 since I modified the SD card driver initialization code (which was in release 3.0).
I wonder if possibly the two issues could both have the same underlying cause - maybe there is a timing problem on the SPI bus selection - I could also try adding a configurable delay to that code to see if it helps make it more reliable. Again, this might take me a while - especially as I don't have any spare longs in the C3 XMM kernel!
Tonight I'll package your xbasic program up into an easily installable form (i.e. one that doesn't need Catalina installed) so that some other C3 users can try it out - having a wider sample of C3's might help identify if what you are seeing is just an individual hardware problem on one C3.
Thanks Ross! I really appreciate the great support you give for your products! I have written a PASM version of the virtual machine that runs code generated by the xbasic compiler. I'm going to try to get that working with Catalina. I just need to figure out how to load another COG with assembly code. Maybe I should look at what Dr_Acula has been doing. It sounds like it is similar to what I'll need except that I'd just like to link the COG images into my C code rather than reading them off of the SD card.
1) after erasing a block, read it, and if you get any non $FF values, goto 1
2) after programming a byte/page
2a) read it back, if not the value you want, reprogram it without erasing it - try this up to 10 times
2b) mark that page bad in a "bad block map"
Now theoretically, once you have all the pages in a sector (4k/32k/64k erasable sector) marked as bad, or one marked as bad rest unused, you could try erasing it, and removing it from the bad block map
Unfortunately for VM, supporting a bad block map means a second-level address translation on flash addresses.
But these flash chips that are used on the C3 should support at least 100k erase cycles, right? I don't think I've gotten anywhere near that on my C3. Do these chips often fail much earlier than their rated life?
Thanks ++ Ross for the explanation. I'll give _sys_plugin a try. Cheers, Drac
I'm curious as to why you're playing with plugins. Have you abandoned your cogjects project? I like the idea of loading the driver COGs from the C code rather than having the target load them before starting the main program. Why did you decide against that?
1) after erasing a block, read it, and if you get any non $FF values, goto 1
2) after programming a byte/page
2a) read it back, if not the value you want, reprogram it without erasing it - try this up to 10 times
2b) mark that page bad in a "bad block map"
Now theoretically, once you have all the pages in a sector (4k/32k/64k erasable sector) marked as bad, or one marked as bad rest unused, you could try erasing it, and removing it from the bad block map
Unfortunately for VM, supporting a bad block map means a second-level address translation on flash addresses.
Thanks Bill. If I have enough space, I'll try implementing 1,2 & 2a. 2b is probably not worth the effort when a replacement unit only costs a few tens of dollars.
I'm curious as to why you're playing with plugins. Have you abandoned your cogjects project? I like the idea of loading the driver COGs from the C code rather than having the target load them before starting the main program. Why did you decide against that?
I'm working hard to convince Dr_A to use plugins, since his cogjects reproduce (in part) what Catalina can already do.
For example, plugins can be loaded and unloaded from C code quite easily. There is an example in the custom_demo folder. The complex_example.c demo program actually loads the plugin two ways - on startup the plugin is loaded by the SPIN target. The C program then unloads it and reloads it again from C.
It takes two lines of C code to load or unload a plugin at run-time (only one if the plugin registers itself).
My problem with plugins is that they require messing around with Spin code to get the environment setup. I would prefer a C environment that lets me do all of my work in C and maybe PASM without having to resort to Spin as well. Is there any chance you could move your plugin code into the C startup code rather than loading plugins from the Spin target code? It would be nice to be able to configure the compiler once for your target board and then forget about it rather than having to go back to the target code every time you want to use a new PASM driver.
My problem with plugins is that they require messing around with Spin code to get the environment setup. I would prefer a C environment that lets me do all of my work in C and maybe PASM without having to resort to Spin as well. Is there any chance you could move your plugin code into the C startup code rather than loading plugins from the Spin target code? It would be nice to be able to configure the compiler once for your target board and then forget about it rather than having to go back to the target code every time you want to use a new PASM driver.
Hi David,
It would certainly be possible to create a target that just loaded the kernel but no plugins, and then to provide a set of PASM programs intended to be compiled and loaded from C as plugins. This would require a fairly modest amount of work, and is something you could do yourself. In many ways it is quite similar to what Dr_A is doing with his cogjects.
But other than complicating both the program build process and the C startup process, I don't see that it really accomplishes much. Yes, it means you can do everything in PASM and C without ever having to touch a line of SPIN code - but in fact, most people in these forums seem to want exactly the opposite (i.e. they want to make the SPIN part more visible, to make it easier to have SPIN programs called from C or vice-versa).
The current solution is kind of a "best of both worlds" approach - i.e. you can load your plugins either in the SPIN target or in the C program - or both!.
I'm assuming that the par and addr parameters to your _coginit function need to point to buffers in hub memory, right? I imagine there isn't any code in _coginit that copies the COG code from external memory to hub memory before executing the coginit instruction. It looks like _coginit will do everything I need to do for getting my xbasic VM working. I guess I can look into making it a plugin later if there is some advantage to that.
I'm assuming that the par and addr parameters to your _coginit function need to point to buffers in hub memory, right? I imagine there isn't any code in _coginit that copies the COG code from external memory to hub memory before executing the coginit instruction. It looks like _coginit will do everything I need to do for getting my xbasic VM working. I guess I can look into making it a plugin later if there is some advantage to that.
Thanks,
David
Yes - plugins cannot (in general) access XMM RAM, and they therefore expect all addresses to be Hub addresses.
The current solution is kind of a "best of both worlds" approach - i.e. you can load your plugins either in the SPIN target or in the C program - or both!.
I think the problem I have with the current approach is that the target stuff is off in another directory but it is really part of my program not part of the infrastructure of Catalina itself. I have to do a build_all when I want to change parameters like cache size and also which drivers are loaded with Flash_Boot but then those settings are used for every program I build after that unless I do another build_all. Maybe the Spin parts of the runtime (at least the parts you need to customize for each application) should be part of the application source code directory and be built by the application makefile so it is more clear that they are actually part of the application not part of the compiler infrastructure.
I think the problem I have with the current approach is that the target stuff is off in another directory but it is really part of my program not part of the infrastructure of Catalina itself.
Aha! This is where we differ - in my view most plugins are not part of your program at all. They are part of the underlying "enabling" infrastructure mandated by the ANSI C standard. This is most obvious when you program your Catalina executable into FLASH. You can then execute the same program but change the output (TV, VGA or PC termial emulator), the input (local keyboard or PC keyboard), the cache size (1k, 2k, 3k, 8k), the Floating point cogs allocated (i.e. one cog or two), and various other things such as the clock source (internal or external) etc etc.
In my view, such plugins are best loaded from a suitably configured target. Why insist that C programmers mess about with these things just because they are programming on the Propeller, when they don't have to do so when programming on any other platform?
But then there are other plugins that are more closely related to the application - such as the plugin in the "custom" folder that flashes a LED. These plugins can be programmed in PASM, and loaded from your C program when you need them.
I think this represents the "best of both worlds".
I agree with you to some extent. Certainly I wouldn't want the plugin code itself to be in my application directory. I think the configuration information about which plugins are in use should be with the application though. It probably shouldn't be in the main application C code but it should be part of the build process for the application. If I chose to use VGA and PS2 for my HMI in one program, that shouldn't affect what gets used as an HMI in some other program. That configuration is program specific and should be part of the program build process not part of a more global "build_all". It of course can draw in modules that are in the target directory so that I don't have to litter my application directory with code that is really part of the infrastructure.
RossH:
I have been interested in Catalina for some time now. Though it is not of much use unless it could be run Prop native, as such could you please port it to the standard Propeller based boards (Demo/Proto Board, Hydra, etc...)? To use some of standard interface for access to mass storage devices would help, so that people may use what ever mass storage device they prefer to work with. It is verry limiting to only have SD and the like, especially once you add a compiler.
In my view, such plugins are best loaded from a suitably configured target. Why insist that C programmers mess about with these things just because they are programming on the Propeller, when they don't have to do so when programming on any other platform?
Name a few products that have a TV driver built in to the "compiler".
I would much rather hook up my own drivers rather than have to wade though all yours.
Of course I'm sure many users do appreciate what you have provided and that's a reasonable value.
RossH:
I have been interested in Catalina for some time now. Though it is not of much use unless it could be run Prop native, as such could you please port it to the standard Propeller based boards (Demo/Proto Board, Hydra, etc...)? To use some of standard interface for access to mass storage devices would help, so that people may use what ever mass storage device they prefer to work with. It is verry limiting to only have SD and the like, especially once you add a compiler.
Hi David,
You should read the Catalina documentation. Catalina runs "out of the box" on any Propeller, including all the boards you mentioned!
As for standard interfaces to mass storage, it's there already - the Catalina SD plugin is simply a sector reader/writer which can easily be modified to use any underlying storage medium. But an SD card is the only mass storage most boards support.
Name a few products that have a TV driver built in to the "compiler".
I would much rather hook up my own drivers rather than have to wade though all yours.
Of course I'm sure many users do appreciate what you have provided and that's a reasonable value.
Hi Jazzed,
It's perfectly reasonable to want to use your own drivers in addition to (or place of) the ones I provide - and with Catalina you can do so (as Dr_A's cogjects and various Catalina demos show). It's just not particularly easy to take an arbitrary object out of the OBEX and insert it into a Catalina program - this is because there is no standard interface to these objects - most people seem to "roll their own" - and they generally also make the assumption (often implicitly!) that their code will only ever be called from SPIN.
Catalina tries to provide a standard interface to drivers with it's plugin approach, and if you adopt that approach from the start then everything is relatively simple. But retrofitting existing drivers that do not do so can still be complex, which is why Catalina provides a few basic ones to get you started.
The targets and plugins provided with Catalina are specifically intended to be sufficient to take any ANSI compliant C program off the net and run it on any Propeller (provided it will fit, of course!). But beyond that, you're on your own.
As for the drivers being part of the program (or part of the compiler) - they're not. They're part of the target, which is neither part of your C program, nor part of the Catalina compiler - it is simply something that is "bundled" with your program to allow your program to run on a particular Propeller platform. As I mentioned earlier, this is most clearly demonstrated by programs that execute from FLASH - there is actually no target (or plugins, or drivers) stored in Flash at all - one must be provided at boot-time (either loaded serially, or from SD card, or from EEPROM).
Perhaps all this would be more evident if I still maintained a separate target package for each Propeller platform - but this seemed silly since most of them were very similar - so I bundled all the standard ones into a common target package - but even in the standard distribution of Catalina there are actually two target packages provided - the common one is called target, but there is another one called custom which is provided specifically to show how to create your own, and how to populate it with your own plugins. If you want to add your own video driver to Catalina for your XYZ board, that's where you are intended to start.
On most computers, all the drivers you will ever need are provided by the Operating System - but there is no general purpose O/S for the Propeller. In its absence, Catalina has to provide all the basic supporting infrastructure for your program - but the Catalina compiler does not actually contribute to this process at all (it simply converts your C code to PASM code). It is the Catalina linker and the various loaders that do the job normally done by the O/S - i.e. to get your program loaded into memory and ready to execute, along with the environment it needs to execute correctly.
I can see I still have a lot of documentation work to do if these key concepts are not getting through!
I can see I still have a lot of documentation work to do if these key concepts are not getting through!.
I understand your concepts but it just isn't the way I expect tools for embedded systems to work. This approach makes sense on a workstation class machine running a real operating system but on an embedded platform you're usually severely resource constrained and need to exercise a lot more control over what gets included in your runtime environment. Also, as I've said before, I find it awkward to have to go to the utilities directory and run build_all with the options I need for a particular project. I'd rather configure those options as part of the build process for my application. That way, if I am working on several applications that need different options each can have its own configuration rather than relying on global settings in the utilities directory.
Anyway, I understand how Catalina works well enough that I can get around these problems. Also, I appreciate all of the effort you put into this and I realize that there are different opinions on how this should work.
I understand your concepts but it just isn't the way I expect tools for embedded systems to work. This approach makes sense on a workstation class machine running a real operating system but on an embedded platform you're usually severely resource constrained and need to exercise a lot more control over what gets included in your runtime environment. Also, as I've said before, I find it awkward to have to go to the utilities directory and run build_all with the options I need for a particular project. I'd rather configure those options as part of the build process for my application. That way, if I am working on several applications that need different options each can have its own configuration rather than relying on global settings in the utilities directory.
Anyway, I understand how Catalina works well enough that I can get around these problems. Also, I appreciate all of the effort you put into this and I realize that there are different opinions on how this should work.
David
Hi David,
It's only since the inclusion of the cache options that you now have to rebuild the utilities folder to match the program being loaded. Prior to that, you only ever needed to build this folder once for each platform, and could then forget about it.
I agree this is not optimal, but I'm not entirely sure what to do about it yet. Annoyingly, the problem arises mainly because I made a design decision to only start the caching driver once during the entire program load and initialization process (no matter how you are loading the program - serially, from EEPROM, from SDCard or from FLASH). This limitation is necessary to accommodate SDRAM boards, with their need to constantly refresh RAM to avoid losing the contents - but in hindsight it seems I have ended up making others suffer because of a design decision based on a board that may never even see Catalina ported to it!
Yeah, I noticed that things changed with this release. With earlier releases I did the build_all once and never had to worry about it again. I guess it's not a big deal now that I understand how it works. It's just a bit surprising.
On another topic, how much hub memory is available to my program? I understand that if I setup a 4K cache that takes 4K away from my application. However, the stack and locals are also in hub memory. Do you have a good rule of thumb about how to estimate stack space requirements? At the moment my PASM version of the xbasic VM can only execute code out of hub memory and I'd like to allocate as much space to it as possible.
Then, after hub execution is working well, I'd like to allow xbasic code to run from external memory. This presents an interesting question. How can I get my xbasic VM to share access to external memory with a Catalina program? Is there any way to handle that?
Thank you RossH.
As for mass storage, any one can add other devices to most of the existing boards, and personally I do not like SD (I prefer CF as it is almost pATA).
but in hindsight it seems I have ended up making others suffer because of a design decision based on a board that may never even see Catalina ported to it!
Comments
That is a bit odd. One possibility - if you just said "payload Flash_Boot" without the -e switch, you didn't actually program it into EEPROM. So on reboot you may be using an old version (perhaps one without the Hub Flash loader fix?).
Ross.
Yes, that's what I did. I left out the -e switch. I copied my command line from the C3 tutorial you wrote in an earlier message but failed to notice that it was just restarting the program in flash not programming the EEPROM. Thanks for pointing that out!
Good. So is everything now working correctly? Are you still having problems programming the Flash?
Ross.
It seems to be working now although I still sometimes get errors programming the flash. It always seems to stop at the same point too. I'm sure I haven't erased the flash on my C3 enough times that it should be starting to fail. I'm pretty sure you can do at least 100k erase cycles and I didn't do anywhere near that many. Also, sometimes when it starts up it fails to read the SD card. It seems like maybe the SD card mount failed.
I don't know if this could also be causing the SD card failure. I haven't had any instances of that on my C3 since I modified the SD card driver initialization code (which was in release 3.0).
I wonder if possibly the two issues could both have the same underlying cause - maybe there is a timing problem on the SPI bus selection - I could also try adding a configurable delay to that code to see if it helps make it more reliable. Again, this might take me a while - especially as I don't have any spare longs in the C3 XMM kernel!
Tonight I'll package your xbasic program up into an easily installable form (i.e. one that doesn't need Catalina installed) so that some other C3 users can try it out - having a wider sample of C3's might help identify if what you are seeing is just an individual hardware problem on one C3.
Ross.
1) after erasing a block, read it, and if you get any non $FF values, goto 1
2) after programming a byte/page
2a) read it back, if not the value you want, reprogram it without erasing it - try this up to 10 times
2b) mark that page bad in a "bad block map"
Now theoretically, once you have all the pages in a sector (4k/32k/64k erasable sector) marked as bad, or one marked as bad rest unused, you could try erasing it, and removing it from the bad block map
Unfortunately for VM, supporting a bad block map means a second-level address translation on flash addresses.
I've heard of people extending the "100k" cycle chips to millions of cycles by using a similar program/check etc approach as I've outlined above.
I'm curious as to why you're playing with plugins. Have you abandoned your cogjects project? I like the idea of loading the driver COGs from the C code rather than having the target load them before starting the main program. Why did you decide against that?
Thanks Bill. If I have enough space, I'll try implementing 1,2 & 2a. 2b is probably not worth the effort when a replacement unit only costs a few tens of dollars.
Ross.
For example, plugins can be loaded and unloaded from C code quite easily. There is an example in the custom_demo folder. The complex_example.c demo program actually loads the plugin two ways - on startup the plugin is loaded by the SPIN target. The C program then unloads it and reloads it again from C.
It takes two lines of C code to load or unload a plugin at run-time (only one if the plugin registers itself).
Ross.
Hi David,
It would certainly be possible to create a target that just loaded the kernel but no plugins, and then to provide a set of PASM programs intended to be compiled and loaded from C as plugins. This would require a fairly modest amount of work, and is something you could do yourself. In many ways it is quite similar to what Dr_A is doing with his cogjects.
But other than complicating both the program build process and the C startup process, I don't see that it really accomplishes much. Yes, it means you can do everything in PASM and C without ever having to touch a line of SPIN code - but in fact, most people in these forums seem to want exactly the opposite (i.e. they want to make the SPIN part more visible, to make it easier to have SPIN programs called from C or vice-versa).
The current solution is kind of a "best of both worlds" approach - i.e. you can load your plugins either in the SPIN target or in the C program - or both!.
Ross.
I'm assuming that the par and addr parameters to your _coginit function need to point to buffers in hub memory, right? I imagine there isn't any code in _coginit that copies the COG code from external memory to hub memory before executing the coginit instruction. It looks like _coginit will do everything I need to do for getting my xbasic VM working. I guess I can look into making it a plugin later if there is some advantage to that.
Thanks,
David
Yes - plugins cannot (in general) access XMM RAM, and they therefore expect all addresses to be Hub addresses.
Ross.
Very sensible! :-)
Aha! This is where we differ - in my view most plugins are not part of your program at all. They are part of the underlying "enabling" infrastructure mandated by the ANSI C standard. This is most obvious when you program your Catalina executable into FLASH. You can then execute the same program but change the output (TV, VGA or PC termial emulator), the input (local keyboard or PC keyboard), the cache size (1k, 2k, 3k, 8k), the Floating point cogs allocated (i.e. one cog or two), and various other things such as the clock source (internal or external) etc etc.
In my view, such plugins are best loaded from a suitably configured target. Why insist that C programmers mess about with these things just because they are programming on the Propeller, when they don't have to do so when programming on any other platform?
But then there are other plugins that are more closely related to the application - such as the plugin in the "custom" folder that flashes a LED. These plugins can be programmed in PASM, and loaded from your C program when you need them.
I think this represents the "best of both worlds".
Ross.
I have been interested in Catalina for some time now. Though it is not of much use unless it could be run Prop native, as such could you please port it to the standard Propeller based boards (Demo/Proto Board, Hydra, etc...)? To use some of standard interface for access to mass storage devices would help, so that people may use what ever mass storage device they prefer to work with. It is verry limiting to only have SD and the like, especially once you add a compiler.
I would much rather hook up my own drivers rather than have to wade though all yours.
Of course I'm sure many users do appreciate what you have provided and that's a reasonable value.
Hi David,
You should read the Catalina documentation. Catalina runs "out of the box" on any Propeller, including all the boards you mentioned!
As for standard interfaces to mass storage, it's there already - the Catalina SD plugin is simply a sector reader/writer which can easily be modified to use any underlying storage medium. But an SD card is the only mass storage most boards support.
Ross.
Hi Jazzed,
It's perfectly reasonable to want to use your own drivers in addition to (or place of) the ones I provide - and with Catalina you can do so (as Dr_A's cogjects and various Catalina demos show). It's just not particularly easy to take an arbitrary object out of the OBEX and insert it into a Catalina program - this is because there is no standard interface to these objects - most people seem to "roll their own" - and they generally also make the assumption (often implicitly!) that their code will only ever be called from SPIN.
Catalina tries to provide a standard interface to drivers with it's plugin approach, and if you adopt that approach from the start then everything is relatively simple. But retrofitting existing drivers that do not do so can still be complex, which is why Catalina provides a few basic ones to get you started.
The targets and plugins provided with Catalina are specifically intended to be sufficient to take any ANSI compliant C program off the net and run it on any Propeller (provided it will fit, of course!). But beyond that, you're on your own.
As for the drivers being part of the program (or part of the compiler) - they're not. They're part of the target, which is neither part of your C program, nor part of the Catalina compiler - it is simply something that is "bundled" with your program to allow your program to run on a particular Propeller platform. As I mentioned earlier, this is most clearly demonstrated by programs that execute from FLASH - there is actually no target (or plugins, or drivers) stored in Flash at all - one must be provided at boot-time (either loaded serially, or from SD card, or from EEPROM).
Perhaps all this would be more evident if I still maintained a separate target package for each Propeller platform - but this seemed silly since most of them were very similar - so I bundled all the standard ones into a common target package - but even in the standard distribution of Catalina there are actually two target packages provided - the common one is called target, but there is another one called custom which is provided specifically to show how to create your own, and how to populate it with your own plugins. If you want to add your own video driver to Catalina for your XYZ board, that's where you are intended to start.
On most computers, all the drivers you will ever need are provided by the Operating System - but there is no general purpose O/S for the Propeller. In its absence, Catalina has to provide all the basic supporting infrastructure for your program - but the Catalina compiler does not actually contribute to this process at all (it simply converts your C code to PASM code). It is the Catalina linker and the various loaders that do the job normally done by the O/S - i.e. to get your program loaded into memory and ready to execute, along with the environment it needs to execute correctly.
I can see I still have a lot of documentation work to do if these key concepts are not getting through!
Ross.
Anyway, I understand how Catalina works well enough that I can get around these problems. Also, I appreciate all of the effort you put into this and I realize that there are different opinions on how this should work.
David
Hi David,
It's only since the inclusion of the cache options that you now have to rebuild the utilities folder to match the program being loaded. Prior to that, you only ever needed to build this folder once for each platform, and could then forget about it.
I agree this is not optimal, but I'm not entirely sure what to do about it yet. Annoyingly, the problem arises mainly because I made a design decision to only start the caching driver once during the entire program load and initialization process (no matter how you are loading the program - serially, from EEPROM, from SDCard or from FLASH). This limitation is necessary to accommodate SDRAM boards, with their need to constantly refresh RAM to avoid losing the contents - but in hindsight it seems I have ended up making others suffer because of a design decision based on a board that may never even see Catalina ported to it!
Ross.
On another topic, how much hub memory is available to my program? I understand that if I setup a 4K cache that takes 4K away from my application. However, the stack and locals are also in hub memory. Do you have a good rule of thumb about how to estimate stack space requirements? At the moment my PASM version of the xbasic VM can only execute code out of hub memory and I'd like to allocate as much space to it as possible.
Then, after hub execution is working well, I'd like to allow xbasic code to run from external memory. This presents an interesting question. How can I get my xbasic VM to share access to external memory with a Catalina program? Is there any way to handle that?
As for mass storage, any one can add other devices to most of the existing boards, and personally I do not like SD (I prefer CF as it is almost pATA).