From: pottier@clipper.ens.fr (Francois Pottier) Subject: csmp-digest-v3-054 Date: Wed, 7 Sep 1994 18:19:19 +0200 (MET DST) C.S.M.P. Digest Wed, 07 Sep 94 Volume 3 : Issue 54 Today's Topics: How to use AESuspendTheCurrentEvent? Learning Macintosh Programming Should function order be conserved? (CW vs. GestaltValue) Sound Manager headaches (again) Stopping a 'snd ' resource dead [Q] What does "_Xxxxx ,Sys,Immed" mean? jGNE from an INIT The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier (pottier@clipper.ens.fr). The digest is a collection of article threads from the internet newsgroup comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi- regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. If you don't have access to news, you may still be able to post messages to the group by using a mail server like anon.penet.fi (mail help@anon.penet.fi for more information). Each issue of the digest contains one or more sets of articles (called threads), with each set corresponding to a 'discussion' of a particular subject. The articles are not edited; all articles included in this digest are in their original posted form (as received by our news server at nef.ens.fr). Article threads are not added to the digest until the last article added to the thread is at least two weeks old (this is to ensure that the thread is dead before adding it to the digest). Article threads that consist of only one message are generally not included in the digest. The digest is officially distributed by two means, by email and ftp. If you want to receive the digest by mail, send email to listserv@ens.fr with no subject and one of the following commands as body: help Sends you a summary of commands subscribe csmp-digest Your Name Adds you to the mailing list signoff csmp-digest Removes you from the list Once you have subscribed, you will automatically receive each new issue as it is created. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest. Questions related to the ftp site should be directed to scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP digest are available there. Also, the digests are available to WAIS users. To search back issues with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html. ------------------------------------------------------- >From phaedrus@chinook.halcyon.com (Mark Phaedrus) Subject: How to use AESuspendTheCurrentEvent? Date: 19 Aug 1994 21:44:57 GMT Organization: NWNEXUS, Inc. - Making Internet Easy Could someone please post some brief sample code showing the correct use of AESuspendTheCurrentEvent and AEResumeTheCurrentEvent? Basically, this is what I'm doing right now: AppleEvent *pendingEvent,*pendingReply; OSErr err; pascal OSErr MyEventHandler(AppleEvent *messagein, AppleEvent *reply, long refcon) { /* make sure we're allowed to put up a window */ if (noErr != (err = AEInteractWithUser(kMyTimeoutTicks,nil,nil))) return err; /* assorted code to display the window deleted */ /* keep track of these events for later */ pendingEvent = messagein; pendingReply = reply; /* we'll wait for the user to do something that triggers a response */ if (noErr != (err = AESuspendTheCurrentEvent(messagein))) return err; return noErr; } pascal OSErr MyEventCompletion(AppleEvent *messagein,AppleEvent *reply, long refcon) { AEPutParamPtr(reply,keyAEResult,typeChar,(Ptr)myStuff,strlen(myStuff)); return noErr; } void CodeCalledWhenReadyToFinish(void) { err = AEResumeTheCurrentEvent(pendingEvent,pendingReply,MyEventCompletion, 0); } When the event handler is called, AESuspendTheCurrentEvent returns noErr, and the event is apparently suspended correctly; at least, the caller never gets a reply, even though the event handler returns. The problem is that the event and reply records seem to be getting disposed immediately; pendingEvent and pendingReply are pointing at garbage when CodeCalledWhenReadyToFinish is called, and as a result AEResumeTheCurrentEvent fails miserably. Any help you can give is gratefully appreciated... -- \o\ If you're interested in books/stories with transformation \o\ \o\themes, or in furry/anthropomorphic art, email me, or anonymous-\o\ \o\ftp to ftp.halcyon.com and check the /local/phaedrus directory. \o\ \o\ Web users: Now try http://www.halcyon.com/phaedrus/Menu.html \o\ +++++++++++++++++++++++++++ >From hanrek@cts.com (Mark Hanrek) Date: 22 Aug 1994 04:54:34 GMT Organization: The Information Workshop In article <33394p$cs5@news.halcyon.com>, phaedrus@chinook.halcyon.com (Mark Phaedrus) wrote: > Could someone please post some brief sample code showing the correct use > of AESuspendTheCurrentEvent and AEResumeTheCurrentEvent? > Basically, this is what I'm doing right now: There is some example source code called "SuspendAppleEvent" that will hopefully help. You will find under "Inter-Application Communication" within the Snippets collection. It is on the Developer CD and hopefully available at ftp://ftp.apple.com/ as well. Mark Hanrek +++++++++++++++++++++++++++ >From bb@lightside.com (Bob Bradley) Date: Sun, 21 Aug 1994 04:13:05 -0800 Organization: SS Software Inc. I don't have a question of how to use AESuspendTheCurrentEvent but, whether I should use it. When I receive an OpenDoc event, I put up a dialog and the files attached to the OpenDoc event do not get processed until the user hits ok in the dialog (or cancel which would not process the documents at all). Should I suspend the OpenDoc event and resume when (or if) the user chooses ok in the dialog or should I just let the AppleEvent return and process the documents when the user wants? IM Interapp Comm says the AppleEvent Manager expects the event to have been processed when the handler returns which it wouldn't have been in my case and I'm not sure if I should call AESuspendTheCurrentEvent (and resume it later). It works fine though. +++++++++++++++++++++++++++ >From paul@architecture.mcgill.ca (Paul Lalonde) Date: Tue, 23 Aug 1994 02:28:45 GMT Organization: McGill University School of Architecture In article <33394p$cs5@news.halcyon.com>, phaedrus@chinook.halcyon.com (Mark Phaedrus) wrote: > Could someone please post some brief sample code showing the correct use > of AESuspendTheCurrentEvent and AEResumeTheCurrentEvent? > Basically, this is what I'm doing right now: > [ stuff deleted ] You have to save the actual event and reply records, not just pointers to them. So a revised version of the snippet you posted would look like this: AppleEvent pendingEvent,pendingReply; pascal OSErr MyEventHandler(AppleEvent *messagein, AppleEvent *reply, long refcon) { /* stuff deleted */ pendingEvent = *messagein; pendingReply = *reply; /* more stuff deleted */ return noErr; } void CodeCalledWhenReadyToFinish(void) { err = AEResumeTheCurrentEvent(&pendingEvent,&pendingReply, MyEventCompletion,0); } Hope this helps, Paul Lalonde paul@architecture.mcgill.ca --------------------------- >From dchakrav@netserv.unmc.edu (Dhruba Chakravarti) Subject: Learning Macintosh Programming Date: 19 Aug 1994 11:23:44 -0500 Organization: University of Nebraska Medical Center, Omaha, NE, USA I do not know anything about programming, which should be obvious from the header. I have a Macintosh computer and would like to learn programming for Macintosh. Please advise me. Regards, Dhruba. +++++++++++++++++++++++++++ >From mathews@ns9000.furman.edu (Owen Mathews) Date: 19 Aug 1994 18:50:13 GMT Organization: furman university computing center Dhruba Chakravarti (dchakrav@netserv.unmc.edu) wrote: : I do not know anything about programming, which should be obvious : from the header. I have a Macintosh computer and would like to : learn programming for Macintosh. Please advise me. : Regards, : Dhruba. If you're programming in Pascal, pick up the -Macintosh Pascal Programming Primer by Dave Mark and ??? Reed (something like that) **good introductory Mac book; teaches all about the Toolbox and Mac programming fundamentals; comes with several well-thought-out example programs to get you started If you're using C, then try -Macintosh C Programming Primer same fellow(s?) **I haven't see this one, but I assume it's the same idea. If you're really ambitious, take a look at -Learn C++ on the Macintosh guess who? (I'm a real admirer of this guy) **Also probably the same basic idea. No matter which language you use, you'll eventually want to invest in -Inside Macintosh Apple Computer **This set of reference books is the ultimate authority on all aspects of Mac programming. It comes in two flavors: Old Inside Mac (IM) and New IM (NIM). Old IM comes in 6 volumes that are organized chronologically. This unfortunately means that certain related material can be spread out over multiple volumes, forcing you to spend extra time to find the right volume. NIM groups material logically by subject. Each volume covers some clearly-defined area of the Mac API. Of course, NIM's disadvantage is that when Apple releases new stuff, you can't go and pick up the next chronological volume -- instead, you'll probably have to go and buy half a dozen updates to the subject volumes. But I'm rambling. Hey, don't let all that talk daunt you. With any of the first three books, you can get started programming quickly and produce your first (albeit ultra- simple) Mac application within an hour or two. Hope this helps! -- Owen Mathews mathews@furman.edu <><><><><><><><><><><><><><><><><><><><> Furman University, Computer Science Dept +++++++++++++++++++++++++++ >From dchakrav@netserv.unmc.edu (Dhruba Chakravarti) Date: 19 Aug 1994 17:17:42 -0500 Organization: University of Nebraska Medical Center, Omaha, NE, USA Owen Mathews (mathews@ns9000.furman.edu) wrote: : Dhruba Chakravarti (dchakrav@netserv.unmc.edu) wrote: : : I do not know anything about programming, which should be obvious : : from the header. I have a Macintosh computer and would like to : : learn programming for Macintosh. Please advise me. : : Regards, : : Dhruba. : If you're programming in Pascal, pick up the : -Macintosh Pascal Programming Primer : by Dave Mark and ??? Reed (something like that) : **good introductory Mac book; teaches all about the Toolbox : and Mac programming fundamentals; comes with several well-thought-out : example programs to get you started : If you're using C, then try : -Macintosh C Programming Primer : same fellow(s?) : **I haven't see this one, but I assume it's the same idea. : If you're really ambitious, take a look at : -Learn C++ on the Macintosh : guess who? (I'm a real admirer of this guy) : **Also probably the same basic idea. : No matter which language you use, you'll eventually want to invest in : -Inside Macintosh : Apple Computer : **This set of reference books is the ultimate authority on all : aspects of Mac programming. It comes in two flavors: Old Inside Mac : (IM) and New IM (NIM). Old IM comes in 6 volumes that are organized : chronologically. This unfortunately means that certain related material : can be spread out over multiple volumes, forcing you to spend extra : time to find the right volume. NIM groups material logically by : subject. Each volume covers some clearly-defined area of the Mac API. : Of course, NIM's disadvantage is that when Apple releases new stuff, : you can't go and pick up the next chronological volume -- instead, : you'll probably have to go and buy half a dozen updates to the subject : volumes. : But I'm rambling. : Hey, don't let all that talk daunt you. With any of the first three books, : you can get started programming quickly and produce your first (albeit ultra- : simple) Mac application within an hour or two. : Hope this helps! : -- : Owen Mathews mathews@furman.edu : <><><><><><><><><><><><><><><><><><><><> : Furman University, Computer Science Dept Thank you very much! I'll get these books and start reading. Regards, Dhruba. +++++++++++++++++++++++++++ >From Chris Kueny Date: 19 Aug 1994 23:37:21 GMT Organization: The University of Texas at Austin, Austin, Texas In article <332mag$2jq@netserv.unmc.edu> Dhruba Chakravarti, dchakrav@netserv.unmc.edu writes: >I do not know anything about programming, which should be obvious >from the header. I have a Macintosh computer and would like to >learn programming for Macintosh. Please advise me. The C Programming Primer by Dave Mark assumes that you know something about the C programming language (and I assume that the Pascal Programming Primer assumes knowledge of Pascal.) Another good book at this level is Dan Parks Sydow's "Macintosh Programming Techniques". But if you have no programming experience at all, then a good one to start with is "Learn C on the Macintosh" by Dave Mark. This has a stripped down version of Symantec's Think C compiler that can be used to run the projects in the book. It will give you an introduction to the C language, but won't tell you everything. It has a good explanation of programming concepts for people who have never done such things before. As mentioned above, Dave also wrote "Learn C++ on the Macintosh". A classic reference for the whole C language is "The C Programming Language" by Kernighan & Ritchie. I don't have much knowledge of Pascal. I think I heard someone say that it is easier for a beginner to learn Pascal than to learn C. Eventually you will have to buy a compiler. C and Pascal compilers are available at good discounts for university and college students and staff (maybe younger students too?) Used ones are also sometimes advertised in this newsgroup. +++++++++++++++++++++++++++ >From millsp@govonca.gov.on.ca (Phil Mills) Date: Sat, 20 Aug 1994 13:05:05 GMT Organization: Government of Ontario In <332mag$2jq@netserv.unmc.edu> dchakrav@netserv.unmc.edu (Dhruba Chakravarti) writes: >I do not know anything about programming, which should be obvious >from the header. I have a Macintosh computer and would like to >learn programming for Macintosh. Please advise me. 1) Decide why you want to program and what kind of program you would like to create. The best choice in tools and information sources will change depending on that decision. (Without an answer to #1, there *is* no item #2. :-) ) +++++++++++++++++++++++++++ >From kenlong@netcom.com (Ken Long) Date: Sat, 20 Aug 1994 16:52:14 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) Learn C on the Macintosh is NOT a good book for someone who has no programming or Mac programming experience. It contains LITTLE about what new Mac programmers are interested in. Think THINK C!, by Dan Parks Sydow is THE book to start with. It teaches new Mac programmers about aspects of Mac programming they WANT to know about. -Ken- +++++++++++++++++++++++++++ >From silicon@Simplex.NL (Silicon Island Software) Date: 21 Aug 1994 08:28:13 GMT Organization: Simplex Networking Amsterdam, The Netherlands. Dhruba Chakravarti (dchakrav@netserv.unmc.edu) wrote: : I do not know anything about programming, which should be obvious : from the header. I have a Macintosh computer and would like to : learn programming for Macintosh. Please advise me. Why Visual EzC is good for learning Macintosh programming. When you program in EzC, the Layouts of the applications with their interface elements are all created graphically in a MacDraw like Layout Editor. The process has little if anything to do with programming. The Menus of the application are also created in a graphic editor by simply adding menus and menu items in a list. The EzC program code is a C-like code, with all the basic syntax and functionality the same as in normal C. There is admittedly nothing new about creating layouts and menus graphically. - The available 4GL languages all do that, each in their own way. What is new though is, that EzC has a very powerful and well known programming language, and the EzC code can be pre-compiled into C, simply by selecting Precompile from the menu. The resulting C code can then be compiled with for instance MPW and the project can be made into a standalone application. Programs written in EzC are just as fast and small in size as programs written from scratch in C or Pascal. To give the curious an example of how a simple program looks like in EzC we can take as an example a window with a text field and listbox and an accept button. When the user keys in a name in the text field and clicks the accept button the name appears in the listbox. Solving the problem: 1) The interface elements are drawn in the layout editor. 2) A menu for the application is created in the menu editor. 3) The code to do the processing is as follows: inherit "Std:System:Window"; string *arr; void _OpenView() { arr=({}); LoadMenubar("Main"); } void _Click(string name) { if(name=="ok") { arr+=({Get("field","text")}); Set("listbox","array",arr); Set("field","text",""); } } The layout with the program code constitutes an object in EzC. The explanation of the code is simple. In the first line we inherit the standard behaviour of a window. EzC is event driven, and opening a window generates an event. To every EzC event corresponds a function. _OpenView() is one such function. If defined in an object, it is invoked when the event occurs. _Click() is another event handler function. It is invoked on clicking the mouse. The interface elements have names. The text field has the been given the name 'field' and the listbox element is called 'listbox' and the accept button's name is 'ok'. The Set() function sets a property of an interface element with given parameters, and the Get() function fetches the value of a property of an interface element. The code is only a few lines, and this is a functioning application, and can be made standalone. It is our opinion that EzC is a suitable language for learning Macintosh programming. - Try for instance for comparison to teach the beginner to create the above example application with Think C using the TCL library. The programmer does not need to study any textbook on Macintosh programming to be able create simple applications like the above application in EzC, nor does he need to have read a word of the voluminous Inside Macintosh. He does however need to know something about C programming in general and to understand the events of EzC and to have at hand a reference over the main kernel and Library functions in EzC. As the programmer becomes more proficient Visual EzC will grow with him, since it is so strongly related to C. The programmer also gradually becomes interested in acquiring knowledge of the Macintosh Toolbox as he needs to solve more advanced problems. The main advantage of learning Macintosh programming by using EzC is that the beginner can actually create useful standalone applications that he can be proud of within hours. Another important advantage is, that the beginner will quickly learn to appreciate Object Oriented programming as object orientation is so closely woven into the EzC language. A third advantage is, that the beginner will learn the basics of a generally known and accepted language, C. Last but not least. One should not forget that EzC also has a built in relational database engine, so when the beginner wants to create a database program, the tools are right there. A demo of Visual EzC can be found on mac.archive.umich.edu in the /mac/misc/demo/visualezc1.0b4-demo.hqx and on any of the info-mac mirror sites. Silicon Island Software Email: silicon@simplex.nl +++++++++++++++++++++++++++ >From D.Birnie@Regy.Canterbury.ac.nz (Denis A. Birnie) Date: Mon, 22 Aug 1994 11:17:06 +1200 Organization: ISS > I do not know anything about programming, which should be obvious > from the header. I have a Macintosh computer and would like to > learn programming for Macintosh. Please advise me. > Dhruba, The current way to go language-wise is C (or C++). The book which I'd recommend (and which uses C) is Macintosh_Programming_Secrets (2nd edition) by Scott Knaster & Keith Rollin. Shows you all sorts of interesting and neat things as well as giving you a skeleton application to work from. A VERY good book. I'd also suggest Think Reference if you get serious and have a screen larger than the original 9"ers. Denis Birnie -- COBOhoLic! +++++++++++++++++++++++++++ >From hanrek@cts.com (Mark Hanrek) Date: 22 Aug 1994 05:04:10 GMT Organization: The Information Workshop In article <332mag$2jq@netserv.unmc.edu>, dchakrav@netserv.unmc.edu (Dhruba Chakravarti) wrote: > I do not know anything about programming, which should be obvious > from the header. I have a Macintosh computer and would like to > learn programming for Macintosh. Please advise me. > Dhruba, Besides all the excellent suggestions and advice thus far, consider doing the following... Decide on a language, and get the compiler for it. Then, download all the example source code you can find in that language and compile it. If something is too hard to get going, move on to another. When you get something to compile successfully, and it runs, then maybe you can think of an easy way to tweak it or make it do something different. - -- This method is an excellent method, because you will quickly become familiar with your development environment, and the language, and the Macintosh Toolbox (the three things you'll be learning at the same time). But what is great about this approach is that you will be getting a sense of gratification as you go along, and you will always be modifying rather than creating -- these are two very important things in the beginning, and two of the major reasons many people give up. There's no need to overwhelm yourself. Always have a language reference handy. So compile freely downloadable program right and left, have fun, make some changes that make goofy things happen, and next thing you know, you will have subliminally learned a ton of essential things without even noticing it. Good luck to you. Mark Hanrek The Information Workshop +++++++++++++++++++++++++++ >From garyg@oak.circa.ufl.edu Date: 22 Aug 1994 12:46:50 GMT Organization: Center for Instructional and Research Computing Activities Dhruba, In addition to the other advice offered, I'd suggest that you also get: Macintosh Programming Techniques: A Foundation for All Macintosh Programmers by Dan Parks Sydow (1994; M&T Books). It includes a diskette with interactive tutorials, sample code with small built applications (in case you don't have a C compiler yet), and lots of highly useful info. Another great job by DPSydow!! hth, Gary +++++++++++++++++++++++++++ >From dchakrav@netserv.unmc.edu (Dhruba Chakravarti) Date: 23 Aug 1994 11:27:23 -0500 Organization: University of Nebraska Medical Center, Omaha, NE, USA garyg@oak.circa.ufl.edu wrote: : Dhruba, : In addition to the other advice offered, I'd suggest that you also get: : Macintosh Programming Techniques: A Foundation for All Macintosh : Programmers by Dan Parks Sydow (1994; M&T Books). It includes a : diskette with interactive tutorials, sample code with small built : applications (in case you don't have a C compiler yet), and lots : of highly useful info. Another great job by DPSydow!! : hth, Gary Thank you all very much! Regards, Dhruba. --------------------------- >From will@cs.su.oz.au (William Uther) Subject: Should function order be conserved? (CW vs. GestaltValue) Date: 20 Aug 1994 16:19:54 +1000 Organization: Basser Dept of Computer Sciece, Uni of Sydney, Australia Hi, I am using CodeWarrior to write a small application. I want this application to publish a handle. I had an earlier version that did this using the GestaltValue library. This library does not work with CW 3.5. I traced it, and found that the reason it didn't work was because it relied upon the ordering of functions to find the size of a block of memory to allocate. (it subtracted the address of the start of one function from the address of the start of another function to get the size of the first function and hence the amount of memory it had to allocate to copy it to the system heap) CW 3.5 does not respect this ordering when it converts Apple's '.o' file into a library. Is this a problem for MetroWerks (CW SHOULD respect the function ordering), or is this a problem for Apple (DTS shouldn't write libraries that rely on function ordering)?? At the moment it just seems to be a problem for me.... Metrowerks tech support were very good at verifying the problem, unfortunately, since they shifted the blame to Apple they haven't done much. (BTW the library works in THINK C 5.0, 6.0 and 7.0 - I assume it works in MPW as it's an MPW object file) Should I be talking to Apple DTS or Metrowerks tech support? \x/ill :-} will@cs.su.oz.au +++++++++++++++++++++++++++ >From cokenias@netcom.com (Damon Cokenias) Date: Sun, 21 Aug 1994 21:16:36 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) - --- I traced it, and found that the reason it didn't work was because it relied upon the ordering of functions to find the size of a block of memory to allocate. (it subtracted the address of the start of one function from the address of the start of another function to get the size of the first function and hence the amount of memory it had to allocate to copy it to the system heap) CW 3.5 does not respect this ordering when it converts Apple's '.o' file into a library. - --- Every time I'm stepping through somebody's INIT trying to find out if it is responsible for crashing my machine, I invariably find this sort of programming. It is sick and immoral. It is absolutely none of the programmer's business where or how their code gets compiled. There are two solutions to the Patch/Gestalt Selector/Shutdown Handler install problem. (Actually, there are more than two, but these are my favorites). ** A ** 1) Call Get1IndResource (INIT, 1) to find yourself (or other appropriate GetResource call) 2) Detach yourself, install all patches, etc. ** B ** 1) Load a code resource containing your patch routines, detach and lock 2) Install patches. I typically use A for quickie jobs that I just want to crank out in a moment or two. It has the disadvantage of leaving the loader code behind. Some of the advantages are: Only one binary to build (nice for THINK and CW users), the patches have access to the same A4 globals the loader code did. This can be usefull. I choose B for lean and mean INITs that I release to the public. In order to initialize the globals for the code resource with values from the loader, I sometimes do the following: 1) Inside the code resource I have an A4 global called 'intialized'. It's initial value is zero. 2) BEFORE installing the patches, I call my code resource, passing a pointer to a structure containing initial values. This can only be done for patches that accept parameters, obviously. 3) If 'initialized' is still false, the code resource knows the passed parameter contains special data and uses that data. 'initialized' is then set to true. 4) From this point on, all calls to the code resource are treated as one would expect them to. Often, this is the most convenient way to tell a patch where to jump to after completion. It is 100% portable on all platforms that allow a standalone code resource to have globals. DO NOT: * assume code gets put anywhere. If you use Codewarrior, the frequent updates and changes should cure you of that fast enough. (What if CW noticed that a particular routine could be called with a short branch instead of a long one? It might re-arrange certain funtions to make them closer to their callers.) -Damon Cokenias . -- Damon Cokenias cokenias@netcom.COM +++++++++++++++++++++++++++ >From h+@nada.kth.se (Jon W{tte) Date: Mon, 22 Aug 1994 14:54:28 +0200 Organization: Royal Institute of Something or other In article , cokenias@netcom.com (Damon Cokenias) wrote: >It is sick and immoral. It is absolutely none of the programmer's business >where or how their code gets compiled. Yes; it definately is. For a well-defined runtime architecture, like the Mac 68k one, you're allowed and sometimes forced to do this. >There are two solutions to the Patch/Gestalt Selector/Shutdown Handler install >problem. (Actually, there are more than two, but these are my favorites). >1) Call Get1IndResource (INIT, 1) to find yourself (or other appropriate > GetResource call) >2) Detach yourself, install all patches, etc. >1) Load a code resource containing your patch routines, detach and lock >2) Install patches. Strangely enough, I use none of these. Instead, I get the address of the first instruction (you can use A0 as well, but it's slightly less safe - someone COULD have jumped to you through another register) Then I call RecoverHandle and DetachResource, and use PC-relative addressing to install my patches (and store data) This requires your INIT to be marked pre-loaded, system heap and locked. >1) Inside the code resource I have an A4 global called 'intialized'. It's A4 globals are much more horrible than comparing addresses of functions. A4 globals require you to always enter through main(), unless you do extra inline assembly, which kind of rules out the case where the loader and the patch are in the same code resource. PS: you can get by the loader-left problem by putting the loader code last, branch to it from the top and then call SetHandleSize. -- Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden "Don't Deal with a Dragon." +++++++++++++++++++++++++++ >From Jaeger@fquest.com (Brian Stern) Date: 22 Aug 1994 17:00:11 GMT Organization: The University of Texas at Austin, Austin, Texas In article <9668AA7E6CA4.FDF19@klkmac008.nada.kth.se>, h+@nada.kth.se (Jon W{tte) wrote: > A4 globals are much more horrible than comparing addresses of > functions. A4 globals require you to always enter through > main(), unless you do extra inline assembly, which kind of > rules out the case where the loader and the patch are in the > same code resource. > This isn't true. With A4 globals you must enter through main *once*. You save the address of A4 in main. After that you can enter through any entry point you like. Each additional entry point first retrieves A4 and can then access its globals. It restores A4 before exiting. There is no reason you can't have the loader and the patch in the same code resource. > PS: you can get by the loader-left problem by putting the > loader code last, branch to it from the top and then call > SetHandleSize. I agree that this is a neat trick. Unfortunately you can't use it when using A4 global addressing. The globals end up at the end of the code resource. Oh well. > -- > Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden > "Don't Deal with a Dragon." -- Brian Stern :-{)} Jaeger@fquest.com +++++++++++++++++++++++++++ >From h+@nada.kth.se (Jon W{tte) Date: Tue, 23 Aug 1994 08:54:14 +0200 Organization: Royal Institute of Something or other In article , Jaeger@fquest.com (Brian Stern) wrote: >This isn't true. With A4 globals you must enter through main *once*. You >save the address of A4 in main. After that you can enter through any >entry point you like. Each additional entry point first retrieves A4 and >can then access its globals. It restores A4 before exiting. There is no >reason you can't have the loader and the patch in the same code resource. How do you retrieve the stored value of A4 without extra inline assembly? Or does Symantec provide the extra assembler to do it for you from anywhere now ?(it was a long time since I last used it...) Cheers, / h+ -- Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden "Psychotherapist" - "Phycho-The-Rapist" Pure coincidence? You decide! +++++++++++++++++++++++++++ >From Jaeger@fquest.com (Brian Stern) Date: 23 Aug 1994 16:19:46 GMT Organization: The University of Texas at Austin, Austin, Texas In article <9668AA7F69B6.206994@klkmac012.nada.kth.se>, h+@nada.kth.se (Jon W{tte) wrote: > How do you retrieve the stored value of A4 without extra inline > assembly? Or does Symantec provide the extra assembler to do it > for you from anywhere now ?(it was a long time since I last used > it...) > > Cheers, > / h+ > -- > Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden > "Psychotherapist" - "Phycho-The-Rapist" > Pure coincidence? You decide! Yes, the inline code is provided in a header file that must be included in each source file that needs to do A4 addressing. The header contains several inline assembler functions for saving and restoring A4. From the standpoint of the programmer there is no assembly required. -- Brian Stern :-{)} Jaeger@fquest.com +++++++++++++++++++++++++++ >From phils@bedford.symantec.com (Phil Shapiro) Date: Tue, 23 Aug 1994 19:31:26 -0400 Organization: Symantec Corp. In article <9668AA7F69B6.206994@klkmac012.nada.kth.se>, h+@nada.kth.se (Jon W{tte) wrote: | In article , | Jaeger@fquest.com (Brian Stern) wrote: | | >This isn't true. With A4 globals you must enter through main *once*. You | >save the address of A4 in main. After that you can enter through any | >entry point you like. Each additional entry point first retrieves A4 and | >can then access its globals. It restores A4 before exiting. There is no | >reason you can't have the loader and the patch in the same code resource. | | How do you retrieve the stored value of A4 without extra inline | assembly? Or does Symantec provide the extra assembler to do it | for you from anywhere now ?(it was a long time since I last used | it...) Each source file gets its own copy of A4. As long as you're in the same source file that you called RememberA0() in (or RememberA4(), if A4 was valid already), you can call SetUpA4() at any entry point. This is because A4 is stored inside code in a static function; each file that uses the function gets a different copy. This has been true for quite awhile, I'm pretty sure that LSC 4.0 worked this way. If you build with a custom header, you don't even need to enter main() at all. But you better set up A4 before you access any globals or cross-segment routines. -phil --------------------------- >From "Andrew C. Plotkin" Subject: Sound Manager headaches (again) Date: Sun, 21 Aug 1994 14:42:43 -0400 Organization: Information Technology Center, Carnegie Mellon, Pittsburgh, PA When we last left our hero, he had just figured out how to play a sound at a given frequency (by sending soundCmd and freqDurationCmd to a sampledSynth channel.) (I sent a code snippet of doing this to alt.sources.mac, if you care. ./vol-08/sampledsnd.cpt.hqx) Well, there was a reason I wanted to do that. See, I want to get music out, and I thought that the way to do that was record snd resources of each instrument, and then use that technique to play notes. Allocate several channels, you can get multiple notes at once. ...Riiiiight. First problem: they don't start off in synch. I use the algorithm given in the PlayTwoSoundsSynched in the SM3.0 tech note: (warning: pseudocode, not real code, ahead) SndDoImmediate(chan1, syncCmd{3, kID}) SndDoCommand(chan1, restCmd{500}); SndDoCommand(chan1, freqDurationCmd{500, MIDDLE_C}); SndDoImmediate(chan2, syncCmd{3, kID}) SndDoCommand(chan2, restCmd{500}); SndDoCommand(chan2, freqDurationCmd{500, MIDDLE_G}); SndDoImmediate(chan1, syncCmd{1, kID}) I expect this to pause a quarter-second, then play a nice chord. Nope. One channel (the first one, I believe) starts slightly -- but audibly -- first. (They do finish together, though.) This occurs both with and without SM3.0. (My guess: the SM has to resample one or both sounds to a different frequency, and this takes some time. Sigh.) Oh, yeah -- syncCmd behaves with extreme magic. I still don't know exactly what it does. For example, if I change the last line in the algorithm above from chan1 to chan2, only one note plays instead of both. Huh? Second problem: Under SM3.0, if I play a sequence of notes of the same duration, they don't come out with the same duration. Again, the difference is pretty audible -- as much as a 50% error in short notes. Unless I can do something about this, my entire plan is screwed. (Kinda cool, huh? The nifty new SM *doesn't support freqDurationCmd* in a usable form. I was pleased.) I recall someone else posted about this a few weeks ago, and he couldn't get it to work either. (My guess: same reason as before. The SM *does* keep the same (distorted) time between channels; if I start two parallel synched sequences, they stay synched. I guess that's something. It still ruins the music, though.) My question, pretty much, is "Have I missed anything?" I don't think I have. I think I'm going to have to ditch the whole idea of freqDurationCmd, and write my *own* sound-resampling-and-playing module a la SoundTracker. (Or just use SoundTracker or some other MOD player. This is tempting, but I haven't seen a freeware MOD player which includes source code, except for an icky-looking one ported straight from Unix, with malloc() everywhere. Anyone? Anyone?) ObBribery: if you give me a magic answer that fixes my music-playing code, I'll release the code as freeware. And I'll throw in the simple-but-oh-so-elegant music editor I've spent the past month on. (OTOH, if I wind up writing a MOD-style thing, I'll do the same thing. Nevertheless.) --Z "And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..." +++++++++++++++++++++++++++ >From Rick_Holzgrafe@taligent.com (Rick Holzgrafe) Date: Mon, 22 Aug 1994 18:22:58 GMT Organization: Semicolon Software In article , "Andrew C. Plotkin" wrote: > Second problem: Under SM3.0, if I play a sequence of notes of the same > duration, they don't come out with the same duration. Again, the > difference is pretty audible -- as much as a 50% error in short notes. > Unless I can do something about this, my entire plan is screwed. (Kinda > cool, huh? The nifty new SM *doesn't support freqDurationCmd* in a > usable form. I was pleased.) I recall someone else posted about this a > few weeks ago, and he couldn't get it to work either. That was me, I think. I've heard The Word from The Source: a key programmer at Apple tells me that SM 3.0 has been optimized for playing sampled sounds. The optimizations DE-optimized for playing melodies via freqDurationCmd; something about internal buffers having a size that causes perceptible delays when they need to be refilled. There is no workaround. For my app, I had to give up on freqDurationCmds (under SM 3.0) and convert my tunes to single sampled sound resources, which increased their size by two orders of magnitude and (to keep them from getting even larger) decreased their sound quality. My app now tests the version of the Sound Manager; if it is 3.0, you get one and only one melody; if less than 3.0, you get a rotating selection out of a list of seven melodies. The seven melodies take up about 20K of disk space; the one sampled-sound melody takes several times that. Feh. FWIW, I can show you code that should solve your synchronization problem. Your various melodic parts will start together correctly, and they will stay synched. Doesn't help the uneven tempo, though. -- Rick Holzgrafe Semicolon Software rmh@taligent.com +++++++++++++++++++++++++++ >From h+@nada.kth.se (Jon W{tte) Date: Tue, 23 Aug 1994 09:49:07 +0200 Organization: Royal Institute of Something or other In article , Rick_Holzgrafe@taligent.com (Rick Holzgrafe) wrote: >version of the Sound Manager; if it is 3.0, you get one and only one >melody; if less than 3.0, you get a rotating selection out of a list of >seven melodies. The seven melodies take up about 20K of disk space; the >one sampled-sound melody takes several times that. Feh. With QuickTime 2.0, however, all you do is store a General MIDI file in your resource fork (3-10k) and there's your melody. Luckily, this isn't rec.music.makers.synth, where "General MIDI" is a cuss word. Cheers, / h+ -- Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden "Psychotherapist" - "Phycho-The-Rapist" Pure coincidence? You decide! +++++++++++++++++++++++++++ >From Rick_Holzgrafe@taligent.com (Rick Holzgrafe) Date: Tue, 23 Aug 1994 18:24:34 GMT Organization: Semicolon Software In article , Rick_Holzgrafe@taligent.com (Rick Holzgrafe) wrote: >version of the Sound Manager; if it is 3.0, you get one and only one >melody; if less than 3.0, you get a rotating selection out of a list of >seven melodies. The seven melodies take up about 20K of disk space; the >one sampled-sound melody takes several times that. Feh. In article <9668AA7F7693.236F39@klkmac012.nada.kth.se>, h+@nada.kth.se (Jon W{tte) wrote: > With QuickTime 2.0, however, all you do is store a General MIDI > file in your resource fork (3-10k) and there's your melody. Great. So now instead of checking for the version of the Sound Manager and having two methods of playing music, I must also check for the presence and version of QuickTime, and have THREE methods. Ain't progress wonderful? Your pardon, please, for my surliness. I'm just tired of carefully coding to Apple's published interfaces, and having my sound code break anyway every couple of years. -- Rick Holzgrafe Semicolon Software rmh@taligent.com --------------------------- >From mdc14@ciao.cc.columbia.edu (Michael D Coble) Subject: Stopping a 'snd ' resource dead Date: 23 Aug 1994 03:53:01 GMT Organization: Columbia University I am a programming student trying to write a couple of macintosh applications. I recorded some music into a 'snd ' resource and want to invoke the music when a user chooses the about this application from the apple menu accompanied by a little animation. The 'snd ' resource is a couple of minutes long, so I'd like to be able to allow a user to click the close box and stop it in its tracks. I wonder if one of you experienced programmers out there might point me in the direction to reach this goal. Thanks, Michael Coble, mdc14@columbia.edu +++++++++++++++++++++++++++ >From bb@lightside.com (Bob Bradley) Date: Sun, 21 Aug 1994 15:12:37 -0800 Organization: SS Software Inc. In article <33brqt$mi8@apakabar.cc.columbia.edu>, mdc14@ciao.cc.columbia.edu (Michael D Coble) wrote: > I am a programming student trying to write a couple of macintosh > applications. I recorded some music into a 'snd ' resource and want to > invoke the music when a user chooses the about this application from the > apple menu accompanied by a little animation. The 'snd ' resource is a > couple of minutes long, so I'd like to be able to allow a user to click > the close box and stop it in its tracks. I wonder if one of you > experienced programmers out there might point me in the direction to > reach this goal. You can do this by playing the sound async. Something like this: SndNewChannel(...) // Create a new sound channel soundHandle = GetResource(...) // Get the snd resource SndPlay(...) // Play the sound setting async to true SndDisposeChanne(...) // Dispose of the sound channel and setting // quietNow to true so it stops any sound // that is currently playing. Hope that helps and doesn't contain too many errors :) +++++++++++++++++++++++++++ >From reed@medicine.wustl.edu (Thomas Reed) Date: Tue, 23 Aug 1994 11:08:58 -0500 Organization: Washington University If you ftp to thomas_mac.wustl.edu, you'll find the source code for a solitaire game I wrote a while back. It contains some very useful libraries I've written -- one of which is a sound library. Not only will it let you do what you want to do, but it'll also let you play the sound from disk to reduce the memory requirements. Hope you like it! Oh, for those of you with NewsWatcher, here's the URL: ftp://thomas_mac.wustl.edu/Public/for_ftp/Solitaire_code.sit -Thomas ===================================================== Thomas Reed Washington University reed@telesphere.wustl.edu Medical School reed@medicine.wustl.edu Saint Louis, MO - --------------------------------------------------- Clothes make the man. Naked people have little or no influence on society. -- Mark Twain ===================================================== Opinions posted are not the opinions of Wash. U. --------------------------- >From chris-b@cs.auckland.ac.nz (Chris Burns) Subject: [Q] What does "_Xxxxx ,Sys,Immed" mean? Date: Wed, 24 Aug 1994 11:36:07 +1200 Organization: AucklandUniversity:ComputerScience:HMU Hi all, What do the ",Sys,Immed" qualifiers mean? I know they specify certain bits in the trap word, but what do the different combinations mean? What I want is a table: Sys Immed Meaning x x ? x ? x ? ? Thanks Heaps In Advance, Chris B - --------------------------------------------------------------------- NewZealand:AucklandUniversity:ComputerScience:HyperMediaUnit:ChrisBurns Internet: chris-b@cs.auckland.ac.nz Phone: +64 9 373-7599 x6194 Fax: +64 9 373-7453 Async, therefore I am. - --------------------------------------------------------------------- +++++++++++++++++++++++++++ >From wysocki@netcom.com (Chris Wysocki) Date: Wed, 24 Aug 1994 15:27:25 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) In article , Chris Burns wrote: >What do the ",Sys,Immed" qualifiers mean? >I know they specify certain bits in the trap word, but what do the >different combinations mean? The ",Sys" and ",Immed" qualifiers displayed by MacsBug can be misnomers, since these are only two of the possible meaning of bits 9 and 10 of a trap word. All the possible meaning for these bits can be found in Traps.a: ; Equates for setting trap option bits ; for Device and File Manager routines immed EQU $200 ; execute immediately, bypass I/O queue async EQU $400 ; asynchronous, don't wait for completion ; for Memory Manager routines clear EQU $200 sys EQU $400 ; for string routines marks EQU $200 ; set to ignore/strip diacriticals case EQU $400 ; set for case sensitivity ; for all Toolbox routines autoPop EQU $400 ; set to pop an extra return address ; for Get/Set & NGet/NSet TrapAddress newTool EQU $600 ; Toolbox trap, under new ordering newOS EQU $200 ; OS trap, under new ordering ; for HFS routines newHFS EQU $200 Chris. --------------------------- >From chrism@col.hp.com (Chris Magnuson) Subject: jGNE from an INIT Date: 17 Aug 1994 05:50:18 GMT Organization: HP Colorado Springs Division I am writing a jGNE event filter in MPW that needs to be part of an INIT that does alot of other things ( i.e. the jGNE function is one part of the INIT code resource). I've gotten alot done, but run into problems when events actually call my jGNE routine to do the event "interception/ redirection." short JGNEFilterFunc(short hasEvent, const EventRecord *theEvent) My question is this: when the JGNEFilterFunc routine is called with an EventRecord, etc. am I supposed to be doing some A5 world swapping to get things to be handled properly in the jGNE routine? Without posting alot of code here is basically what the INIT initialization does. Hints are greatly appreciated! main() { oldZone = GetZone(); SetZone(SystemZone()); MakeA5World(&A5Ref); if (A5Ref == nil) { SetZone(oldZone); return(memFullErr); } a_SetA5Ref(A5Ref); oldA5 = SetA5World(A5Ref); (void) ReadPrefs(); jGNEInit(); /* point to assembly glue routine that eventually calls * JGNEFilterFunc() when events go through jGNE 0x29A */ (void) SetA5(oldA5); SetZone(oldZone); } Chris Magnuson chrism@col.hp.com +++++++++++++++++++++++++++ >From gurgle@dnai.com (Pete Gontier) Date: Tue, 16 Aug 1994 23:10:27 -0800 Organization: Integer Poet Software In article <32s8eq$kdr@hp-col.col.hp.com>, chrism@col.hp.com (Chris Magnuson) wrote: > I am writing a jGNE event filter in MPW that needs to be part of an INIT... > am I supposed to be doing some A5 world swapping... ? You will want to read the DSC Technical Note "Stand-alone Code Resources Ad Nauseum" if you have not already. The short answer is yes, you do need to do some twiddling to get access to global variables. Frankly, though, I would recommend doing this project in THINK C, because (a) assembly code is easier to integrate, (b) global variables are easier to access, and (c) my sample jGNE INIT, "jGNE Helper", is posted monthly to 'alt.sources.mac' with a THINK C project and will make all of these problems go away for you. -- Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com "I am Homer of Borg! Prepare to be... Ooooooo! Donuts!" +++++++++++++++++++++++++++ >From neil_ticktin@xplain.com (Neil Ticktin) Date: Wed, 17 Aug 1994 16:26:42 GMT Organization: MacTech Magazine/Xplain Corporation In article <32s8eq$kdr@hp-col.col.hp.com>, chrism@col.hp.com (Chris Magnuson) wrote: >> I am writing a jGNE event filter in MPW that needs to be part of an INIT that >> does alot of other things ( i.e. the jGNE function is one part of the >> INIT code resource). I've gotten alot done, but run into problems when >> events actually call my jGNE routine to do the event "interception/ >> redirection." >> Chris, Late last year, there was a great article by Symantec Tech Support in about writing a jGNEFilter. It was one of the THINK Top 10 columns. It contained the template code and an example of how to do it. I'm on the road and don't have the issue handy, but you should check it out. Hope it helps, Neil - --------------------------------------------------------------------- Neil Ticktin, MacTech Magazine (formerly MacTutor) PO Box 250055, Los Angeles, CA 90025 * 310-575-4343 * Fax: 310-575-0925 For more info, anonymous ftp to ftp.netcom.com and cd to /pub/xplain custservice@xplain.com * editorial@xplain.com * adsales@xplain.com marketing@xplain.com * accounting@xplain.com * pressreleases@xplain.com progchallenge@xplain.com * publisher@xplain.com * info@xplain.com +++++++++++++++++++++++++++ >From chrism@col.hp.com (Chris Magnuson) Date: 17 Aug 1994 20:14:57 GMT Organization: HP Colorado Springs Division Pete Gontier (gurgle@dnai.com) wrote: : In article <32s8eq$kdr@hp-col.col.hp.com>, : chrism@col.hp.com (Chris Magnuson) wrote: : > I am writing a jGNE event filter in MPW that needs to be part of an INIT... : > am I supposed to be doing some A5 world swapping... ? : You will want to read the DSC Technical Note "Stand-alone Code Resources : Ad Nauseum" if you have not already. The short answer is yes, you do need : to do some twiddling to get access to global variables. : Frankly, though, I would recommend doing this project in THINK C, because : (a) assembly code is easier to integrate, (b) global variables are easier : to access, and (c) my sample jGNE INIT, "jGNE Helper", is posted monthly : to 'alt.sources.mac' with a THINK C project and will make all of these : problems go away for you. No it won't :) I must not be communicating what has to happen here. main() is no longer the entry point for a jGNE filter only. main() is the entry point for an entire INIT, one component of which is a jGNE event processor. So the code resource in question here is an entire INIT, not just a jGNE filter. In other words, the jGNE portion of the code is one routine within the INIT code resource, and I have glue that dispatches to that routine, but it does not behave properly. So maybe the question is, when the jGNE event is dispatched to the code within my INIT, must I set A5 for some reason? Even though I am not interested in globals (just the parameters on the stack)? Chris Magnuson chrism@col.hp.com +++++++++++++++++++++++++++ >From chrism@col.hp.com (Chris Magnuson) Date: 17 Aug 1994 20:16:09 GMT Organization: HP Colorado Springs Division Thanks. Yes, I did check that out. It doesnt answer my question since it is a standalone jGNE (in other words the jGNE event processor is not part of a larger code resource with other things going on). Chris Magnuson chrism@col.hp.com Neil Ticktin (neil_ticktin@xplain.com) wrote: : In article <32s8eq$kdr@hp-col.col.hp.com>, chrism@col.hp.com (Chris : Magnuson) wrote: : >> I am writing a jGNE event filter in MPW that needs to be part of an : INIT that : >> does alot of other things ( i.e. the jGNE function is one part of the : >> INIT code resource). I've gotten alot done, but run into problems when : >> events actually call my jGNE routine to do the event "interception/ : >> redirection." : >> : Chris, : Late last year, there was a great article by Symantec Tech Support in : about writing a jGNEFilter. It was one of the THINK Top 10 columns. It : contained the template code and an example of how to do it. I'm on the : road and don't have the issue handy, but you should check it out. : Hope it helps, : Neil : ----------------------------------------------------------------------- : Neil Ticktin, MacTech Magazine (formerly MacTutor) : PO Box 250055, Los Angeles, CA 90025 * 310-575-4343 * Fax: 310-575-0925 : For more info, anonymous ftp to ftp.netcom.com and cd to /pub/xplain : custservice@xplain.com * editorial@xplain.com * adsales@xplain.com : marketing@xplain.com * accounting@xplain.com * pressreleases@xplain.com : progchallenge@xplain.com * publisher@xplain.com * info@xplain.com +++++++++++++++++++++++++++ >From larson@oahu.cs.ucla.edu (Christopher Larson) Date: Wed, 17 Aug 94 21:28:50 GMT Organization: UCLA, Computer Science Department In article <32tr42$pfg@hp-col.col.hp.com> chrism@col.hp.com (Chris Magnuson) writes: >: In article <32s8eq$kdr@hp-col.col.hp.com>, >: chrism@col.hp.com (Chris Magnuson) wrote: > >: > I am writing a jGNE event filter in MPW that needs to be part of an INIT... >: > am I supposed to be doing some A5 world swapping... ? [...] > So maybe the question is, when the jGNE event is dispatched to the code > within my INIT, must I set A5 for some reason? Even though I am not > interested in globals (just the parameters on the stack)? If you don't use (or cause to be used) any globals, you don't need an A5 world, and, therefore, you don't need to set A5. If the jGNE filter doesn't need access to any globals, why is it part of the INIT (I read the above to mean the jGNE code is within the INIT resource, if not, ignore this)? Wouldn't it be easier to compile the jGNE portion as a seperate resource, and just load, detatch, and install from the INIT resource? --Chris Larson _______________________________________________________________________________ Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious Death to the Trojans! Go Bruins! (Insert disclaimer here) Internet: larson@kingston.cs.ucla.edu +++++++++++++++++++++++++++ >From Jaeger@fquest.com (Brian Stern) Date: 18 Aug 1994 00:53:36 GMT Organization: The University of Texas at Austin, Austin, Texas In article <32tr42$pfg@hp-col.col.hp.com>, chrism@col.hp.com (Chris Magnuson) wrote: > Pete Gontier (gurgle@dnai.com) wrote: > : In article <32s8eq$kdr@hp-col.col.hp.com>, > : chrism@col.hp.com (Chris Magnuson) wrote: > > : > I am writing a jGNE event filter in MPW that needs to be part of an INIT... > : > am I supposed to be doing some A5 world swapping... ? > > No it won't :) I must not be communicating what has to happen here. main() > is no longer the entry point for a jGNE filter only. main() is the entry > point for an entire INIT, one component of which is a jGNE event processor. > So the code resource in question here is an entire INIT, not just a jGNE > filter. > > In other words, the jGNE portion of the code is one routine within the INIT > code resource, and I have glue that dispatches to that routine, but it > does not behave properly. > > So maybe the question is, when the jGNE event is dispatched to the code > within my INIT, must I set A5 for some reason? Even though I am not > interested in globals (just the parameters on the stack)? > > Chris Magnuson > chrism@col.hp.com In order to function properly any jGNEFilter has to insert itself into the chain of all jGNEFilters. When your filter exits it needs to jump to the previous filter. The address of the previous filter must be saved at the time that you install your filter. This saved address must be a global. Therefore your jGNEFilter, and all jGNEFilters for all time, must have access to global variables. There are several mechanisms for accessing global variables in stand alone code resources like your jGNEFilter. As I understand it MPW uses an A5-based mechanism that is described in the tech note. Use that mechanism if you like. Think, and I believe CW, use an A4-based mechanism, which is straightforward to use. Aside from access to the previous filter's address or to other global variables there is no requirement for an A5 world to be set up. There is a sample jGNEFilter written by Dave Falkenberg that can be found at ftp.apple.com. This sample is all in MPW assembler. It does not use the A5 mechanism for storing the address of the previous filter. It simply stores the address within itself. -- Brian Stern :-{)} Jaeger@fquest.com +++++++++++++++++++++++++++ >From gurgle@dnai.com (Pete Gontier) Date: Wed, 17 Aug 1994 21:17:15 -0800 Organization: Integer Poet Software In article <1994Aug17.212850.10867@cs.ucla.edu>, larson@oahu.cs.ucla.edu (Christopher Larson) wrote: > If the jGNE filter doesn't need access to any globals, why is it part of > the INIT ... ? Wouldn't it be easier to compile the jGNE portion as > a seperate resource, and just load, detatch, and install from the INIT > resource? His filter might want to call other functions in the INIT without duplicating them in the jGNE resource. I don't know enough about MPW-generated code resources to be able to say whether it needs A5 to call functions. Probably it uses PC-relative calls, but it's something you would want to look up. -- Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com "Even during a particularly harsh (Colorado) winter... many of the 300 families in the VCTV (movies-on-demand) trial continued to go to video stores." -- eis@murrow.tufts.edu, in Wired 2.09 p62 +++++++++++++++++++++++++++ >From gurgle@dnai.com (Pete Gontier) Date: Wed, 17 Aug 1994 21:25:33 -0800 Organization: Integer Poet Software In article <32tr42$pfg@hp-col.col.hp.com>, chrism@col.hp.com (Chris Magnuson) wrote: > I must not be communicating what has to happen here. main() > is no longer the entry point for a jGNE filter only. main() is the entry > point for an entire INIT, one component of which is a jGNE event processor. > So the code resource in question here is an entire INIT, not just a jGNE > filter. In other words, the jGNE portion of the code is one routine within > the INIT code resource, and I have glue that dispatches to that routine, > but it does not behave properly. As I said in email, I know. :-) Probably I am the one who did insufficient communicating. With a THINK (or CodeWarrior) compiler, what you're asking about is trivial, because the compiler actually knows that it's compiling something other than an application, unlike MPW. MPW only knows at link time; consequently, MPW code resource have to pretend in many ways that they are apps. Hence that entire tech note about code resources and A5. Blech. > So maybe the question is, when the jGNE event is dispatched to the code > within my INIT, must I set A5 for some reason? Even though I am not > interested in globals (just the parameters on the stack)? Again as I said in email, if your code does not use statically allocated variables (locals declared 'static' or globals), you may still need to set up A5 if your filter calls other routines, depending on how MPW finds those routines. Probably it finds them PC-relative, but it may find them A5-relative. Perhaps some MPW guru can shed light on this. -- Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com "Even during a particularly harsh (Colorado) winter... many of the 300 families in the VCTV (movies-on-demand) trial continued to go to video stores." -- eis@murrow.tufts.edu, in Wired 2.09 p62 +++++++++++++++++++++++++++ >From Jaeger@fquest.com (Brian Stern) Date: 19 Aug 1994 02:36:45 GMT Organization: The University of Texas at Austin, Austin, Texas In article , jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote: > On a side note.. I dont suppose you have any idea if I can > allocate some memory in a jGNEfilter? I dont mind stealing > from the host app. I want to muck with the clipboard, so need > a couple handles that dont mind being resized by the Scrap calls. > > -James Since jGNEFilters are called from WNE/GNE and both of those traps are documented as moving or purging memory, Yes you can allocate memory from inside a jGNEFilter. If you want the memory to last longer than one pass through your filter make sure to allocate the memory in the system heap, otherwise it will be lost if the app quits. If the memory will be allocated and disposed within one pass of the filter it can go in the application's heap. -- Brian Stern :-{)} Jaeger@fquest.com +++++++++++++++++++++++++++ >From jedavis@Xenon.Stanford.EDU (James Edward Davis) Date: 18 Aug 94 18:51:13 GMT Organization: Stanford University: Computer Science Department larson@oahu.cs.ucla.edu (Christopher Larson) writes: >In article <32tr42$pfg@hp-col.col.hp.com> chrism@col.hp.com (Chris Magnuson) writes: >> So maybe the question is, when the jGNE event is dispatched to the code >> within my INIT, must I set A5 for some reason? Even though I am not >> interested in globals (just the parameters on the stack)? >If you don't use (or cause to be used) any globals, you don't need an A5 >world, and, therefore, you don't need to set A5. Yes, but remember that some Quickdraw globals are offset from A5 as well. You might not need *your* A5, but you will need a valid one. I bring this up, because inside your jGNEfilter you wont neccessarily get one. You can set the A5 of the currently executing application from the low memory global CurrentA5, but remember to put back whatever stuffs was in A5 to start with. James Davis : jedavis@cs.stanford.edu +++++++++++++++++++++++++++ >From larson@oahu.cs.ucla.edu (Christopher Larson) Date: Thu, 18 Aug 94 21:05:17 GMT Organization: UCLA, Computer Science Department James said: >I said: >>Chris Magnuson said: >>> So maybe the question is, when the jGNE event is dispatched to the code >>> within my INIT, must I set A5 for some reason? Even though I am not >>> interested in globals (just the parameters on the stack)? > >>If you don't use (or cause to be used) any globals, you don't need an A5 >>world, and, therefore, you don't need to set A5. > >Yes, but remember that some Quickdraw globals are offset from A5 as >well. Making any calls which require Quickdraw globals count as causing globals to be used. (Perhaps I should have made that point clear :-). > You might not need *your* A5, but you will need a valid one. Why? If I don't use Quickdraw or my own globals, I shouldn't (see caveat below) need an A5 world and shouldn't care what the value of A5 is. I've written numerous code resources and trap patches (though never a jGNE filter). I've never needed an A5 world of my own (meaning belonging to the code resource), and only needed to borrow the current application's A5 when using Quickdraw globals. Unless jGNE filters are inherently different, I don't see why one must run with a valid A5. (I didn't intend this to sound at all like a flame. I'm just trying to get to the bottom of this too.) caveat: As Peter Lewis pointed out, calls to other routines within code resources may use a jump table, which may use A5. Consult your development system regarding this. (I'm paraphrasing, excuse me if I've misinterpreted you, Peter.) >I bring this up, because inside your jGNEfilter you wont neccessarily get >one. You sure won't. >You can set the A5 of the currently executing application from the low >memory global CurrentA5, but remember to put back whatever stuffs was in >A5 to start with. An invaluable piece of information. Saved my hiney many times. --Chris _______________________________________________________________________________ Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious Death to the Trojans! Go Bruins! (Insert disclaimer here) Internet: larson@kingston.cs.ucla.edu +++++++++++++++++++++++++++ >From jedavis@Xenon.Stanford.EDU (James Edward Davis) Date: 18 Aug 94 23:53:53 GMT Organization: Stanford University: Computer Science Department larson@oahu.cs.ucla.edu (Christopher Larson) writes: >> You might not need *your* A5, but you will need a valid one. >Why? If I don't use Quickdraw or my own globals, I shouldn't (see caveat >below) need an A5 world and shouldn't care what the value of A5 is. I've >written numerous code resources and trap patches (though never a jGNE >filter). I've never needed an A5 world of my own (meaning belonging to >the code resource), and only needed to borrow the current application's >A5 when using Quickdraw globals. Unless jGNE filters are inherently >different, I don't see why one must run with a valid A5. (I didn't >intend this to sound at all like a flame. I'm just trying to get to >the bottom of this too.) You're correct. I phrased something badly. I had meant to suggest that stealing the current applications A5 would do for quickdraw globals, if you didnt have one of your own handy. On a side note.. I dont suppose you have any idea if I can allocate some memory in a jGNEfilter? I dont mind stealing from the host app. I want to muck with the clipboard, so need a couple handles that dont mind being resized by the Scrap calls. -James +++++++++++++++++++++++++++ >From jedavis@Xenon.Stanford.EDU (James Edward Davis) Date: 19 Aug 94 09:42:08 GMT Organization: Stanford University: Computer Science Department Jaeger@fquest.com (Brian Stern) writes: >In article <32tr42$pfg@hp-col.col.hp.com>, chrism@col.hp.com (Chris >Magnuson) wrote: >> Pete Gontier (gurgle@dnai.com) wrote: >> : In article <32s8eq$kdr@hp-col.col.hp.com>, >> : chrism@col.hp.com (Chris Magnuson) wrote: >> >> So maybe the question is, when the jGNE event is dispatched to the code >> within my INIT, must I set A5 for some reason? Even though I am not >> interested in globals (just the parameters on the stack)? >> >> chrism@col.hp.com >In order to function properly any jGNEFilter has to insert itself into the >chain of all jGNEFilters. When your filter exits it needs to jump to the >previous filter. The address of the previous filter must be saved at the >time that you install your filter. This saved address must be a global. Global? Well not really. Its not really good style, but Ive seen it done by stuffing the address into your code at install time. The same way many people store their app A5, with code that self modifies to contain the location. For that matter, where should I store my apps A5, so I can reset it without using self modifying code? -James +++++++++++++++++++++++++++ >From larson@oahu.cs.ucla.edu (Christopher Larson) Date: Fri, 19 Aug 94 16:15:35 GMT Organization: UCLA, Computer Science Department In article jedavis@Xenon.Stanford.EDU (James Edward Davis) writes: >Jaeger@fquest.com (Brian Stern) writes: >>In order to function properly any jGNEFilter has to insert itself into the >>chain of all jGNEFilters. When your filter exits it needs to jump to the >>previous filter. The address of the previous filter must be saved at the >>time that you install your filter. This saved address must be a global. > >Global? Well not really. Its not really good style, but Ive seen it done >by stuffing the address into your code at install time. The same way >many people store their app A5, with code that self modifies to >contain the location. I'm not sure this strategy counts as self-modification if the installed code is contained in its own resource. When the app (INIT, whatever) loads the resource, before detaching and installing, it's just data. If it's modified at this point, I don't think you will have any problems (still need to flush caches though), because the resource has never been loaded as code. If the code to be installed is in your 'CODE' resources, all bets are off. (Comments on this welcome....) >For that matter, where should I store my apps A5, so I can reset >it without using self modifying code? Well, you could use the above strategy, or if that is still to self-modify- ish, you could install a Gestalt selector. Note that trickery to recover your A5 is only necessary if your code might run when your app is switched out or at interrupt time. If this is not the case, you can recover it from CurrentA5, as you suggested earlier. Hmmm. This raises an interesting question. If an app installs a jGNEFilter, is that filter visible to all other applications, or is it more like trap patches (which, if done from an app, are only visible to the installing app)? Anyone? Since this thread is about jGNEFilters, I assume your question was specific to recovering A5 from a jGNEFilter/trap patch kind of situation. If not, mail me with the specifics. --Chris _______________________________________________________________________________ Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious Death to the Trojans! Go Bruins! (Insert disclaimer here) Internet: larson@kingston.cs.ucla.edu +++++++++++++++++++++++++++ >From larson@oahu.cs.ucla.edu (Christopher Larson) Date: Fri, 19 Aug 94 16:22:01 GMT Organization: UCLA, Computer Science Department In article Jaeger@fquest.com (Brian Stern) writes: >In article , >jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote: > >> On a side note.. I dont suppose you have any idea if I can >> allocate some memory in a jGNEfilter? I dont mind stealing > >Since jGNEFilters are called from WNE/GNE and both of those traps are >documented as moving or purging memory, Yes you can allocate memory from >inside a jGNEFilter. If you want the memory to last longer than one pass >through your filter make sure to allocate the memory in the system heap, >otherwise it will be lost if the app quits. Or, you could receive consecutive calls from two different applications. Best, in any case, to allocate from the system heap if you want persistance. >If the memory will be allocated and disposed within one pass of the filter >it can go in the application's heap. Or maybe temporary memory if you don't want to use the app's heap. --Chris _______________________________________________________________________________ Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious Death to the Trojans! Go Bruins! (Insert disclaimer here) Internet: larson@kingston.cs.ucla.edu +++++++++++++++++++++++++++ >From gurgle@dnai.com (Pete Gontier) Date: Fri, 19 Aug 1994 09:45:18 -0800 Organization: Integer Poet Software In article <1994Aug19.161535.10734@cs.ucla.edu>, larson@oahu.cs.ucla.edu (Christopher Larson) wrote: > If an app installs a jGNEFilter, > is that filter visible to all other applications, or is it more like trap > patches (which, if done from an app, are only visible to the installing app)? It's visible to all other applications. -- Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com "Even during a particularly harsh (Colorado) winter... many of the 300 families in the VCTV (movies-on-demand) trial continued to go to video stores." -- eis@murrow.tufts.edu, in Wired 2.09 p62 +++++++++++++++++++++++++++ >From Jaeger@fquest.com (Brian Stern) Date: 19 Aug 1994 16:43:20 GMT Organization: The University of Texas at Austin, Austin, Texas In article , jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote: > Jaeger@fquest.com (Brian Stern) writes: > > >In order to function properly any jGNEFilter has to insert itself into the > >chain of all jGNEFilters. When your filter exits it needs to jump to the > >previous filter. The address of the previous filter must be saved at the > >time that you install your filter. This saved address must be a global. > > Global? Well not really. Its not really good style, but Ive seen it done > by stuffing the address into your code at install time. The same way > many people store their app A5, with code that self modifies to > contain the location. > For that matter, where should I store my apps A5, so I can reset > it without using self modifying code? > > -James App? I thought we were talking about about an INIT. Installing a jGNEFilter from an app has a number of problems to worry about. I would probably write the filter as a code resource using A4 addressing. To install it I'd load the resource into the system heap, set up A0, and jump to it from the app to initilize it. It would save A5 for later use. It would also have to make sure that the app still existed. The A4 mechanism as used by Think C is also a self-modifying mechanism and I don't see any clean way around it. Having said that, I recently came across some code in a package called Extension Shell by Dair Grant that uses A4 addressing without being self-modifying. Here's the code: WRITTEN BY: Eric Shapiro (from July 1993 BYTE article, and the supporting source code) // Saves the current value of A4 on the stack, and puts the address of main // into A4. Should be called at start of stand-alone code resource to access globals. #define GetGlobals() asm { \ move.l A4, -(SP) ; save old A4 \ lea main, A4 ; get globals \ } // The converse of GetGlobals(). Restore the value of A4 #define UngetGlobals() asm { \ move.l (SP)+, A4 ; restore A4 from stack \ } This is dependent on main being at the beginning of your code resource and on your compiler compiling the code resource using A4 addressing. -- Brian Stern :-{)} Jaeger@fquest.com +++++++++++++++++++++++++++ >From bjaques@vanbc.wimsey.com (Barton Jaques) Date: Fri, 19 Aug 1994 09:36:35 -0700 Organization: Wimsey Information Services I spent many long hours slaving over my hot jGNEFilter before it worked correctly. It is the sloppiest hack I've seen in a while, but it works great. In short, here's what I do: ¥ I have a separate jGNEFilter.¹ project which compiles into a single resource. ¥ My INIT or DRVR reads that resource, detaches it, locks it. ¥ At startup time, my INIT or DRVR reads the current value of jGNEFilter, pokes it into my patch resource, then sticks the address of my patch resource into jGNEFilter. ¥ I have another handle which contains useful "global" variables and pointers to procedures contained in other code resources. I poke the handle into my detached jGNE resource. This way I have access to "globals" which I have scattered through different code resources É yet I don't have to fiddle with A5. ¥ The way I do this is by initialising a couple of local variables in my patch resource as follows: globRecH globalsH = 0xEEEEEEEE; long nextGNEFilter = 0xDDDDDDDD; My INIT or DRVR scans the resource, finds 0xEEEEEEEE, and overwrites it with my "globals" handle. Then it scans for 0xDDDDDDDD, and overwrites it with the pointer to the next GNE filter. ¥ If my GNEFilter calls a procedure in another of my code resources, THEN I need to set up A4/A5 as appropriate, and put it back before I return to my patch. ¥ When I want to de-install my driver, etc., I cauterise my patch by plugging 0x00000000 where my globals handle was. The filter then knows that it has been deactivated, so it passes to the next filter without doing anything. I can always restore the patch simply by poking globH back in again. This is the code in THINK C 68K. It surely will not work under another environment without serious modification, but it should illustrate the idea. void main() { globRecH globH = (globRecH)0xEEEEEEEE; long nextGNEFilter = 0xDDDDDDDD; EventRecord *filteredEventP; // declare any other local vars you need Ptr stackP; // stackP MUST be last local var declared // move.l (a7), -(a7) ; In actual res this line must precede LINK A6 // ; In ResEdit, insert '2F17' as 1st word in res // ; then move 2nd-last byte (= 4E5E) to // ; precede 5th-last byte (= 4A97) asm{ movem.l a7, stackP ; make copy of stack pointer movem.l a0-a3/d0-d7, -(sp) ; save registers } // if nextGNEFilter exists we must fiddle with stack to insert it if (nextGNEFilter) { stackP += ((Ptr)&globH - (Ptr)&stackP) + 8; *(long*)stackP = nextGNEFilter; } // do nothing if no globals if (globH) { // get a pointer to the event record asm{ move.l a1, filteredEventP ; test a1 (EventPtr) } eventwhat = filteredEventP->what; // now we can do our stuff } // restore registers and stack asm{ movem.l (sp)+, d0-d7/a0-a3 ; restore all registers tst.l (sp) ; in actual res these lines follow UNLK A6 (see note above) bne @END ; tst.l (sp)+ ; @END } // control now passes to next GNEFilter handler if any } -- bjaques@vanbc.wimsey.com +++++++++++++++++++++++++++ >From gurgle@dnai.com (Pete Gontier) Date: Fri, 19 Aug 1994 12:20:28 -0800 Organization: Integer Poet Software In article , bjaques@vanbc.wimsey.com (Barton Jaques) wrote: > I spent many long hours slaving over my hot jGNEFilter before it worked > correctly. It is the sloppiest hack I've seen in a while, but it works > great. In short, here's what I do... With all due respect for your long hours, quite frankly this all seems very convoluted and mildly dangerous. If any step in the development process goes wrong, the program fails at runtime. There are a minimum of helpful compile-time checks, and it's difficult to see why any one part of it works the way it does without understanding the whole picture. I'm glad it works for you, but it seems a lot simpler and a lot cleaner to simply use a strategy like that illustrated in "jGNE Helper" or whatever the hell that monthly posting is called. (It may sound like I didn't write it because I can't even remember its name, but I did write it, and you should assume I am accordingly biased.) -- Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com "Even during a particularly harsh (Colorado) winter... many of the 300 families in the VCTV (movies-on-demand) trial continued to go to video stores." -- eis@murrow.tufts.edu, in Wired 2.09 p62 +++++++++++++++++++++++++++ >From Jaeger@fquest.com (Brian Stern) Date: 20 Aug 1994 00:25:40 GMT Organization: The University of Texas at Austin, Austin, Texas In article , bjaques@vanbc.wimsey.com (Barton Jaques) wrote: > I spent many long hours slaving over my hot jGNEFilter before it worked > correctly. It is the sloppiest hack I've seen in a while, but it works > great. In short, here's what I do: Or, you could simply use A4 addressing to access your globals from your Filter. You can easily set a Boolean flag to let your Filter know if it's supposed to do anything. I don't trust any code building method that has instructions in it like ' In ResEdit, insert '2F17' as 1st word in res then move 2nd-last byte (= 4E5E) to precede 5th-last byte (= 4A97)'. In programming like in most things simpler is usually better. There are lot's simpler ways to do it than this. > -- > bjaques@vanbc.wimsey.com -- Brian Stern :-{)} Jaeger@fquest.com +++++++++++++++++++++++++++ >From jedavis@Xenon.Stanford.EDU (James Edward Davis) Date: 20 Aug 94 17:24:09 GMT Organization: Stanford University: Computer Science Department larson@oahu.cs.ucla.edu (Christopher Larson) writes: >In article jedavis@Xenon.Stanford.EDU (James Edward Davis) writes: >>Jaeger@fquest.com (Brian Stern) writes: >Well, you could use the above strategy, or if that is still to self-modify- >ish, you could install a Gestalt selector. Note that trickery to recover your >A5 is only necessary if your code might run when your app is switched out or >at interrupt time. If this is not the case, you can recover it from CurrentA5, >as you suggested earlier. >Hmmm. This raises an interesting question. If an app installs a jGNEFilter, >is that filter visible to all other applications, or is it more like trap >patches (which, if done from an app, are only visible to the installing app)? >Anyone? The jGNE filter *is* active across all apps. The low memory global that points to the filter chain, is not changed by context switches. This means you have to be very careful if you install a filter with code in your app heap, since if you quit without cleanup, theres a dangling reference and the machine will crash. -James +++++++++++++++++++++++++++ >From kluev@jonathan.srcc.msu.su (Kluev) Date: Mon, 22 Aug 94 23:02:46 +0400 Organization: (none) In article jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote: > The jGNE filter *is* active across all apps. The low memory global that > points to the filter chain, is not changed by context switches. This > means you have to be very careful if you install a filter with code > in your app heap, since if you quit without cleanup, theres a dangling > reference and the machine will crash. One should be careful about this cleanup. One shouldn't restore original value in jGNEFilter, because someone may install gne filter on top of one's. Restoring jGNEFilter to original value will remove someone's filter and may crash him. The better solution is to install one's filter into system heap, never remove it, check if filter was already installed (Gestalt is one solution) (not to install it twice), set/clear flag on application's startup/exit to turn filter's activity on/off. Michael Kluev. +++++++++++++++++++++++++++ >From jedavis@Xenon.Stanford.EDU (James Edward Davis) Date: 23 Aug 94 02:50:02 GMT Organization: Stanford University: Computer Science Department kluev@jonathan.srcc.msu.su (Kluev) writes: >In article >jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote: >One should be careful about this cleanup. One shouldn't restore >original value in jGNEFilter, because someone may install gne >filter on top of one's. Restoring jGNEFilter to original value >will remove someone's filter and may crash him. The better >solution is to install one's filter into system heap, never >remove it, check if filter was already installed (Gestalt is >one solution) (not to install it twice), set/clear flag on >application's startup/exit to turn filter's activity on/off. Yes, that would work but Id rather not leave memory allocated in the system heap. But your right about another being installed over mine. I allocate a small block in the system heap that just jumps to my code in the application heap. When I want to deinstall, I check to see if the front jGNEfilter is me. If it is, I can just reset the pointer. If its not, I change my stub to jump to the original address instead of my code. I only end up wasting a little system heap that way. I cant claim credit for the technique. I got a snippet from someone else, thought it was clever, and used it. -James +++++++++++++++++++++++++++ >From h+@nada.kth.se (Jon W{tte) Date: Tue, 23 Aug 1994 09:49:02 +0200 Organization: Royal Institute of Something or other In article , jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote: >Yes, that would work but Id rather not leave memory allocated >in the system heap. But your right about another being installed >over mine. I allocate a small block in the system heap that just >jumps to my code in the application heap. When I want to deinstall, I hope you remember to flush the cache when you change this value... Cheers, / h+ -- Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden "Psychotherapist" - "Phycho-The-Rapist" Pure coincidence? You decide! +++++++++++++++++++++++++++ >From jedavis@Xenon.Stanford.EDU (James Edward Davis) Date: 23 Aug 94 22:00:51 GMT Organization: Stanford University: Computer Science Department h+@nada.kth.se (Jon W{tte) writes: >In article , >jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote: >>Yes, that would work but Id rather not leave memory allocated >>in the system heap. But your right about another being installed >>over mine. I allocate a small block in the system heap that just >>jumps to my code in the application heap. When I want to deinstall, >I hope you remember to flush the cache when you change this >value... Why.. thats an excellent point. I dont flush it, but it seems to work fine on my C610. I think Ive been very lucky.. Ill go change that. Unless anyone can think of a legit reason its working. Thanks, James +++++++++++++++++++++++++++ >From kluev@jonathan.srcc.msu.su (Kluev) Date: Wed, 24 Aug 94 21:13:06 +0400 Organization: (none) In article jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote: > h+@nada.kth.se (Jon W{tte) writes: > > >In article , > >jedavis@Xenon.Stanford.EDU (James Edward Davis) wrote: > > >>Yes, that would work but Id rather not leave memory allocated > >>in the system heap. But your right about another being installed > >>over mine. I allocate a small block in the system heap that just > >>jumps to my code in the application heap. When I want to deinstall, > > >I hope you remember to flush the cache when you change this > >value... > > Why.. thats an excellent point. I dont flush it, but it seems to > work fine on my C610. I think Ive been very lucky.. Ill go change > that. Unless anyone can think of a legit reason its working. This depends on processor type and what your code is looked like. If it is looked like that: JMP Address; 0x4EF9 0x12345678; where 0x12345678 is modified address, you need to flush cache on 040 processors. If it is looked like this: MOVE.L *+$0006, -(sp); 0x2F3A0004; RTS; 0x4E75 DC.L 0x12345678; 0x12345678; where 0x12345678 is modified addr, don't worry about flushing cache. (DC.L will not run as code.) /* From MacTech magazine */ Michael Kluev. --------------------------- End of C.S.M.P. Digest **********************