From: pottier@clipper.ens.fr (Francois Pottier) Subject: csmp-digest-v3-073 Date: Sun, 4 Dec 1994 15:53:28 +0100 (MET) C.S.M.P. Digest Sun, 04 Dec 94 Volume 3 : Issue 73 Today's Topics: ? THINK Pascal: calling code Any science to segmenting? Plug-Ins w- CFM Saving a PICT to a file - how? Sprite Animation Toolkit 2.3a1 UPP's & calling completion procs 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 ase@cyberspace.org (Ashley A Thomas) Subject: ? THINK Pascal: calling code Date: Fri, 18 Nov 1994 16:51:15 +1100 Organization: little to none Could someone tell me where to find a good desription of how to write and use code you call from inside your program with THINK Pascal in the same way C programs can by calling a routine by passing a pointer to it. e.g. running code in a resource given its handle (like dnr); or passing a pointer to a procedure to be called somewhere else. Thanks! ASE -- Ashley A Thomas Email: ase@cyberspace.org +++++++++++++++++++++++++++ >From ingemar@lysator.liu.se (Ingemar Ragnemalm) Date: 20 Nov 1994 12:59:59 GMT Organization: (none) ase@cyberspace.org (Ashley A Thomas) writes: >Could someone tell me where to find a good desription of how to write and >use code you call from inside your program with THINK Pascal in the same >way C programs can by calling a routine by passing a pointer to it. >e.g. running code in a resource given its handle (like dnr); or passing a >pointer to a procedure to be called somewhere else. The following inline function is taken from TransSkel.p: procedure CallpInt (myInt: integer; myProc: ProcPtr); { Two calls use integer as one parameter arguments. This procedure handles } { both of them. } inline $205f, {movea.l (a7)+,a0 ; (a0) is a ptr to string, 4(a0) is mode} $4e90; By calling CallpInt, you call the procedure that myProc points to, with myInt as argument. Unfortunately, there is no type-checking done, so you are responsible for sending a pointer to a procedure that takes exactly the arguments you assume. myProc can be created by taking the address of the procedure (e.g. myProc := @MyProcedure;), or by dereferencing a handle to a code resource (after locking it!), e.g. something like: myCode := GetResource('CODE', 9999); if myCode = nil then HandleError else begin HLock(myCode); myProc := myCode^; end; You can change the above inline to any other argument list simply by adding or replacing arguments. Calling procedure pointers should really be built-in into Pascal, just as it is in Modula2, so we didn't have to do this kind of workarounds. Most of all, I want type checking on my procedure pointers. Perhaps we could convince MetroWerks to add it? -- - - Ingemar Ragnemalm, PhD Image processing, Mac shareware games E-mail address: ingemar@isy.liu.se or ingemar@lysator.liu.se --------------------------- >From ikb_macd@ece.concordia.ca (Keith MacDonald) Subject: Any science to segmenting? Date: 8 Nov 1994 04:23:04 GMT Organization: ECE - Concordia University Should I be practising any science in determining which procedures are grouped into the same segments when I code or is there little/no overhead in jumping from one segment to another? Cheers, Keith ___________________________________________________________________________ Keith MacDonald Computer Engineering ikb_macd@ECE.concordia.ca Concordia University http://www.ece.concordia.ca/~ikb_macd/addr.html Montreal, QC, Canada +++++++++++++++++++++++++++ >From nick+@pitt.edu ( nick.c ) Date: Tue, 08 Nov 1994 01:05:54 -0500 Organization: The Pitt, Chemistry In article <39muf8$9mu@newsflash.concordia.ca>, ikb_macd@ece.concordia.ca (Keith MacDonald) wrote: > Should I be practising any science in determining which procedures are > grouped into the same segments when I code or is there little/no > overhead in jumping from one segment to another? My understanding is a segment is swapped into memory as a whole. So, (and I'm reasoning here, not speaking with any authority) it would make sense to me to group functions that call each other together into the same segment. Try and make each segment as "self contained" as possible (realizing that no segment could be entirely self contained - or it would be unnecessary to 'main'). This would minimize the efficiency loss of swapping in segments. 'Course with the modern memory structure of the Mac, I'm not sure this "swapping" ocurrs any longer... dunno. Internet: nick+@pitt.edu _/ _/ _/ _/_/_/ _/ _/ eWorld: nick _/_/ _/ _/ _/ _/ _/_/_/ CIS: 71232,766 _/ _/_/ _/ _/ _/ _/ http://www.pitt.edu/~nick/ _/ _/ _/ _/_/_/ _/ _/ +++++++++++++++++++++++++++ >From ramer@nrc.uab.edu (Kevin W. Ramer) Date: Wed, 09 Nov 1994 09:07:44 -0600 Organization: University of Alabama at Birmingham In article , nick+@pitt.edu ( nick.c ) wrote: > > > Should I be practising any science in determining which procedures are > > grouped into the same segments ? > My understanding is a segment is swapped into memory as a whole. > So, (and I'm reasoning here, not speaking with any authority) > it would make sense to me to group functions that call each > other together into the same segment. Try and make each segment > as "self contained" as possible (realizing that no segment > could be entirely self contained - or it would be unnecessary > to 'main'). This would minimize the efficiency loss of swapping > in segments. 'Course with the modern memory structure of the > Mac, I'm not sure this "swapping" ocurrs any longer... dunno. A couple of additional points to be made are 1) if you wish to have segments unloaded, do so from the main segment. Typically, calling UnloadSeg each time through your event loop. 2) If you don't stick to 1 be sure to never unload segments earlier in the calling chain ! For example, main calls A which calls B (each in different segments) _do not_ UnloadSeg(A) while in B. Makes for nasty crashes. -- Kevin W. Ramer ramer@nrc.uab.edu Programmer Analyst Neurobiology Research Center University of Alabama at Birmingham +++++++++++++++++++++++++++ >From pgontier@novell.com (Pete Gontier) Date: Wed, 09 Nov 1994 09:42:45 -0800 Organization: Novell, Inc., Walnut Creek/Macintosh Site In article , nick+@pitt.edu ( nick.c ) wrote: > 'Course with the modern memory structure of the > Mac, I'm not sure this "swapping" ocurrs any longer... dunno. Yes, it does. The Modern Memory Manager just has better (read: faster) heap management. It doesn't try to tell anyone what to do with individual heap blocks, which of course are what contain each code segment. You may be thinking of the Power Mac code model, which has a new paging scheme for code fragments in the data fork, assuming VM is turned on. I might as well add, now that I have followed up, that a successful segmentation strategy has to be planned ahead of time. The good news is that the strategy has a lot in common with good engineering practice regardless of segmentation, so if you are a good engineering citizen, you probably *accidentally* planned your segmentation strategy ahead of time :-). More specifically, if you have narrow entry points into your functional sub-systems, you can simply put each sub-system into its own segment and unload it when it's not needed. -- The views expressed here do not necessarily reflect those of my employer. +++++++++++++++++++++++++++ >From Rick_Holzgrafe@taligent.com (Rick Holzgrafe) Date: Tue, 8 Nov 1994 18:41:38 GMT Organization: Semicolon Software In article <39muf8$9mu@newsflash.concordia.ca>, ikb_macd@ece.concordia.ca (Keith MacDonald) wrote: > Should I be practising any science in determining which procedures are > grouped into the same segments when I code or is there little/no > overhead in jumping from one segment to another? Segments exist mainly for memory management purposes: they allow you to group relevant portions of your code into chunks which do not have to be kept in memory when they are not in use. For example, your initialization code runs only once, when the app starts up: put it all into a segment, and unload it when initialization is complete. You may have printing code which can be cleanly separated from the rest of your code; there's no need for it to be in memory when the user isn't printing -- and so on. This makes more efficient use of your heap and allows your app to run in less memory. There is a slight performance hit when making calls across segments, because they must pass through the jump table. Normally it's not worth worrying about, but I wouldn't call segment B from inside a tight, long, hopefully-fast loop in segment A. If you segment your code functionally, this will generally not happen anyway. You should be aware that segments are loaded automagically the first time any function in them is called, but they are never unloaded unless you do so specifically in your code. This has a couple of effects. One effect is that *any* routine can move memory if it is in an unloaded segment when you call it, because its segment will be loaded into your heap before the routine can be called. Another effect is that you need to be intelligent about unloading your segments if you want to reap the memory-management benefits. A common practice is to keep your main event loop in segment 0 (that is, the one that contains your main routine), and each time through the event loop, unload every other segment you've got. Unloading a segment doesn't force it from memory, it just frees it to move in the heap and to be purged if needed when memory gets low. Commonly used segments will therefore incur no serious performance penalty from being repeatedly unloaded unless memory is low; the user can then improve performance by allocating more memory to the app, if more memory is available. Exceptions to the automagical loading of segments: returns from subroutines do *not* force loading of segments, and segments cannot be loaded at interrupt level. Never unload a segment if your call stack contains pointers into it, or if you are using interrupt-level callbacks (e.g. from VBL or slot queues, async sound calls, async network calls, and the like) to routines in the segment. (I got into trouble once by calling my main event handler from a routine in a different segment; the main event handler was innocently unloading the segment that called it. Intermittently [whenever something stirred up the heap just wrong] it would crash when trying to return to the unloaded segment.) Segments can be marked "preload" in the resource fork if you want them loaded at startup; if you never explicitly unload them, then they'll always be there when you need them. Hope this helps. -- Rick Holzgrafe, a member of the Taligentsia Rick_Holzgrafe@taligent.com rmh@taligent.com +++++++++++++++++++++++++++ >From curreyr@halcyon.halcyon.com (curreyr) Date: 19 Nov 1994 10:16:54 GMT Organization: Northwest Nexus Inc. In article Rick_Holzgrafe@taligent.com (Rick Holzgrafe) writes: > You should be aware that segments are loaded automagically the first time > any function in them is called, but they are never unloaded unless you do > so specifically in your code. This has a couple of effects. One effect is > that *any* routine can move memory if it is in an unloaded segment when > you call it, because its segment will be loaded into your heap before the Another "effect" is that it can FAIL to load if there isn't room in the heap for the segment. This can be bad news to your users. If you ignore this fact, and the segment fails to load, your code had better handle this fact. But handling the failure is a pain in the @#$@. How many apps can you name that handle low memory situations reliably? My suggestion would be to use a modern application framework that hides the ugly details of segmentation loading/unloading and follow the advice others have given on segmenting your code. MacApp maintains a reserve in order to insure that there is always going to be memory available for that code segments to be loaded and could be used as an example if you want to "roll your own". -Robert Currey --------------------------- >From mdaw@alias.com (Matt Daw) Subject: Plug-Ins w- CFM Date: Wed, 16 Nov 1994 03:50:10 GMT Organization: Alias Research Inc. Has anybody implemented a way to do plug-ins (ala PhotoShop) with the Code Fragment Manager? If so, what is the best way of doing this? - --------------------- | Matt Daw | | Alias Research Inc. | - --------------------- +++++++++++++++++++++++++++ >From h+@metrowerks.com (Jon W{tte) Date: Sat, 19 Nov 1994 15:40:34 +0100 Organization: The Conspiracy In article , mdaw@alias.com (Matt Daw) wrote: >Has anybody implemented a way to do plug-ins (ala PhotoShop) with the Code >Fragment Manager? If so, what is the best way of doing this? It's REALLY easy. You just load the fragment from disk, and get the value of the symbol you want (like "main") and call it as a function pointer. NO PAIN! Unless you're on the 68K, in which case it's #$GUffaw Cheers, / h+ -- Jon Wätte (h+@metrowerks.com), Hagagatan 1, 113 48 Stockholm, Sweden "Psychotherapist" - "Psycho-The-Rapist" Pure coincidence? You decide! --------------------------- >From andy@dijkstra.cs.clemson.edu (Andrew Greenshields) Subject: Saving a PICT to a file - how? Date: 16 Nov 1994 00:43:29 GMT Organization: Clemson University I have finally got my text file to convert to a nice infra-red image which I now have in the format of a PICT. However, when I try to save this PICT as a file I am running into trouble. I am using GetHandleSize to find out how big the PICT is and then I am using SFWrite to write the data to a file. I am using *thePict as the pointer to the data, where thePict is of type PicHandle. When I try and look at this file using Photoshop it tells me there is a problem reading this file. What am I doing wrong? Any help would be greatly appreciated. Thanks in advance, Andy -- Andrew J. Greenshields N3IGS | Some people can tell what time it is by andy@cs.clemson.edu | looking at the Sun, but I have never been USPA C-24393 | able to make out the numbers. - ---------------------***STANDARD DISCLAIMERS APPLY***------------------------ +++++++++++++++++++++++++++ >From blm@coho.halcyon.com (Brian L. Matthews) Date: 16 Nov 1994 18:14:08 GMT Organization: NWNEXUS, Inc. - Making Internet Easy In article <3abkjh$5jm@hubcap.clemson.edu>, Andrew Greenshields wrote: | I am using GetHandleSize to find out how big the PICT is and then I |am using SFWrite to write the data to a file. A PICT file starts with a 512-byte header before the actual PICT data. This header is for use by applications, and as far as I know, there aren't any standards for what goes in there, except one. If it's all zeroes, you're fine. So, before calling FSWrite to put the picture data in the file, do a: err = SetFPos (fRefNum, 1, 512); If you've just created the file, this will effectively put 512 0s at the start of the file. Note that if you're writing to an existing file, you may actually have to do an FSWrite of 512 0s to ensure they're there. Brian -- Brian L. Matthews blm@halcyon.com "Look past the ghost that hides Hell's treasures." -Sky Cries Mary +++++++++++++++++++++++++++ >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) Date: 17 Nov 94 16:59:07 +1300 Organization: University of Waikato, Hamilton, New Zealand In article <3adi5g$qed@news.halcyon.com>, blm@coho.halcyon.com (Brian L. Matthews) writes: > > A PICT file starts with a 512-byte header before the actual PICT data. > This header is for use by applications, and as far as I know, there aren't > any standards for what goes in there, except one. If it's all zeroes, > you're fine. So, before calling FSWrite to put the picture data in the > file, do a: > > err = SetFPos (fRefNum, 1, 512); > > If you've just created the file, this will effectively put 512 0s at > the start of the file. No, it will not. You must explicitly write 512 bytes of zeroes in all cases. Lawrence D'Oliveiro fone: +64-7-856-2889 Computer Services Dept fax: +64-7-838-4066 University of Waikato electric mail: ldo@waikato.ac.nz Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00 +++++++++++++++++++++++++++ >From blm@chinook.halcyon.com (Brian L. Matthews) Date: 17 Nov 1994 18:26:54 GMT Organization: NWNEXUS, Inc. - Making Internet Easy In article <1994Nov17.165907.35371@waikato.ac.nz>, Lawrence D'Oliveiro, Waikato University wrote: |> err = SetFPos (fRefNum, 1, 512); |> If you've just created the file, this will effectively put 512 0s at |> the start of the file. |No, it will not. You must explicitly write 512 bytes of zeroes in all cases. Argh. Lawrence is, of course, absolutely right. I always seem to get Unix and the Mac confused in cases like this. Anyway, I was actually wrong twice. First, SetFPos will fail if you attempt to set the file position beyond the end of file. And second, if you use SetEOF before the SetFPos, it doesn't fill with 0s. So while I was right about needing the 512 0s, I screwed up how to get them there. :-) Brian -- Brian L. Matthews blm@halcyon.com "Look past the ghost that hides Hell's treasures." -Sky Cries Mary +++++++++++++++++++++++++++ >From andy@dijkstra.cs.clemson.edu (Andrew Greenshields) Date: 18 Nov 1994 01:32:04 GMT Organization: Clemson University In article <3ag79e$2vj@news.halcyon.com> blm@chinook.halcyon.com (Brian L. Matthews) writes: >In article <1994Nov17.165907.35371@waikato.ac.nz>, >Lawrence D'Oliveiro, Waikato University wrote: Thankyou both, I can now successfully save my PICTs to files! Andy -- Andrew J. Greenshields N3IGS | Some people can tell what time it is by andy@cs.clemson.edu | looking at the Sun, but I have never been USPA C-24393 | able to make out the numbers. - ---------------------***STANDARD DISCLAIMERS APPLY***------------------------ +++++++++++++++++++++++++++ >From rollin@newton.apple.com (Keith Rollin) Date: Sun, 20 Nov 1994 22:56:08 -0800 Organization: Apple ][ -> Mac -> Taligent -> Newton -> Windows? In article <3abkjh$5jm@hubcap.clemson.edu>, andy@dijkstra.cs.clemson.edu (Andrew Greenshields) wrote: > I have finally got my text file to convert to a nice infra-red image >which I now have in the format of a PICT. However, when I try to save >this PICT as a file I am running into trouble. I am using >GetHandleSize to find out how big the PICT is and then I am using >SFWrite to write the data to a file. I am using *thePict as the >pointer to the data, where thePict is of type PicHandle. When I try >and look at this file using Photoshop it tells me there is a problem >reading this file. What am I doing wrong? PICT files begin with a 512 byte header (documented in an old Technote and in NIM:Imaging with QuickDraw). You don't mention that you are providing for this header, so that might be your problem. The 512 byte header is for application-defined purposes. If you don't need to use it, you should clear it out (set it to zero) so as not to confuse another application that may try interpreting it. - -------------------------------------------------------------------------- Keith Rollin --- Phantom Programmer --- Apple Computer, Inc. --- Team Newton "I say, let's write "wacko" on all the rocks and be done with it." --------------------------- >From ingemar@lysator.liu.se (Ingemar Ragnemalm) Subject: Sprite Animation Toolkit 2.3a1 Date: 19 Nov 1994 18:12:06 GMT Organization: (none) Sprite Animation Toolkit 2.3, alpha version 1, is now available by ftp from ftp.uu.net, in the /tmp directory, as sat23a1.hqx. It will probably not remain there for more than a week. Sprite Animation Toolkit is a programming library for making sprite-based animations (e.g. games). It includes a large number of demos, ranging from trivially simple to a complete game. It has been used for producing over a dozen released games. This version works with CodeWarrior (Pascal or C, not PPC yet) as well as the Think compilers. (Not MPW. Sorry.) Several new features have been added, and a few changes have been made to make it faster, use less memory and be more foolproof. This is an alpha version. It is not thoroughly tested. All demos work just fine on all systems I have been able to try them on, but I need help to find out if there are any serious bugs left. -- - - Ingemar Ragnemalm, PhD Image processing, Mac shareware games E-mail address: ingemar@isy.liu.se or ingemar@lysator.liu.se --------------------------- >From D_Gladstone@cs.auckland.ac.nz (David Gladstone) Subject: UPP's & calling completion procs Date: Thu, 17 Nov 1994 08:55:53 +1200 Organization: University of Auckland, New Zealand. Hi. I have been having some conceptual problems with UPPs. I am writing a Catalog Service Access Module driver which needs to call a completion routine. I have been getting confused about how things work (especially with CFM68K on the horizon). I wrote the following initially as a series of questions and (as is often the case) managed to find plausible answers just by trying to phrase the questions - so I have stated what I understand instead. How accurate is my version of the story below. It has been a while since I read develop 17 (16?) "Making the Leap to PowerPC"... The way I figure it, there are several situations that could occur at runtime for my driver: 1. I am 68K code and the completion routine field is a ProcPtr 2. I am 68K code and the completion routine field is a UPP (either PPC or 68K code fragment) 3. I am PPC code and the completion routine field is a UPP (either PPC or 68K code fragment) 4. I am PPC code and the completion routine field is a ProcPtr (from a 68K, non CFM68K app) Case 1 would occur when we are running on a PPC in emulation or on a 68K machine and an old piece of software calls me. Since my code is 68K and I don't have CFM68K at my disposal the only option I have is to call the routine as if it were a ProcPtr (which is fine in this case). Case 2 would occur when a 68K version of the driver is running in emulation on a PPC or it is running on a 68K machine with CFM68K installed. It would not be so difficult if CFM68K existed - I could use it to dispatch all UPP calls and it would determine whether the pointer was a real UPP or not. However, without using CFM68K for the 68K version of the driver I have to call any value in the completion routine field of the parameter block as if it were a ProcPtr. This means that I will be jumping to the routine descriptor rather than the routine itself. I presume that NewRoutineDescriptor() must put 68K code at the beginning of all routine descriptors to handle this. Case 3 would occur when a PPC version of the driver is called by a CFM aware 68K or PPC app. In this case just call CallUniversalProc to dispatch the call. Case 4 would occur when a PPC version of the driver is called by an old non-CFM68K application. This must be handled by the Code Fragment Manager. If you call CallUniversalProc with a ProcPtr it figures out that the address in memory is not a routine descriptor and therefore should execute it as 68K code. Is it really that simple? David Gladstone. _________________________________________________________________________ David Gladstone : Computer Science Department, University of Auckland, NZ david@cs.auckland.ac.nz : Ph. +64 9 373-7599 x 5336 : Fax: +64 9 373-7453 _________________________________________________________________________ "Give blood... Play Hockey." +++++++++++++++++++++++++++ >From Jaeger@fquest.com (Brian Stern) Date: 17 Nov 1994 05:03:19 GMT Organization: The University of Texas at Austin, Austin, Texas In article , D_Gladstone@cs.auckland.ac.nz wrote: < Hi. I have been having some conceptual problems with UPPs. I am writing < a Catalog Service Access Module driver which needs to call a completion < routine. I presume that < NewRoutineDescriptor() must put 68K code at the beginning of all routine < descriptors to handle this. Not Exactly. If you're on a PowerMac, drop into macsBug and type 'il CopyBits'. CopyBits is native. What you'll see looks something like this: 000C12AC TB E | AAFE 000C12AE BTST D3,D0 | 0700 000C12B0 ORI.B #$00,D0 | 0000 0000 000C12B4 ORI.B #$00,D0 | 0000 0000 000C12B8 ORI.B #$BFC0,D3 | 0003 BFC0 000C12BC ORI.B #$04,D1 | 0001 0004 000C12C0 ORI.B #$2C10,A3 | 000B 2C10 000C12C4 ORI.B #$00,D0 | 0000 0000 000C12C8 ORI.B #$00,D0 | 0000 0000 000C12CC ORI.B #$A8EF,D0 | 0000 A8EF What you're looking at is the routine descriptor for Copybits. Notice that the first word is AAFE. That's the mixedmodemagic trap. So when you call copybits you're actually jumping to the mixedmodemagic trap. It knows the location of the rest of the routine descriptor and gets the information that it needs to jump to the appropriate code in the appropriate mode. < Is it really that simple? Pretty much. If you're 68K then all you know about are procptrs. If you're PPC then you MUST use CallUniversalProc. CallUniversalProc works correctly if the code it's pointing to is a routine descriptor or is 68K code. < < < David Gladstone. < < _________________________________________________________________________ < David Gladstone : Computer Science Department, University of Auckland, NZ < david@cs.auckland.ac.nz : Ph. +64 9 373-7599 x 5336 : Fax: +64 9 373-7453 < _________________________________________________________________________ < "Give blood... Play Hockey." -- Brian Stern :-{)} Toolbox commando and Menu bard Jaeger@fquest.com +++++++++++++++++++++++++++ >From wdh@fresh.com (Bill Hofmann) Date: Thu, 17 Nov 1994 17:54:50 GMT Organization: Fresh Software In article , D_Gladstone@cs.auckland.ac.nz wrote: >.... > The way I figure it, there are several situations that could occur at runtime > for my driver: > > 1. I am 68K code and the completion routine field is a ProcPtr > 2. I am 68K code and the completion routine field is a UPP (either PPC or 68K > code fragment) > 3. I am PPC code and the completion routine field is a UPP (either PPC or 68K > code fragment) > 4. I am PPC code and the completion routine field is a ProcPtr (from a 68K, > non CFM68K app) >.... > Is it really that simple? Yes, it is. Look at almost any header. The proper way to call the completion proc is to define a set of macros (I bet they're already defined for CSAMs): #if ROUTINEDESCRIPTORS #define CallCSAMCompletionProc(proc, foo, bar) \ CallUniversalProc(proc, uppCSAMCompletionProcInfo, (foo), (bar)) #else #define CallCSAMCompletionProc(proc, foo, bar) \ ((proc)((foo), (bar)) #endif like so, look for more detail in any header. Just use CallCSAMCompletionProc() in your code. -Bill -- Bill Hofmann wdh@fresh.com Fresh Software and Instructional Design voice: +1 510 524 0852 1640 San Pablo Ave #C, Berkeley CA 94702 USA fax: +1 510 524 0853 +++++++++++++++++++++++++++ >From h+@metrowerks.com (Jon W{tte) Date: Fri, 18 Nov 1994 09:26:57 +0100 Organization: The Conspiracy In article , D_Gladstone@cs.auckland.ac.nz (David Gladstone) wrote: >1. I am 68K code and the completion routine field is a ProcPtr >2. I am 68K code and the completion routine field is a UPP (either PPC or 68K > code fragment) Here, just blithely jump to the address. Things will work, because the 68K code in the UPP includes the _MixedModeMagic trap. >3. I am PPC code and the completion routine field is a UPP (either PPC or 68K > code fragment) >4. I am PPC code and the completion routine field is a ProcPtr (from a 68K, > non CFM68K app) If the API says this is now a UPP field, then you have to call through with CallXXX() which will make sure that everything works. However, the way that the 68K CFM works (totally new glue libraries; can't use old headers) and PPC emulation works, the 68K CFM model will look just like the PPC model, i e do what you'd do on the PPC and you will be fine. That there is no architecture for CFM driver (and even less for PPC drivers) probably has something to do with it as well. Safest bet would be to write it in plain, non-CFM 68K code until the new driver architecture rolls around. Cheers, / h+ -- Jon Wätte (h+@metrowerks.com), Hagagatan 1, 113 48 Stockholm, Sweden "When I started hacking, we didn¹t have ones. We had to make do with zeros." ‹ Overheard by Andrew Craze +++++++++++++++++++++++++++ >From Bruce@hoult.actrix.gen.nz (Bruce Hoult) Date: Sat, 19 Nov 1994 01:43:04 +1300 (NZDT) Organization: (none) Jaeger@fquest.com (Brian Stern) writes: > I presume that > < NewRoutineDescriptor() must put 68K code at the beginning of all routine > < descriptors to handle this. > > Not Exactly. If you're on a PowerMac, drop into macsBug and type 'il > CopyBits'. CopyBits is native. What you'll see looks something like > this: > > 000C12AC TB E | AAFE > 000C12AE BTST D3,D0 | 0700 > 000C12B0 ORI.B #$00,D0 | 0000 0000 > 000C12B4 ORI.B #$00,D0 | 0000 0000 > 000C12B8 ORI.B #$BFC0,D3 | 0003 BFC0 > 000C12BC ORI.B #$04,D1 | 0001 0004 > 000C12C0 ORI.B #$2C10,A3 | 000B 2C10 > 000C12C4 ORI.B #$00,D0 | 0000 0000 > 000C12C8 ORI.B #$00,D0 | 0000 0000 > 000C12CC ORI.B #$A8EF,D0 | 0000 A8EF > > What you're looking at is the routine descriptor for Copybits. Notice > that the first word is AAFE. That's the mixedmodemagic trap. So when you > call copybits you're actually jumping to the mixedmodemagic trap. It > knows the location of the rest of the routine descriptor and gets the > information that it needs to jump to the appropriate code in the > appropriate mode. You're running an old version of Macsbug. My 6100 says: 000B6FAC _MixedModeMagic ; AAFE | AAFE 000B6FAE BTST D3,D0 | 0700 000B6FB0 ORI.B #$00,D0 | 0000 0000 000B6FB4 ORI.B #$00,D0 | 0000 0000 000B6FB8 ORI.B #$BFC0,D3 | 0003 BFC0 000B6FBC ORI.B #$04,D1 | 0001 0004 000B6FC0 ORI.B #$8A60,A2 ; '`' | 000A 8A60 000B6FC4 ORI.B #$00,D0 | 0000 0000 000B6FC8 ORI.B #$00,D0 | 0000 0000 000B6FCC ORI.B #$A8EF,D0 | 0000 A8EF -- Bruce --------------------------- End of C.S.M.P. Digest **********************