Help with coding
Yannis Irvine (1965) 9 posts |
Is this the right forum to request help with RISC OS programming? If not, I would be grateful for a link to a more appropriate forum. If yes, here is my query: |
Chris Hall (132) 3564 posts |
Have you tried *LOAD ing it into an area of memory reserved within the module of sufficient size and then calling the code? |
Yannis Irvine (1965) 9 posts |
Wouldn’t the code then need to conform to Module code requirements, e.g. calling X SWIs. A normal Absolute file would call non-X SWIs, and end by calling OS_Exit rather than returning into my code, wouldn’t it? |
Rick Murray (539) 13861 posts |
Yes – that’s right. But more importantly, a module runs in SVC mode so you MUST preserve R14 around calls to SWIs. A normal user mode application won’t think to do that (as USR R14 != SVC R14). However… Just an idea, until somebody posts the really simple/easy way to do this ;-) you might be able to get something if you stack something for R14 (not sure if it should be SVC or USR stack, I’d try SVC first) and then switch to USR mode. The stacked R14 should point to your tidyup code which will (hopefully!) be called upon OS_Exit. Can’t hurt to look in the sources to see how |
Theo Markettos (89) 919 posts |
When you say ‘run’, what do you mean? If you load in the code into &8000 and *Go it, you’ll wipe out the current task. If you don’t want to do that, ie you want to start a new task, look at Wimp_StartTask. But that will need to do multitasking itself, unless it’s short or run in a taskwindow. What things like C compilers do when they chain other programs is to move the current task away from &8000 (via MMU-twiddling, I assume), move in their program, run it, and then reinstate the current task. I’m not sure how to do that exactly. |
Chris Hall (132) 3564 posts |
I, too, am not sure exactly what you are trying to do. What about
where the pathname is a BASIC file containing an ‘OSCLI’ statement loading and running the desired absolute file into some memory space you have reserved. It shouldn’t matter where the space is reserved as addresses in the code will almost certainly be relative. Alternatively write a simple multi-tasking shell in BASIC and do the same. Alternatively examine the absolute file after you load it into your module – if it has been compiled from C then it should start with the first four instructions as branches (BL) or NOPs, followed by SWI OS_Exit. The first three are optional and are for decompress code, zero init So try to see if the code is already decompressed and, if so, replace the SWI"OS_Exit" with a MOV PC,R14 instruction. |
Rick Murray (539) 13861 posts |
Nothing so fancy. Basically all the environment stuff is unlinked (that’s the part people tend to forget). Then the program is copied up in memory, along with workspace of course. Then the stack or whatever is prodded so return to our program will happen when the child exits. Then the child is called. |
nemo (145) 2569 posts |
Getting back to the original question, you are in effect duplicating the behaviour of The crucial point about them is that they ‘enter’ the module – see OS_Module,2. At that point your module becomes the owner of the application slot, and can therefore load an Absolute into it and call it. Job done. |
Yannis Irvine (1965) 9 posts |
Thanks for replies thus far. My original question was a bit brief, as I was not sure whether it was appropriate for the forum. Let me now give a bit more info. I am writing a module (let’s call it BlahMod) that implements a star command (*BlahCmd). I want the handler for the command to be able to launch a program, which is a non-WIMP absolute file (<Blah$Dir>.BlahHelper), such that BlahHelper does its thing and exits (I do not mind if the machine single-tasks for the duration), and control goes back into the command handler, which carries on with its job. The module, I am writing in ARM assembly, and the Helper is also my own code, written in C. What I tried was to pass “<Blah$Dir>.BlahHelper” into XOS_CLI, which resulted in BlahHelper being launched, but control never returning into the BlahCmd handler. My first suspicion was that it was OS_CLI that had called my command handler, so I could not call OS_CLI myself, as it is not re-entrant (according to the PRM). This is when I posted by original question. I can certainly try and load the absolute file into my own memory and call it, and arrange for control to return to me (by replacing the OS_Exit with a return seemed to be the most promising trick), and I can even try switching to USR mode while it’s running. R14 preservation was never an issue, as I already save it on the stack at the beginning of my BlahCmd handler. But will this be sufficient, or will there be further problems with the BlahHelper code using non-X SWIs? And wouldn’t the code also be non-relocatable, and therefore expect to reside at &8000? The OS knows how to launch Absolute programs correctly, but I am loath to try and replicate that functionality; that is why I thought I would get the OS to do it for me, via OS_CLI. @nemo: can you explain you last paragraph, please? |
Chris Hall (132) 3564 posts |
This is where another question comes to mind. Is the absolute file one that you’ve created? Or a general requirement to run any arbitrary absolute file? If you are creating the absolute file, then you can control what SWI calls it makes. Or just test to see whether it works and if it does, fine. If it can be any absolute file then you need to make sure your method is generally applicable – i.e. follows the rules. |
nemo (145) 2569 posts |
BASIC is a useful example. When you type That isn’t what BASIC does of course, as it needs the application slot for its own purposes – the program it is interpreting and its variables of course. BASIC cannot simply take over application space and then, when the BASIC program says Instead, when it receives the If you’re slightly worried about this apparently single-tasking behaviour and how that interacts with the Wimp, the Wimp is merely a trick played on the unsuspecting OS. RISC OS itself is single tasking… it’s the WindowManager which provides a cooperative multitasking layer on top. However, starting applications (note I use the word application, not task, to avoid confusion) is an OS-level activity, hence calls such as OS_Module,2. (A task is an application which the Wimp is making cooperatively multitask) |
nemo (145) 2569 posts |
If by “carry on with its job” you then mean to return from OS_CLI to whoever called you, then you can’t — you may have been called by the previous occupant of the application slot, and they’re gone! If, however, you just mean your code has more to do, then that’s not a problem – when an application (your helper) calls OS_Exit the OS calls the Exit Handler. So what your code needs to do is something like:
Something like that anyway. |
Yannis Irvine (1965) 9 posts |
@Chris: Yes, I write the helper, but in C, so I do not (think I) have control over the SWIs. @nemo: Thanks for all your help. The critical part for me was to realise that you were talking about the “Start code” entry point (PRM 1-209). When I read that part of the PRM, I misunderstood it: I took it that the entry point was only called when a module was ran “as an application”, meaning when its file was ran as if it were Absolute (e.g. by typing its name into the CLI). I did not realise that it could be called on a module already loaded in RMA! Again, I misunderstood OS_Module 2, thinking that R1 points to the filename of the module. Thanks also for pointing out that BASIC was doing something similar to what I wanted to do. |
nemo (145) 2569 posts |
Yeah, I didn’t want to write “start the module” because that could so easily lead to “I have started it – I double clicked it!” confusion. :-)
Hmmm… the purist in me says “no”. I shouldn’t have written step 4. As I’ve mentioned, the WIMP was stuck on afterwards, so ideally we’d pretend it didn’t exist and expect it to work by magic. Omitting Step 4 means the caller of your star command must use BASIC doesn’t call Wimp_SlotSize (oh no it doesn’t * ), it just uses whatever memory is available when it starts – that’s why BASIC applications use OS_ChangeDynamicArea can apparently be used to alter the application slot from RO4.2, but I have never used it (because it’s only available from RO4.2!) and I don’t know how it interacts with the WIMP anyway.
Exactly. Well, mostly. The module doesn’t actually have to be in the RMA, but that’s where the OS puts them. It is possible to put them in a DA if you’re being devious – see OS_Module again. So the module will (probably) be in the RMA, (probably) with workspace in the RMA, and will own the application slot (which it might not use!). Simple! ;-) * Actually BASIC does call Wimp_SlotSize… but only when the program uses the |
nemo (145) 2569 posts |
BTW The reason BASIC etc don’t set the size of the application slot is that in the absence of the WIMP one expects the application slot to contain all the memory of the computer (that will fit) that isn’t in the screen, RMA, DAs, sys heap etc. It’s the WIMP that imposes the fancy trick of limiting the memory in the application slot (via ‘Next’ and *WimpSlot) as part of the BBC Micro sideways ROM -inspired task swapping (even the base address is the same!). Ideally your module would work even with WindowManager RMKilled. BASIC does (unless you do |
Yannis Irvine (1965) 9 posts |
Nemo, thanks again for all the help. I have done plenty of BASIC & C programming of straight apps, but I had never strayed into modules, the RMA, DAs, and all the bits where RO is quite different to, say, Linux. When I finish my truly brilliant and amazing system, in a couple of decades, I will let you chaps know ;-P |