Sof loading BASIC
Pages: 1 2
Steve Drain (222) 1620 posts |
I wrote that, but it set me wondering. I have put together a little Utility, SoftBasic, that might let us do what everyone wants. It is probably “dead dodgy”, but in principle works like this:
I have done little more testing than to check that it does not obviously crash anything and does actually load BASIC into new memory. There is plenty of polishing to do. I would be very interested in comments. ;-) |
Steve Drain (222) 1620 posts |
No, it had occurred to me, too, but comes under the ‘polishing’ heading. |
Jon Abbott (1421) 2651 posts |
What are the issues when replacing a soft-loaded BASIC? I’ve seen it mentioned a few times now. |
Martin Avison (27) 1494 posts |
What happens if it is in ROM, as mine is currently? What is the advantage of SoftBasic over just loading BASIC at boot time from the standard place? Just needs one Obey in PreDesk. |
Steve Drain (222) 1620 posts |
I attempted to summerise them here https://www.riscosopen.org/forum/forums/1/topics/16225 |
Steve Drain (222) 1620 posts |
I have thought of that, and as it stands it just does RMLoad without the RMKill and Claim. This is just proof of concept at the moment.
I would like all users to follow that principle, but can a software author rely on it being done? There is pressure to treat the BASIC module like others. If the principle is sound I will do all the polishing and perhaps think of a better name. |
David J. Ruck (33) 1636 posts |
If the user hasn’t put the new BASIC in !Boot and rebooted, this should be caught by an RMEnsure BASIC x.xx in the application’s !Run. This program is a useful for developers to be able to test with a range of different BASIC modules without rebooting. Letting it lose on normal users might be asking for trouble though. |
Martin Avison (27) 1494 posts |
Exactly. I already provide a !System with Organizer with instructions to use the standard !System Merge to install some modules, which checks they need updating first. I could easily include BASIC in there. Many other apps also provide !System or !Boot directories (eg Netsurf and RiscOSM). Any apps dependant on a module version should check it in their !Run file, and try to load if necessary. Should we be confusing users with another approach?
That I can agree with. |
Steve Pampling (1551) 8172 posts |
Oops, and you’re usually so precise. |
Jon Abbott (1421) 2651 posts |
I think you mean here but I’m still none the wiser. What “code” are you referring to in your summarisation? The BASIC Module itself? Or something in AppSpace? I’m possibly misunderstanding as I thought BASIC, being interpreted, stored all it’s references in AppSpace, so the BASIC Module itself isn’t actually directly referenced? I could understand SYS potentially being an issue, but the last version of BASIC I looked at had the code for SYS in AppSpace. |
Steve Drain (222) 1620 posts |
I do, but I have yet to figure out how to reference individual posts. ;-)
I may get this wrong, but here goes. A BASIC program, even tokenised, is a script which is interpreted by a machine code program invoked by *Basic and running inside the BASIC module. This program uses application space for its stack and storing various data – the ‘arguments’ referenced to ARGP and the variables etc in the heap below ‘free space’. The script (BASIC program) is usually stored there as well, at PAGE, but it can be practically anywhere in memory. The script for Alarm, for instance, is in ROM. Once the module code for an instance of a BASIC program is running you cannot change any of it, so it must not be overwritten. This will always be true for any BASIC program started from the ROM module. One started from a RAM module is liable to have its code overwritten when a new version of the module is RMLoaded and the RMA memory is freed for re-allocation. Indeed, depending on sizes, the new module may overwrite the old one. Is that any help? |
Steve Drain (222) 1620 posts |
You should see my posts when first typed and then the corrections I do after posting. That one slipped through. ;-) |
Steve Drain (222) 1620 posts |
Therein lies the problem. I am sure that you do: RMEnsure ThisMod 1.30 RMLoad System:Modules.ThisMod RMEnsure ThisMod 1.30 Error MyProg requires version 1.30 of ThisMod If a user has not done a SysMerge with your !System you will get the error and your program will not run without the necessary module version. This is quite satisfactory for most modules. However, consider this with the BASIC module. A soft-loaded copy has been RMLoaded as a consequence of this check. In simple cases this might not matter, because an identical copy occupies the same memory as the original, but if more than one programmer requests a !System to be SysMerged, and not all carried out by the user, there could be trouble. I think there needs to be a more fundamental method instigated by ROOL. Something that at start-up RMLoads a soft-loaded BASIC module if it exists in !System. Programmers will still provide their !System to be SysMerged, but will only do: RMEnsure ThisMod 1.30 Error MyProg requires version 1.30 of ThisMod Alternatively, there is SoftBasic. ;-) (tongue very much in cheek) |
Steve Drain (222) 1620 posts |
On deeper consideration my brain starts to hurt and this might not really be a problem, but not for the obvious reasons. I cannot be sure. ;-( |
Martin Avison (27) 1494 posts |
@Steve: Hmm, yes, I see the possible problem if an app does an RMEnsure then Load of BASIC. I will look at SoftBasic in a new light… |
Stuart Painting (5389) 714 posts |
The timestamp on a message (above the poster’s name) is a clickable link1. Position the pointer on the link, click Menu and choose “Copy link location”. On NetSurf you would choose “Object > Link > Save”. 1 This only works if you’re in the thread itself. If you’re looking at an entry in “Recent posts” there won’t be a direct link. |
Jeffrey Lee (213) 6048 posts |
I believe SoftBasic is indeed “dead dodgy”. The problem is that when a BASIC program is running, some of the values in the ARM registers and the user mode stack will point to arbitrary locations within the BASIC module. For something like a task window, where the program could be suspended while it’s at almost any point in the interpreter, this would mean you’re very limited in terms of the changes you can make to the BASIC binary without the risk of something breaking. There may also be references/dependencies on the module’s RMA workspace (currently none), ResourceFS files (softloaded BASIC registers & deregisters files on init/shutdown), etc. A much more sane solution would be to ‘orphan’ the current BASIC module. Allow current programs to continue to use it, but make it inaccessible to any new programs that try to start. The same tactic could be used for some other problem areas, like CLib. |
Martin Avison (27) 1494 posts |
@Jeffrey: I believe that the purpose of SoftBasic is to leave any current module code unchanged, even if it not still on the module chain. Also, if there is a way to obtain the CAO values for running tasks, then if none were the current BASIC module presumably it could be changed with no harm done? |
Jeffrey Lee (213) 6048 posts |
Yes, my mistake, I didn’t look close enough at the initial post. |
Alan Adams (2486) 1149 posts |
So the BASIC interpreter code is running from the area of memory that was initially RMloaded, and which has been protected by allocating it to SoftBasic, which makes no use of it. Thus the original BASIC is self-contained and doesn’t know anything has changed. Neat. I just have a slight niggle in my mind though – does EVAL do anything unusual here? (I remember taking Viewsheet apart some years ago [although I may be thinking of the different rom-based spreadsheet on the BBC] – because it had a bug which reduced the maximum equation count from the intended 63 to 31, as it initialised the usage count to space characters later. In the progess I discovered that it evaluated equations by calling the BASIC routine for EVAL by its address in ROM. Crafty, no?) |
Martin Avison (27) 1494 posts |
Building on Steve’s SoftBasic idea, it would be really neat if RMLoad had a small list of modules that should not be re-loaded in RAM (eg BASIC, BASIC64, BASICVFP, CLib and ?). If in the list, then RMLoad would protect the old RAM like SoftBasic does. This would enable the normal RMEnsure/Load/Ensure sequence to be used safely … and I think it could be implemented on old machines by loading at boot a small module with e.g. an RMEnsureX command, which also set an alias to run it rather than the normal one. Could this solve some ongoing issues using some newer modules on older machines? |
Steve Pampling (1551) 8172 posts |
:) |
Rick Murray (539) 13851 posts |
Plus change the way things are done going forwards. I discovered the reason why so many programs RMEnsure CLib 5.17 (or something) and then immediately RMEnsure a later version…it is described in the C manual…but there’s so much wrong with that explanation. It would be much better to RMEnsure the version you actually need and error out if it is not present. Under no circumstances (since about 1995) has it been a good idea to blindly try to RMLoad a later CLib. That “instruction” needs quashed. Just don’t do it.
That would work going forwards (it’s a good idea), but what about going back? It doesn’t look like Module_PreInit can be used to examine and reject a module being loaded, so…. maybe intercept CLIV to look for “rmload” and then try to vet what is being loaded? |
Rick Murray (539) 13851 posts |
Hmm, possible (rare) memory leak? The module handler, Load_Module function, reads catalogue info to perform some basic vetting. If we’re all good, it will claim an RMA chunk in which to load the module into. If that fails, it will go to modfailxit to abort the process. |
Jon Abbott (1421) 2651 posts |
Thanks for the explanation Jeffrey, Task windows are the crux of the matter. Everything else will be at the return from the SYS handler and I’m pretty sure that can handle BASIC being changed mid flow. |
Pages: 1 2