From: idg10@cl.cam.ac.uk (I.D. Griffiths)
Subject: Re: RISC-OS apps in modules
Reply-To: idg10@cl.cam.ac.uk (I.D. Griffiths)
Organization: U of Cambridge, England
Date: Mon, 12 Oct 1992 16:17:59 GMT

In article <BuwFpr.Kzy@cantua.canterbury.ac.nz>,
dean@cosc.canterbury.ac.nz (Dean Ashby) writes:
|> There must be someone out there who has experience of writing RISC-OS
|> apps in C, and packaging them as modules using 'cmhg'.

I'm afraid I have...  And it was no fun at all.

|>...  The C release 4
|> manual has a description of the header definition file, and how to use
|> it.  The manual doesn't make any reference to, or offer any advice on
|> writing multi-tasking RISC-OS apps.
|> 
Not entirely surprised.  I would be quite surprised if the RiscOSLib bits and
pieces worked in the context of a module app.  In fact I'm almost certain they
won't, particularly if any bits have been written in C, which they are quite
likely to have been.

The reason for this is that the C compiler stomps all over R12 (aargh!) and so
alternative measures need to be taken to work in a module.  What
actually happens
is cmgh (popular pronunciation: "see-munge") provides 'veneer' code,
which stuffs
two relocation pointers at the bottom of the supervisor stack. 
(nyurgh!) I think
one is the address of the module code, and the other of the workspace of the
current instantiation, or at least a derivative thereof (there seems to be some
global magic number like 536 by which these are offset).

Apart from being utterly horrible, the problem with this is that context
switches
don't tend to work unless they decide to preserve the two words at the
very bottom
of the stack, which isn't necessarily what you would think of doing. 
This is why
*logon from within a task window under NFS causes the machine to hang.  (yup!
NFS is written in C, even some of the low level bits...)  So basically if two
tasks written in C are running at once, the machine will hang.  Obviously this
only applies to SVC mode C, since user mode apps obviously seem to work.

|> I've successfully created applications in modules to do real simple stuff,
|> mainly just to test that I've got the header set up okay.  I've trapped
|> service call 11, and dealt with it using the code supplied in the manual
|> and on the examples disk.  What other things have to be set up before
|> calling Wimp_Initialise?  Currently when I call it, it causes an internal
|> error at &38?????  Note, I'm not linking with RISC-OSLib, but calling
|> the SWI directly using _kernel_swi.

Oh.. oops, maybe I should read before I write.  Still, I think the above
paragraph may be useful to some -it came as a revalation to me.  Caused me to
not wish to use the compiler apart from anything else.

The only approach I can suggest is writing your own assembler routines to call
the swis, which stack these two pointers before calling Wimp_Polll. 
Quite why it
falls over at Wimp_Initialise though I don't know, but it could be that
kernle_swi is not used to being called in SVC mode, since the compiler
prodecues its code
somewhat differently in that mode, although there's no good reason it shouldn't
work.

|>  Before I resort to disassembling
|> !Edit from rom, have you got any ideas on what I'm missing?
You're missing the fact that !Edit runs as a normal application and not a
module application...  Although maybe it doesn't, it's hard to tell
since I think
the task manager only uses memory allocation to decide (i.e. 0k of app
space means
it's a module task...).  I don't know precisely what edit does, although it is
quite likely to have some assembler patching...


|>  Any other 
|> tips for things to look out for would be appreciated.
|>
Use assembler.

(Thus speaks someone who has possibly had too much to do with CC this
summer...)
 

Ian