[comp.sys.mac.programmer] Problems installing interrupt handler

nugteren@pttrnl.nl (11/14/90)

Hi,

I have written an interrupt handler in Think C, that catches incoming 
characters from the serial port and manipulates these in the background 
(i.e. invisible to the user). It works fine as an application, but I
am having troubles installing it in the background (memory resident etc.).
I'm new to MacIntosh programming so I would appreciate any help greatly.

The program is written in what I might be an unconventional way 
(and messy too), I'm not sure :

The basic structure of the program is :

_______________________________________________________________________________

ManipulateChars()           	/* this is the real interrupt handler	    */
                             	/* it is called every time the serial driver*/
				/* receives three characters	       	    */
{
	SaveRegisters();    	/* assembly-stub : puts registers on stack  */
	SetUpA5();           	/* Sets upreg A5 for globals		    */ 

	DoYourThingWithChars(); /* main routine : uses incoming characters  */
	StartDriver(Async);  	/* Starts ROM Serial Driver, asynchronously */
                                /* Specifies ManipulateChars() as	    */
				/* completion-routine			    */
	RestoreA5();            
	RestoreRegisters();     /* Cleans up registers			    */
} 

main()				/* main() is only called once. 		    */
{
	InitialiseSerPort();	/* set's baud rate, parity etc.		    */
	StartDriver(Async);   	/* Same function as above		    */
	while(1){}              /* Keeps program resident. It's got to go.  */
}
_______________________________________________________________________________

The function main() is only executed once. It initialises the serial port,
sets baudrate etc.. 
Then StartDriver() opens ROM Serial Driver and starts it reading 
characters asynchronously. It specifies ManipulateChars() as completion 
routine, which is the actual interrupt handler. After this, the program is
gets caught in a closed loop (which I put there to stop the Mac from leaving
the program and releasing the memory). 

When a certain amount of characters has been received, the serial driver 
generates an interrupt and causes a jump to the completion routine 
ManipulateChars().

The program, when compiled as an application, works fine. Now, obviously ,I have
to get rid of that closed loop, so the Mac can exit main() and get on with
life. How can I get the Mac to leave main() without releasing the heap space?

Also, the program must be combined with an INIT somehow, because it has to
startup and install itself in the background in startup time. Should I convert
the whole program to an INIT or create a loader INIT that loads the code in
separately ?
How do I go about this with Think C?
The program uses global variables (but not QuickDraw).
I gather this may be somewhat of a problem in an INIT. Or does Think C take 
care of this problem by using register A4 to address globals ?

The program should stay resident indefinitely and not be reinitialised.
Do I have to load it into the system heap? How do I do this with Think C ?

If someone actually made it all the way through this letter, and can answer
one/more/all of the above questions, I would be grateful indeed.

Thanks in advance,

Nils Nugteren.

Chris.Gehlker@p12.f56.n114.z1.fidonet.org (Chris Gehlker) (11/20/90)

In a message
> From: nugteren@pttrnl.nl

Nils Nugteren asks:

> I have written an interrupt handler in Think C, that catches incoming 
> characters from the serial port and manipulates these in the background 
> (i.e. invisible to the user). It works fine as an application, but I
> am having troubles installing it in the background (memory resident etc.).
> I'm new to MacIntosh programming so I would appreciate any help greatly.

Nils, my serial drivers patch themselves into the level 2 dispand reprogram the SCC completely.  What you are trying to do is somewhat
different so take these suggestions with a grain of salt.

> Also, the program must be combined with an INIT somehow, because it has to
> startup and install itself in the background in startup time. Should I 
convert
> the whole program to an INIT or create a loader INIT that loads the code in
> separately ?

Use an INIT that loads the driver and then calls DetachResource() on it
so that the driver won't get purged by the INIT31 mechanism.  The part
of the INIT that does the ShowIcon stuff can go away. Also set the
SysHeap and Locked bits in the driver.

> The program uses global variables (but not QuickDraw).
> I gather this may be somewhat of a problem in an INIT. Or does Think C take
> care of this problem by using register A4 to address globals ?

Using A4 works for me.

> The program should stay resident indefinitely and not be reinitialised.
> Do I have to load it into the system heap? How do I do this with Think C ?

For some reason THINK C gives you a pop-up menu to set the resource bits
for code resources but not for drivers. What I do is compile my cdev to
disk. Then I compile the INIT that opens the driver and merge like it
into the cdev.  Then I compile my driver into a file of type rsrc with
creator RSED. When I double click this file it launches ResEdit and I have
the ResEdit menu customized to open my cdev-INIT from the Open Special
Menu.  I set both the DRVR and the DATA resources to SysHeap and Locked
and paste them into the INIT-cdev.  Then I just shove the DRVR-INIT-cdev
file into the system folder and reboot.

 

--  
Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!56.12!Chris.Gehlker
Internet: Chris.Gehlker@p12.f56.n114.z1.fidonet.org