fri0@quads.uchicago.edu (Christian Fritze) (05/02/91)
So I'm writing my first INIT, based on J. Waette's useful example in the UMPG. The first part is a loader which reads patches a trap and loads and locks a code resource for the actual patch. The loader also reads in several snds the patch uses and locks them away. Finally, I store in a handle an array of longs which hold the addresses to the beginnings of each sound header in the block of sounds. By looking for two tags in the code resource, I save 1) the address of the trap I patched so we can jmp to it after executing my patch, and 2) the address to the block of memory that holds the array of longs (the addresses of sound headers). (Whew!) Now the problem. I can run the loader as an app under the Think C debugger and verify that loading, parsing of sound resources and locking goes correctly. However, I get an address error as a result of the SndDoCommand call - if I comment it out, no more crashes. The relevant code is as follows, first loader, then patch: int strcmp ( char * s1, char * s2 ) { while ( *s1 == *s2 && *s2 ) { s1++; s2++; } if ( *s1 == *s2 ) return 1; return 0; } pascal main() { char *moof; Handle foom, arrayHandle, long SndPtrArray[NUM_SNDS] /* ....... */ / * load code for patch */ foom = GetResource('hoov', 128); if (foom == 0) BailOut ( 0L); else { HUnlock ( foom ); /* move hi and lock down */ DetachResource ( foom ); MoveHHi ( foom ); HLock ( foom ); /* Find our signature */ for ( moof = *foom; !strcmp ( moof, "Moof!" ); moof++ ); /* Patch the trap */ trapAddr = * (long *) moof = NGetTrapAddress ( 0x1B2, ToolTrap ); NSetTrapAddress ( StripAddress ( *foom ), 0x1B2, ToolTrap ); /* Now allocate storage for our array, move it hi and lock it down */ arrayHandle = NewHandle ( sizeof ( SndPtrArray ) ); if ( arrayHandle == 0 ) BailOut ( trapAddr ); MoveHHi ( arrayHandle ); HLock ( arrayHandle ); /* Find second tag and write address of storage */ for ( moof = *foom; !strcmp ( moof, "Hoov!" ); moof++ ); * (long *) moof = ( long ) ( StripAddress ( *arrayHandle ) ); /* Load sounds, combine to one handle with HandAndHand(), move it hi and lock down. Then parse snd resources to get addresses of each sound header and store each address as a long in SndPtrArray. Then... Copy array to prearranged storage */ BlockMove ( SndPtrArray, *arrayHandle, sizeof ( SndPtrArray ) ); } } /* Here's the actual patch from the 'hoov' resource we just loaded */ #include <EventMgr.h> #include <SoundMgr.h> pascal Boolean main ( EventRecord *e ) { long * sndArrayPtr; SndChannelPtr myChan; SndCommand theCmd; asm { movem.l a0-a5/D0-D7, -(SP) } asm { bra @done @moof: dc.b 'M', 'o', 'o', 'f', '!' @done: nop } asm { bra @skip @hoov: dc.b 'H', 'o', 'o', 'v', '!' @skip: nop } if ( e->what == keyDown ) { /* Retrieve address to the start of the array in memory */ asm { move.l @hoov, sndArrayPtr } myChan = 0L; SndNewChannel ( &myChan,5,initMono,0L ); theCmd.cmd = bufferCmd; theCmd.param1 = 0; /* Pass a pointer to the first sound header. This is the first element in the array we stored, or the value at the address pointed to by sndArrayPtr */ theCmd.param2 = * (long *)sndArrayPtr; SndDoCommand ( myChan, &theCmd, FALSE ); SndDisposeChannel ( myChan, FALSE ); } asm { movem.l (SP)+, a0-a5/D0-D7 } asm { move.l @moof, a0 unlk a6 jmp (a0) } } I suspect there's something funky with the way I retrieve the address stored @hoov. Interestingly, all the sound code when lifted to the loader and run as an app under the debugger works fine - I get my sound. In that case, I assign sndArrayPtr either as sndArrayPtr = * (long *) moof; or sndArrayPtr = ( StripAddress ( *arrayHandle ) ); Either way works (as expected). So why does it crash when it's part of the patch? Many thanks for any help. I suspect my limited knowledge of assembly language is getting me in trouble. -- Christian E. Fritze | AOL:geneman University of Chicago | fri0@midway.uchicago.edu Molecular Genetics and Cell Biology | "No one ever died of laughing" -M.B. --