[comp.sys.mac.programmer] Option Key and Amanda's Solutions

pete@titan.rice.edu (Pete Keleher) (11/30/89)

The solutions presented by <amanda.intercon.com> were exactly what I was asking
for. Unfortunately, I don't have IM V (got I-IV, but...). I asked a friend for
the parameters and wrote the following code in LSC v3. I got an infinite cycle
of Odd Address errors as soon as the NSetTrapAddress was invoked. A breakpoint
placed at my trap routine seems not to have been encounted. I would have sent
mail to Amanda directly asking for further advice, but rice.edu doesn't seem
to be able to find your machine. 

Opinions, chuckles, guffaws, kudos for the Central-Division-leading Cleveland
Browns welcome:

 ..
#include	<pascal.h>
 ..
long		keyTransAddr;
 ..
pascal long
keyTransHeadPatch(transData, theKeyCode, myState)
char	*transData;
int	theKeyCode;
long	*myState;
{
	register int	option_mask = theKeyCode & optionKey;
	register int	control_mask = theKeyCode & controlKey;
	
	theKeyCode &= ~(optionKey | controlKey);
	theKeyCode |= (option_mask << 1) | (control_mask >> 1);
	return(CallPascalL(transData, theKeyCode, myState, keyTransAddr));
}
 ..
Initialize all routines
 ..
	keyTransAddr = NGetTrapAddress((int)0xac93,ToolTrap);
BOOM->	NSetTrapAddress(keyTransHeadPatch,(int)0xac93,ToolTrap);
	if (NGetTrapAddress((int)0xac93,ToolTrap) != (long)keyTransHeadPatch)
	{
		SysBeep(1);
		Debugger();
	}

--

===========================================================================
Pete Keleher						pete@titan.rice.edu

Rice University knows nuttin about what I say, or what I do ...
===========================================================================

oster@dewey.soe.berkeley.edu (David Phillip Oster) (11/30/89)

Pete's patch of KeyTrans is incorrect because it references global
variables without saving and restoring A5.  It crashes early because the
debugger calls KeyTrans(), A5 is not what the application expects, and it
does a CallPascal of a bogus address.

Do not use THINK C's SetUpA5 and restoreA5, they are not safe in a
multfinder environment.  You can make a safe SetUpA5, RestoreA5 pair by
cloning the file SetUpA4.h and replacing all occurences of A4 with A5.
Remember to do a RememberA5() before you patch the trap.

> The mac is a detour in the inevitable march of mediocre computers.
> drs@bnlux0.bnl.gov (David R. Stampf)
--- David Phillip Oster          -master of the ad hoc odd hack. 
Arpa: oster@dewey.soe.berkeley.edu 
Uucp: {uwvax,decvax}!ucbvax!oster%dewey.soe.berkeley.edu 

pete@titan.rice.edu (Pete Keleher) (12/01/89)

Point about A5 well taken. However, the a5 routines (as I am using them) don't
seem to make the difference. So there were at least two major problems, not 
one. To test this out, I build an application and ran it under the uni-finder,
getting exactly the same results. Are my transKey parameters wrong? I used
LSC's CallPascalL and patched TickCount() and everything worked fine.

Current code:

static
__GetA5()
{
	asm {
		bsr.s	@1
		dc.l	0			;  store A5 here
@1		move.l	(sp)+,a1
	}
}


#define pRememberA5()	__GetA5(); asm { move.l A5,(a1) }
#define pRememberA0()	__GetA5(); asm { move.l a0,(a1) }

#define pSetUpA5()		asm { move.l A5,-(sp) } __GetA5(); asm { move.l (a1),A5 }
#define pRestoreA5()		asm { move.l (sp)+,A5 }

....
....

	pRememberA5();
	keyTransAddr = NGetTrapAddress((int)0xac93,ToolTrap);
	NSetTrapAddress(keyTransHeadPatch,(int)0xac93,ToolTrap);
	if (NGetTrapAddress((int)0xac93,ToolTrap) != (long)keyTransHeadPatch)
	{
		SysBeep(1);
		Debugger();
	}

....
....

pascal long
keyTransHeadPatch(transData, theKeyCode, myState)
char	*transData;
int		theKeyCode;
long	*myState;
{
	int		option_mask;
	int		control_mask;
	long	res;
	
	pSetUpA5();
	option_mask = theKeyCode & optionKey;
	control_mask = theKeyCode & controlKey;
	theKeyCode &= ~(optionKey | controlKey);
	theKeyCode |= (option_mask << 1) | (control_mask >> 1);
	res = CallPascalL(transData, theKeyCode, myState, keyTransAddr);
	
	pRestoreA5();
	return(res);
}

	
--

===========================================================================
Pete Keleher						pete@titan.rice.edu

Rice University knows nuttin about what I say, or what I do ...
===========================================================================

amanda@intercon.com (Amanda Walker) (12/01/89)

Well, we did it all in assembler, so that we wouldn't have to worry about
application globals at all (we stick the old address into a long allocated
with DC.L in the code area).  I'll check to see if I can post the code
(I doubt it has any trade secrets in it :-)).

--
Amanda Walker
InterCon Systems Corporation
amanda@intercon.com