[comp.sys.apple2] Orca/C/M...Ack!

2hnemarrow@kuhub.cc.ukans.edu (02/17/91)

Yites... Excuse me, but I was just sitting here and wondering (and wondering
here, sitting ) if anyone would happen to have an example of an Orca/M
subroutine called from Orca/C.  We are trying to use code already written in ML
(to load and display pictures) but we can't seem to figure out how to set up
the ML subroutines.  I tried following the example and saving and retrieving
the DP pointers, but we keep getting an error # 53 (which has something to do
with the tools, I can't remember exactly right now.)  Anway, I think the error
relates to the only variable we're trying to pass (MyID, i.e., the programs ID)
for setting up space to load the picture.

So after all that, I guess the question is how to pass parameters between the
languages.  The manual says to put the variable on the stack from C (which we
did) but the example has the variable equated right after the START of the ML
subroutine.  Which doesn't seem to work with us.

mock@iris.ucdavis.edu (Kenrick J. Mock) (02/18/91)

Here is an easy way to mix Orca C and Orca M together.  Here is the general
structure of your Orca/M file:

************************************************************************
         keep  myprog
MYPROG   start
* init stuff.  Set data/prog bank
         phk
         plb
* maybe save processor status as well and disable interrupts if necessary
         php
         sei
* Your program goes here
         lda somevar
         ...
         WDM        ; Your code goes here, do something with somevar
         ...
* Quit code.  Load a #0 as the returning value
         plp
         lda   #0
         rtl
SOMEVAR  entry      ; Declare SOMEVAR as external entry point
         dc H'00 00'
         end
************************************************************************

From the shell, ASML MYPROG.

Here is what the C program can look like:

/********************************************************************/
#pragma keep "CPROG"
extern void MYPROG(void);       /* Declare external parameters */
extern void SOMEVAR(void);
main()
 {
  word *asmparm;

  asmparm=(word *) SOMEVAR;
  *asmparm=0x0101;              /* your parameter */
  MYPROG();                     /* Call the assembly procedure */
 }
/********************************************************************/
Compile CPROG.CC.  Then do a "link cprog myprog keep=cprog" and the 
resulting EXE file will execute your Orca/M code.  This method is a little
simpler than passing in parameters through the stack, although it is not
as clean.  Opponents of global variables are certain not to like it...
In any case, I hope it helps.

Ken

P.S. Play Columns!  Oh, also, if all you want to do is load and
display a $C1 picture, you can load it directly to $E12000 and the
picture will load right to the SHR screen.

------------------------------------------------------------------------------
    "When you make your mark in the world, watch out for guys with erasers."
      - Wall Street Journal.
GEnie : K.MOCK        Net : mock@iris.ucdavis.edu, mock@alderon.lanl.gov

ericmcg@pnet91.cts.com (Eric Mcgillicuddy) (02/19/91)

>To: 2hnemarrow@kuhub.cc.ukans.edu

The example given is wrong in one of two ways (depending on what you need
done). Apparently the copy editor missed the fact that the Direct register was
pushed on the stack after the stack diagram was drawn. Increase the EQU's by
2 :
 
i       equ     12
ch      equ     10
z       equ     6

This allows you to continue with the examples as given. I don't know how
often this error is repeated, better keep a couple of fingers free for couning
the bytes on the stack.  :)

If you do not need any direct page locations I would suggest that you leave
the EQU's alone and access your variables with  lda  <varname>,s :

myid    equ     6
......
        lda     myid,s
......

This should access the correct variable and should solve your problem also.

On a related note...... Does anyone know if the System Loader calls the Memory
Manager in a non-standard way?  My ViM projects patches NewHandle and a half
dozen other calls, it works great within an application, but nukes the Loader
when a new app is launched. Perhaps the loader uses the alternate dispatcher
($e10008 ?) with the extra return address on the stack. 

I am wondering if the Loader might JSL directly to &NewHandle instead of
following Apple's guidelines. Any ideas on this?

And any ideas how I could use GSbug to follow the boot process so I can watch
the stack and variables change?


UUCP: bkj386!pnet91!ericmcg
INET: ericmcg@pnet91.cts.com

toddpw@nntp-server.caltech.edu (Todd P. Whitesel) (02/19/91)

ericmcg@pnet91.cts.com (Eric Mcgillicuddy) writes:

>On a related note...... Does anyone know if the System Loader calls the Memory
>Manager in a non-standard way?  My ViM projects patches NewHandle and a half
>dozen other calls, it works great within an application, but nukes the Loader
>when a new app is launched. Perhaps the loader uses the alternate dispatcher
>($e10008 ?) with the extra return address on the stack. 

Well, if you're installing it with SetTSPtr and SetDefaultTPT (encouraged
if your installer runs at boot time) then you should always expect two RTS's
on the stack (as normal tool functions are required to).

If you're patching the vectors directly then I suggest you either patch them
both or use the method in the previous paragraph to play it safe.

Todd Whitesel
toddpw @ tybalt.caltech.edu

ericmcg@pnet91.cts.com (Eric Mcgillicuddy) (02/21/91)

>Well, if you're installing it with SetTSPtr and SetDefaultTPT (encouraged
>if your installer runs at boot time) then you should always expect two RTS's
>on the stack (as normal tool functions are required to).
>
>Todd Whitesel
>toddpw @ tybalt.caltech.edu

Volume 3 says that applications should never make this call. An Init is an
application, ending with RTL, therefore an Init should never make
SetDefaultTPT. Or so my reasoning went at the time. Regardless ViM works fine
without it and I require the option to restore the old FPT pointer if the user
requests it (for compatibility reasons), this should only occur in the Finder
and should not be dangerous.

The two RTLs on the stack were picked up using GSbug (why two?) and it just a
matter of updating a few global EQUs to get the correct parameters. NewHandle
was a special case, the other five patches did their stuff before passing
control to the original code, NewHandle did its stuff after (Basically adding
the Handle to the LRU queue). What I had to do was extract the original return
address from the stack, save it, change it to return to my routine, make the
call and then put the original return back. I made two mistakes. First I
forgot that the return from original NewHandle call would not leave any return
addresses on the stack (having returned to what it thought had called it), so
I ended up overwriting the Handle I wanted saved and returned with the
original return address. Secondly, I save the P and B registers before doing
my stuff, but I confused the size of the B register with the D register and
pulled an extra byte from the stack (it's a long story). So not only did I
eradicate the Handle that the call was expected to return, I corrupted the
address that was to be returned to!!!   Ever have one of those month's?

Anyhow, that is all in the past. I have now have it installed in my system and
it seems to mostly work. The only program that I have that does not work with
it is Proterm, I suspect that this is due to the way it grabs the GS's memory.
I can get Proterm to operate correctly by first running Mousewrite (weird but
true). All of my GS specific programs work with it active, however I still get
Out of Memory with Halls of Montezuma and I doubt any of the others take real
advantage of the concept. In order for a memory segment to be swapped out, it
must be position Independent, Unlocked and not in Bank 0. I think very few
segments meet all three criterio.

I will be working on a demo, something that just creates a few megs of memory
segments and accesses them randomly, do demonstrate that a programmer can
create a very large program without having to worry about overlays or the
Segment Loader overhead. Assuming that they follow rules at any rate.

There is one problem in that after several applications have been run, it will
drop into the monitor (or GSbug in my case). I think that this is due to too
small a workspace for the LRU queue. I also want to replace the cheesy
Applesoft installation program.

Wish I knew what the problem with Proterm was.

UUCP: bkj386!pnet91!ericmcg
INET: ericmcg@pnet91.cts.com