home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / csmpdigest / csmp-digest-v3-049 < prev    next >
Text File  |  2010-09-21  |  114KB  |  3,126 lines

  1. Received-Date: Mon, 8 Aug 1994 16:14:03 +0200
  2. From: pottier@clipper.ens.fr (Francois Pottier)
  3. Subject: csmp-digest-v3-049
  4. To: csmp-digest@ens.fr
  5. Date: Mon, 8 Aug 1994 16:13:56 +0200 (MET DST)
  6. X-Mailer: ELM [version 2.4 PL23]
  7. Mime-Version: 1.0
  8. Content-Type: text/plain; charset=ISO-8859-1
  9. Content-Transfer-Encoding: 8bit
  10. Errors-To: listman@ens.fr
  11. Reply-To: pottier@clipper.ens.fr
  12. X-Sequence: 54
  13.  
  14. C.S.M.P. Digest             Mon, 08 Aug 94       Volume 3 : Issue 49
  15.  
  16. Today's Topics:
  17.  
  18.         CODE resources 101
  19.         Can I do this with the Thread Manager?
  20.         Dice Rolling - answers
  21.         Easy file access functions [source]
  22.         How to detect whether Debugger is installed?
  23.         Q: Converting PB to FSSpec
  24.         Q: Reentrancy and PowerMac Runtime Model
  25.         Std filter proc trashes register D3!
  26.         Which NIM for serial port info?
  27.  
  28.  
  29.  
  30. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  31. (pottier@clipper.ens.fr).
  32.  
  33. The digest is a collection of article threads from the internet newsgroup
  34. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  35. regularly and want an archive of the discussions.  If you don't know what a
  36. newsgroup is, you probably don't have access to it.  Ask your systems
  37. administrator(s) for details.  If you don't have access to news, you may
  38. still be able to post messages to the group by using a mail server like
  39. anon.penet.fi (mail help@anon.penet.fi for more information).
  40.  
  41. Each issue of the digest contains one or more sets of articles (called
  42. threads), with each set corresponding to a 'discussion' of a particular
  43. subject.  The articles are not edited; all articles included in this digest
  44. are in their original posted form (as received by our news server at
  45. nef.ens.fr).  Article threads are not added to the digest until the last
  46. article added to the thread is at least two weeks old (this is to ensure that
  47. the thread is dead before adding it to the digest).  Article threads that
  48. consist of only one message are generally not included in the digest.
  49.  
  50. The digest is officially distributed by two means, by email and ftp.
  51.  
  52. If you want to receive the digest by mail, send email to listserv@ens.fr
  53. with no subject and one of the following commands as body:
  54.     help                        Sends you a summary of commands
  55.     subscribe csmp-digest Your Name    Adds you to the mailing list
  56.     signoff csmp-digest            Removes you from the list
  57. Once you have subscribed, you will automatically receive each new
  58. issue as it is created.
  59.  
  60. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  61. Questions related to the ftp site should be directed to
  62. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  63. digest are available there.
  64.  
  65. Also, the digests are available to WAIS users.  To search back issues
  66. with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
  67. http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
  68.  
  69.  
  70. -------------------------------------------------------
  71.  
  72. >From ikb_macd@ECE.Concordia.CA (Keith MacDonald)
  73. Subject: CODE resources 101
  74. Date: Fri, 15 Jul 1994 05:30:50 GMT
  75. Organization: ECE - Concordia University
  76.  
  77.  
  78. I'd like to be able to distribute files (aka plug-ins) to add features
  79. to a program I'm working on.  These files would (I assume) contain code 
  80. resources.  I've not been able to find any examples or clear description
  81. of what I need to do to achieve this.  I'm using Pascal, but I imagine
  82. C works in a similar manner.
  83.  
  84. Also related to code resources -
  85.     would it be possible to have a C PPC native code resource used by
  86.     a non-native (written in Think Pascal) application?
  87.  
  88. Thanks,
  89. Keith
  90. ..............................................................................
  91. Keith MacDonald                                   A bridge is not a high place 
  92. ikb_macd@ece.concordia.ca                               The fifty-second floor
  93. Computer Engineering                                         Icarus would know
  94. Concordia University                              A mountain isn't far to fall
  95. Montreal, QC, CANADA                          When you've fallen from the moon
  96.                                                                    - Marillion 
  97.  
  98. +++++++++++++++++++++++++++
  99.  
  100. >From mathews@ns9000.furman.edu (Owen Mathews)
  101. Date: 15 Jul 1994 17:03:44 GMT
  102. Organization: furman university computing center
  103.  
  104. Keith MacDonald (ikb_macd@ECE.Concordia.CA) wrote:
  105.  
  106. : I'd like to be able to distribute files (aka plug-ins) to add features
  107. : to a program I'm working on.  These files would (I assume) contain code 
  108. : resources.  I've not been able to find any examples or clear description
  109. : of what I need to do to achieve this.  I'm using Pascal, but I imagine
  110. : C works in a similar manner.
  111.  
  112. : Also related to code resources -
  113. :     would it be possible to have a C PPC native code resource used by
  114. :     a non-native (written in Think Pascal) application?
  115.  
  116. Using code resources to add functionality to an existing program doesn't
  117. require too much modification.  You can "call" a code resource just like
  118. calling a function (see code example below).  The main concept to under-
  119. stand is that code resources can be compiled from souce files just as
  120. an application can be.  The compiler should let you do this when you are
  121. setting all of the options for compiling and linking (in SC++, the menu
  122. option is "Set Project Type").  When the resource is called, the entry
  123. point is simply the main procedure of the file.
  124.  
  125. For more info, see IM.
  126.  
  127. ********************this code example was taken from
  128. ********************Think Reference, copyright Symantec corp.
  129.  
  130. // Calling a Code Resource
  131. // The following code illustrates how to call a
  132. // code resource.  The code resource that we
  133. // are calling is given at the end
  134.  
  135. // Assuming inclusion of <MacHeaders>
  136.  
  137. typedef void (*MyProcPtr) (int);      // Define a procedure pointer
  138.                                             // for the code resource
  139. void DoError (OSErr err);
  140. main ()
  141. {
  142.     Handle myCRHandle;
  143.     ProcPtr myCRPtr;
  144.     int    integerParam;
  145.  
  146.     myCRHandle = GetNamedResource ('ALCT', "\pmyBeep");
  147.     if (myCRHandle == nil)
  148.             DoError (ResError());
  149.     else
  150.     {
  151.             HLock (myCRHandle);
  152.             (* (MyProcPtr) (*myCRHandle)) (integerParam);
  153.             HUnlock (myCRHandle);
  154.     }
  155. }
  156.  
  157. /*********************************************
  158. Here is the code resource that we're calling
  159.  
  160. void main (int i)
  161. {
  162.     int j;
  163.  
  164.     for (j = 0; j < i; j++)
  165.             SysBeep (5);
  166. }
  167. **********************************************/
  168.  
  169.  
  170. : Also related to code resources -
  171. :     would it be possible to have a C PPC native code resource used by
  172. :     a non-native (written in Think Pascal) application?
  173.  
  174. PPC macs do not use the same kind of CODE resources that 68k macs do.
  175. Instead of keeping their program code in the resource fork, divided into 
  176. 32K segments, PowerMacs keep code in the *data* fork of a file.  It may
  177. be possible to call a PPC code chunk from a Pascal application (using the
  178. mixed-mode manager), but it will be a little different than calling a
  179. 68k code resource.
  180.  
  181. --       
  182.        Owen Mathews    mathews@furman.edu
  183.        <><><><><><><><><><><><><><><><><><><><>
  184.        Furman University, Computer Science Dept
  185.  
  186.  
  187. +++++++++++++++++++++++++++
  188.  
  189. >From tyen@netcom.com (Anthony Yen)
  190. Date: Sat, 16 Jul 1994 09:13:13 GMT
  191. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  192.  
  193. In article <306fhg$fl8@ns9000.furman.edu>,
  194. Owen Mathews <mathews@ns9000.furman.edu> wrote:
  195. >PPC macs do not use the same kind of CODE resources that 68k macs do.
  196. >Instead of keeping their program code in the resource fork, divided into 
  197. >32K segments, PowerMacs keep code in the *data* fork of a file.  It may
  198. >be possible to call a PPC code chunk from a Pascal application (using the
  199. >mixed-mode manager), but it will be a little different than calling a
  200. >68k code resource.
  201.  
  202. Hmm...several questions come to mind as I read this:
  203.  
  204. Has anyone seen how to support calling PPC-native code from within a
  205. PPC-native app?  And from within a fat-app?
  206.  
  207. If I append some application-specific data to the data fork of a
  208. fat-app, it won't confuse the loader or whatever else Apple might have
  209. in store for the data fork in the future, right?  <hope, hope, cross
  210. fingers>
  211.  
  212. Is there a convention for writing fat-code?  That is, can I just build
  213. a CODE resource for 68K, then do what I normally do to build a fat-app
  214. but wave the magic wand over the CODE resource instead, and append the
  215. PPC code onto that resource file and wind up with a fat-loadable code
  216. module?  If I can, is there a single calling convention for both
  217. loadable code modules (this refers back to my first question)?
  218.  
  219. Finally, the THINK Reference code sample appears to add two
  220. dereferences over the standard function call overhead when calling a
  221. code resource.  Is this correct?  If it is correct, in the grand
  222. scheme of things this would not matter, but I may get down to shaving
  223. cycles in the future and if so I may need to have all code resources
  224. locked down in memory and as fully dereferenced as possible.  Offhand,
  225. I see only one dereference I could avoid, by making sure the code
  226. resource is marked locked and getting a pointer out of the handle.
  227. But I'm getting a nagging feeling I'm missing something here...
  228. -- 
  229.  
  230. Anthony Yen <tyen@netcom.com>                           Austin, Texas, USA
  231.  
  232. +++++++++++++++++++++++++++
  233.  
  234. >From jwbaxter@olympus.net (John W. Baxter)
  235. Date: Sat, 16 Jul 1994 10:03:43 -0700
  236. Organization: Internet for the Olympic Peninsula
  237.  
  238. In article <tyenCt10A2.CsB@netcom.com>, tyen@netcom.com (Anthony Yen) wrote:
  239.  
  240. > In article <306fhg$fl8@ns9000.furman.edu>,
  241. > Owen Mathews <mathews@ns9000.furman.edu> wrote:
  242. > >PPC macs do not use the same kind of CODE resources that 68k macs do.
  243. > >Instead of keeping their program code in the resource fork, divided into 
  244. > >32K segments, PowerMacs keep code in the *data* fork of a file.  It may
  245. > >be possible to call a PPC code chunk from a Pascal application (using the
  246. > >mixed-mode manager), but it will be a little different than calling a
  247. > >68k code resource.
  248. > Hmm...several questions come to mind as I read this:
  249. > Has anyone seen how to support calling PPC-native code from within a
  250. > PPC-native app?  And from within a fat-app?
  251.  
  252. Widely available for some time now.
  253. Inside Mac: PowerPC System Software
  254. various "develop" articles
  255. various "MacTech" articles
  256.  
  257. > If I append some application-specific data to the data fork of a
  258. > fat-app, it won't confuse the loader or whatever else Apple might have
  259. > in store for the data fork in the future, right?  <hope, hope, cross
  260. > fingers>
  261.  
  262. The resource which tells the system where to look for the code fragment(s)
  263. provides for this.  But it's probably cleaner not to put variable-length
  264. data in there, or even mutable but fixed length data.
  265.  
  266. > Is there a convention for writing fat-code?  That is, can I just build
  267. > a CODE resource for 68K, then do what I normally do to build a fat-app
  268. > but wave the magic wand over the CODE resource instead, and append the
  269. > PPC code onto that resource file and wind up with a fat-loadable code
  270. > module?  If I can, is there a single calling convention for both
  271. > loadable code modules (this refers back to my first question)?
  272.  
  273. Above references.
  274.  
  275. -- 
  276. John Baxter    Port Ludlow, WA, USA  [West shore, Puget Sound]
  277.    No hablo Intel.
  278.    jwbaxter@pt.olympus.net
  279.  
  280. +++++++++++++++++++++++++++
  281.  
  282. >From winter@ai.rl.af.mil (Jim Wintermyre)
  283. Date: Tue, 19 Jul 1994 19:23:13 GMT
  284. Organization: Rome Laboratory
  285.  
  286. In article <CsyvBJ.Ku3@newsflash.concordia.ca>
  287. ikb_macd@ECE.Concordia.CA (Keith MacDonald) writes:
  288.  
  289. > to a program I'm working on.  These files would (I assume) contain code 
  290. > resources.  I've not been able to find any examples or clear description
  291. > of what I need to do to achieve this.  I'm using Pascal, but I imagine
  292.  
  293. Check out MacTech vol. 9 no. 9 (Sept 93), "External Code Modules in
  294. Pascal."  Also check out the tech note "Stand-Alone Code ad nauseum."
  295.  
  296. > Also related to code resources -
  297. >         would it be possible to have a C PPC native code resource used by
  298. >         a non-native (written in Think Pascal) application?
  299.  
  300. I believe so, but I'm not sure of the details.  Check out the Mixed
  301. Mode and Code Fragment Manager chapters in New Inside Mac: Power PC
  302. System Software.
  303.  
  304. Jim Wintermyre   (Opinions expressed are my own, of course)
  305.  
  306. winter@ai.rl.af.mil
  307. wintermyrej@lonex.rl.af.mil
  308.  
  309. ---------------------------
  310.  
  311. >From amundson@phenom.physics.wisc.edu (James F. Amundson)
  312. Subject: Can I do this with the Thread Manager?
  313. Date: Sat, 16 Jul 1994 21:05:16 -0600
  314. Organization: Division of Information Technology
  315.  
  316. Can someone tell me if what I have in mind is possible? I want to use the
  317. Thread Manager to give me basic preemptive multitasking without much
  318. thought.
  319.  
  320. My situation is this: I'm not writing a Mac application. I'm using Think C
  321. 7.0 to run scientific calculations. My programs are entirely ANSI C with
  322. no toolbox calls other than those from the Think C ANSI libraries. I'd
  323. like to be able to run the programs I write without taking over my mac
  324. while they run. In the past, I've hacked them to call WaitNextEvent
  325. occasionally. The problem is that it takes a fair amount of effort on my
  326. part to decide where and how often I need to call WNE. Since the nature of
  327. my work involves constantly changing the programs I'm writing, adjusting
  328. my calls to WNE every time is impractical. 
  329.  
  330. Can I use the Thread Manager without much effort? Are there any examples
  331. of this sort of thing?
  332.  
  333. Any advice will be appreciated.
  334.  
  335. Thanks,
  336.  
  337. Jim Amundson
  338.  
  339. +++++++++++++++++++++++++++
  340.  
  341. >From first.ascent@mindlink.bc.ca (Alex Curylo)
  342. Date: 17 Jul 1994 03:17:02 GMT
  343. Organization: MIND LINK! Communications Corp.
  344.  
  345. In article <amundson-1607942105160001@f180-186.net.wisc.edu>
  346. amundson@phenom.physics.wisc.edu (James F. Amundson) writes:
  347.  
  348. > Can I use the Thread Manager without much effort? Are there any examples
  349. > of this sort of thing?
  350.  
  351. Grab develop 17, and a copy of CodeWarrior 3.5. The latest iteration of
  352. PowerPlant includes a nice selection of thread classes. They're being
  353. used in a project I'm working on right now, and the fellow using them
  354. seems to have fairly positive regard for them. And for the rest of
  355. PowerPlant, as soon as they finish it ;)
  356.  
  357. +++++++++++++++++++++++++++
  358.  
  359. >From rmah@panix.com (Robert Mah)
  360. Date: Sun, 17 Jul 1994 00:53:05 -0500
  361. Organization: One Step Beyond
  362.  
  363. amundson@phenom.physics.wisc.edu (James F. Amundson) wrote:
  364.  
  365. ) I'm using Think C 7.0 to run scientific calculations. My programs are
  366. ) entirely ANSI C with no toolbox calls other than those from the Think
  367. ) C ANSI libraries. I'd like to be able to run the programs I write
  368. ) without taking over my mac while they run. In the past, I've hacked
  369. ) them to call WaitNextEvent occasionally. The problem is that it takes
  370. ) ...
  371. ) Can I use the Thread Manager without much effort? Are there any examples
  372. ) of this sort of thing?
  373.  
  374. Thread Manager can do pre-emptive threads, _but_ only on 68K Macs.  In
  375. addition, pre-emptive threads must obey the same rules as interupt level
  376. code.  I.e. no drawing, no moving memory, etc.
  377.  
  378. There's examples in Develop 17 that goes over using the Thread Mgr, but
  379. since using co-operative threads won't gain you much (you'll still have
  380. to call Yield() occaisionally) you should look at your code and see if
  381. you can use pre-emptive threads.
  382.  
  383. Cheers,
  384. Rob
  385. _____________________________________________________________________
  386. Robert S. Mah    :  Macintosh software development  :    212.947.6507
  387. One Step Beyond  :      and network consulting      :  rmah@panix.com
  388.  
  389. +++++++++++++++++++++++++++
  390.  
  391. >From gwatts@fnal.fnal.gov (Gordon Watts)
  392. Date: Mon, 18 Jul 1994 00:09:54 -0600
  393. Organization: Fermi Lab
  394.  
  395. In article <rmah-1707940053050001@rmah.dialup.access.net>, rmah@panix.com
  396. (Robert Mah) wrote:
  397.  
  398. > amundson@phenom.physics.wisc.edu (James F. Amundson) wrote:
  399. > ) I'm using Think C 7.0 to run scientific calculations. My programs are
  400. > ) entirely ANSI C with no toolbox calls other than those from the Think
  401. > ) C ANSI libraries. I'd like to be able to run the programs I write
  402. > ) without taking over my mac while they run. In the past, I've hacked
  403. > ) them to call WaitNextEvent occasionally. The problem is that it takes
  404. > ) ...
  405. > ) Can I use the Thread Manager without much effort? Are there any examples
  406. > ) of this sort of thing?
  407. > Thread Manager can do pre-emptive threads, _but_ only on 68K Macs.  In
  408. > addition, pre-emptive threads must obey the same rules as interupt level
  409. > code.  I.e. no drawing, no moving memory, etc.
  410. > There's examples in Develop 17 that goes over using the Thread Mgr, but
  411. > since using co-operative threads won't gain you much (you'll still have
  412. > to call Yield() occaisionally) you should look at your code and see if
  413. > you can use pre-emptive threads.
  414. > Cheers,
  415. > Rob
  416.  
  417. It depends upon what ANSI C library calls you make.  If you make calls to
  418. printf, etc. then the short answer is ... well, no.  Calls to things like
  419. sqrt, etc. are ok.  Basically, any call that will cause the screen to be
  420. drawn to or memory to be moved (malloc, etc.) will break with the
  421. pre-emptive threads.
  422.  
  423. There are two things you can do, if you still want to use the threads. 
  424. First, you can isolate your calls to printf and the like so they are never
  425. called in a preemptive thread (a thread is preemptive or cooperative when
  426. it is created, and cannot change during its lifetime).
  427.  
  428. Second, and perhaps simpler, is you can implement your calculation as a
  429. cooperative thread.  Sprinkle calls to "Yield()" all over the place, but
  430. don't worry too much about the placement.  Just make sure there are enough
  431. of them.  Now, in your main event loop you can put something like the
  432. following (this code has not been compiled/debugged!):
  433.  
  434. while (!gDone) {  // gDone will be set by your calc when it is finished...
  435.  
  436.   current_time = TickCount () + 30;  // Current time plus 1/2 a second
  437.  
  438.   while (current_time > TickCount ())
  439.     Yield ();  // Go off and do some real calculations for a 1/2 second
  440.  
  441.   WaitNextEvent (...);
  442. }
  443.  
  444. Excuse the formatting... You will incure dead time in the Yield call, I'm
  445. not sure how much speed you are trying to get out.  The fact that you are
  446. calling WaitNextEvent means that you are willing to give up some time... 
  447. This will require little modification to your current application, I
  448. suspect.
  449.  
  450. One bad thing about using threads if you have to figure out what your
  451. stack usage is before you run your calculation -- threads don't have a
  452. stack that grows as need be.  This might be bad if you are doing lattice
  453. calculations and allocate large arrays on the stack (do it globally at
  454. compile time or by malloc while running).
  455.  
  456. You can use all calls in cooperative threads, printf, malloc, etc. etc.
  457. and they will work on the powerpc.
  458.  
  459. Cheers,
  460.    Gordon (high energy physics).
  461.  
  462. -- 
  463. Gordon Watts -- gwatts@fnal.fnal.gov
  464.  
  465. +++++++++++++++++++++++++++
  466.  
  467. >From Dave Falkenburg <falken@apple.com>
  468. Date: Wed, 20 Jul 1994 16:43:41 GMT
  469. Organization: Apple Computer, Inc.
  470.  
  471. In article <gwatts-1807940009540001@slip113.fnal.gov> Gordon Watts,
  472. gwatts@fnal.fnal.gov writes:
  473. >while (!gDone) {  // gDone will be set by your calc when it is
  474. finished...
  475. >
  476. >  current_time = TickCount () + 30;  // Current time plus 1/2 a second
  477. >
  478. >  while (current_time > TickCount ())
  479. >    Yield ();  // Go off and do some real calculations for a 1/2 second
  480. >
  481. >  WaitNextEvent (...);
  482. >}
  483.  
  484.  
  485. GACK!
  486.  
  487. Please use a dynamic value for adjusting sleep timings like this: i.e.
  488. replace the "+30" with "+gRunQuantum", a value that is computed
  489. dynamically based on the compute power of the CPU.  The code above means
  490. that even if we make the MacOS 100x faster, you might limit the ability
  491. for the user to switch applications down to once every two seconds.
  492.  
  493. HALF A SECOND IS ALOT OF CPU TIME TO BE EATING without yielding control
  494. to other applications.
  495.  
  496. -Dave Falkenburg
  497. -Apple Computer, Inc.
  498.  
  499. ---------------------------
  500.  
  501. >From cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine)
  502. Subject: Dice Rolling - answers
  503. Date: Thu, 21 Jul 1994 08:12:12 -0700
  504. Organization: Ministry of Environment, Lands & Parks
  505.  
  506. Finally, after much fiddling and examining of code, I finally got my dice
  507. animation working in my game.  There is a trick to it.
  508.  
  509. Because many people helped me, I thought I would post what I found so that
  510. others can be helped too.
  511.  
  512. First, a little background.  I use 3 global GWorlds to hold (a) all six
  513. dice from a PICT resource, (b) the mask and (c) a working area.  This set
  514. up is similar to how john calhoun did his games like Glypa II.  As
  515. mentioned above, these are all global, so I can access them from
  516. anywhere.  I also use a custom window record structure that includes a
  517. GWorld which has the contents of the window in it.  This is used for
  518. really fast updates (See Mac Prog. Secrets, ch 6 for more details)
  519.  
  520. Now that all the GWorlds are set up and the items are in them, I use
  521. CopyMask (speed is not important in this game) to copy the dice from the
  522. diceWorld and the mask from the maskWorld to the workWorld. (with me so
  523. far?)  This is a simple call.  I use it twice as I have 2 dice I want to
  524. display and "roll".  I can then use CopyBits to copy the workWorld to my
  525. window's offscreen GWorld for updating purposes.  No problems here.
  526.  
  527. The trick comes when you want to copy the dice from the GWorld to the
  528. window.  When you use GWorlds, you always use GetGWorld and SetGWorld when
  529. copying from 1 GWorld to another.  However, if you use this when you want
  530. to copy to the window, CopyBits makes your Mac CRASH big time!! (I ran
  531. this in the debugger in THINK C 7.0.3 and I still couldn't get out. 
  532. cmd-opt-esc didn't do much, I had to restart.  I have an LCIII with 12MB
  533. RAM).  So what you have to do is use GetPort and SetPort when copying to
  534. the window.  This works without a hitch.  
  535.  
  536. I then use CopyMask as I did before to copy the dice to the workWorld and
  537. CopyBits to copy from the workWorld to the window.  This is still pretty
  538. fast despite the intermediate steps.  I've seen some code by Tony Myles
  539. that I got off of ftp.apple.com called CopyBits vs. CopyMask.  He uses
  540. CopyBits with a maskRgn to copy to the window.  This is much faster.  But
  541. like I said, I don't need speed.  Also, you can just plain elimate the
  542. intermate step and CopyMask directly to the window instead of the
  543. workWorld and then the window.
  544.  
  545. Thanks to many people on the Net for donating code (Ken Long) and help
  546. (Aaron Giles, Ingemar R., et al.) so that I can actually get this to work.
  547.  
  548. -- 
  549. ========================================================================
  550. Carl B. Constantine                  B.C. Environment, Lands & Parks
  551. End-User Support Analyst             CCONSTAN@epdiv1.env.gov.bc.ca
  552.  PGP Key available if you finger: CCONSTAN@EUSACBC.env.gov.bc.ca
  553.  
  554. +++++++++++++++++++++++++++
  555.  
  556. >From s828963@kub.nl (Peter Berck)
  557. Date: 22 Jul 1994 12:21:53 GMT
  558. Organization: KUB, The Netherlands
  559.  
  560. In article <cconstan-2107940812120001@eusacbc.env.gov.bc.ca>, cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine) writes:
  561. |> Finally, after much fiddling and examining of code, I finally got my dice
  562. |> animation working in my game.  There is a trick to it.
  563. |> 
  564. |> Because many people helped me, I thought I would post what I found so that
  565. |> others can be helped too.
  566. |> 
  567. [snip]
  568. |> 
  569. |> The trick comes when you want to copy the dice from the GWorld to the
  570. |> window.  When you use GWorlds, you always use GetGWorld and SetGWorld when
  571. |> copying from 1 GWorld to another.  However, if you use this when you want
  572. |> to copy to the window, CopyBits makes your Mac CRASH big time!! (I ran
  573. |> this in the debugger in THINK C 7.0.3 and I still couldn't get out. 
  574. |> cmd-opt-esc didn't do much, I had to restart.  I have an LCIII with 12MB
  575. |> RAM).  So what you have to do is use GetPort and SetPort when copying to
  576. |> the window.  This works without a hitch.  
  577.  
  578. Uhm? Are you sure? I am writing a program which also has an offscreen
  579. GWorld which is copied to the screen (using CopyBits) when necessary.
  580. I use SetGWorld and GetGWorld all the time. In fact, NIM:Imaging with
  581. QuickDraw mentions somewhere (don't have it on me, so I can't give you
  582. the page number) that you should use SetGWorld/GetGWorld instead of
  583. GetPort and SetPort.
  584.  
  585. Now I'm slightly confused. I have just started to use GWorld stuff,
  586. and I was pretty sure that Get/SetGWorld was all I needed, so if any
  587. macguru can enlighten me I'd be very grateful...
  588.  
  589. -Peter
  590.  
  591. - ----------------------------------------------------------------
  592. P.J.Berck@kub.nl                             pgp-pubkey on request
  593. (format t "~&~{~<~%~1:;~a~>~^,~}.~%"
  594.    '(DoD#-337 The-Ex Sonic-Youth NIN Dante-Alighieri Guinness))
  595.  
  596. +++++++++++++++++++++++++++
  597.  
  598. >From cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine)
  599. Date: Fri, 22 Jul 1994 11:30:50 -0700
  600. Organization: Ministry of Environment, Lands & Parks
  601.  
  602. In article <30odl1$7ro@kubds1.kub.nl>, P.J.Berck@kub.nl wrote:
  603.  
  604. > In article <cconstan-2107940812120001@eusacbc.env.gov.bc.ca>,
  605. cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine) writes:
  606. > |> Finally, after much fiddling and examining of code, I finally got my dice
  607. > |> animation working in my game.  There is a trick to it.
  608. > |> 
  609. > |> Because many people helped me, I thought I would post what I found so that
  610. > |> others can be helped too.
  611. > |> 
  612. > [snip]
  613. > |> 
  614. > |> The trick comes when you want to copy the dice from the GWorld to the
  615. > |> window.  When you use GWorlds, you always use GetGWorld and SetGWorld when
  616. > |> copying from 1 GWorld to another.  However, if you use this when you want
  617. > |> to copy to the window, CopyBits makes your Mac CRASH big time!! (I ran
  618. > |> this in the debugger in THINK C 7.0.3 and I still couldn't get out. 
  619. > |> cmd-opt-esc didn't do much, I had to restart.  I have an LCIII with 12MB
  620. > |> RAM).  So what you have to do is use GetPort and SetPort when copying to
  621. > |> the window.  This works without a hitch.  
  622. > Uhm? Are you sure? I am writing a program which also has an offscreen
  623. > GWorld which is copied to the screen (using CopyBits) when necessary.
  624. > I use SetGWorld and GetGWorld all the time. In fact, NIM:Imaging with
  625. > QuickDraw mentions somewhere (don't have it on me, so I can't give you
  626. > the page number) that you should use SetGWorld/GetGWorld instead of
  627. > GetPort and SetPort.
  628. > Now I'm slightly confused. I have just started to use GWorld stuff,
  629. > and I was pretty sure that Get/SetGWorld was all I needed, so if any
  630. > macguru can enlighten me I'd be very grateful...
  631.  
  632. It crashed my mac considerably.  However, I'm piggybacking a GWorldPtr
  633. onto a custom windowRecord structure.  this may be why it's crashing.  I'm
  634. not sure, I haven't tested it otherwise (I don't have NIM: Imaging).  I'd
  635. have to test.
  636.  
  637. I have it off hand from a good source (Aaron Giles, writer of JPEGView)
  638. that you SHOULD always used GetGWorld & SetGWorld.  I'm not sure why it
  639. was crashing in my system, but it was so I left it with GetPort & SetPort.
  640.  
  641. Hope this helps.
  642.  
  643. -- 
  644. ========================================================================
  645. Carl B. Constantine                  B.C. Environment, Lands & Parks
  646. End-User Support Analyst             CCONSTAN@epdiv1.env.gov.bc.ca
  647.  PGP Key available if you finger: CCONSTAN@EUSACBC.env.gov.bc.ca
  648.  
  649. +++++++++++++++++++++++++++
  650.  
  651. >From kenlong@netcom.com (Ken Long)
  652. Date: Sat, 23 Jul 1994 14:24:16 GMT
  653. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  654.  
  655. Here are some fragments/snippets from Mark Hanrek, on the subjuct, ala 
  656. NuCube (some names changed for another program):
  657.  
  658. - -----------
  659. WindowPtr starsWindow;        // Windows and GWorlds are the same thing, so
  660. GWorldPtr gOffscreenGWorld; // use only Get/SetGWorld calls in 
  661.                 // this app.screen" area in the window
  662. Rect gOffscreenRect;        // The offscreen rect's upper-left is 0,0
  663. Rect gProjectionRect;        // The projection Rect
  664.  
  665. //*******************************************************************//
  666. //  Create window, offscreen GWorld, and one control for starters     //
  667. //*******************************************************************//
  668.  
  669. void SetupWindow (void) 
  670. {
  671.     Rect    tempRect;
  672.     
  673.     //------ Set up our main window, man
  674.  
  675.     starsWindow = GetNewWindow (rWIND, nil, (WindowPtr) -1L);
  676.     
  677.     SetPort (starsWindow);
  678.     ShowWindow (starsWindow);
  679.  
  680.     SetRect (&gProjectionRect, kHorizOffset, kVertOffset,  
  681.           kHorizOffset+kCubeSide, kVertOffset+kCubeSide);
  682.  
  683.     //% Set up an offscreen GWorld for preparing the next cube's image.
  684.     SetRect (&gOffscreenRect, 0, 0, kCubeSide, kCubeSide);
  685.     
  686.     gOffscreenGWorld = CreateOffscreenGWorld (&gOffscreenRect);
  687.     
  688. }
  689.  
  690. void RotateCubeOnce (void)
  691. {
  692.     long            ticksNow;
  693.     GWorldPtr        windowGW;
  694.     GDHandle        windowGD;
  695.     PixMapHandle    thePixMap;
  696.  
  697.     GetGWorld (&windowGW, &windowGD);     // Save whatever we had before
  698.  
  699.     SetGWorld (gOffscreenGWorld, nil);
  700.  
  701.     if (LockPixels (thePixMap = GetGWorldPixMap (gOffscreenGWorld)))
  702.     {
  703.         EraseRect (&gOffscreenGWorld->portRect);
  704.  
  705.     //======================================================
  706.     (action)
  707.     //======================================================
  708.     //
  709.     //  Always set the current port to a window's port before 
  710.     // drawing from
  711.     //  a GWorld, so that the Window Manager can "clip" the 
  712.     // image properly
  713.     //  should there be other windows in front. Comment out 
  714.     // the next statement
  715.     //  and notice what happens when you drag another window in front of 
  716.     //  the NuCube window.  :)
  717.     //
  718.         
  719.     SetGWorld (windowGW, windowGD);  // Focus on a real window
  720.  
  721.     CopyBits ((BitMapPtr)*thePixMap, 
  722.           (BitMapPtr)&starsWindow->portBits, 
  723.            &gOffscreenRect, 
  724.            &gProjectionRect, srcCopy, nil);
  725.  
  726.     UnlockPixels (thePixMap);
  727.     }
  728.     SetGWorld (windowGW, windowGD); // Okay if this is redundant
  729. }
  730.  
  731. //*******************************************************************//
  732. //  Use the following function for the rest of your programming      
  733. //  days. 
  734. //  Do not alter it in any way. It is a complete functional unit
  735. //  doing all REQUIRED things.
  736. //*******************************************************************//
  737.  
  738. GWorldPtr CreateOffscreenGWorld (Rect *theRect)
  739. {
  740.     CGrafPtr    currentPort;
  741.     GDHandle    currentGDevice;
  742.     GWorldPtr   offScreen;
  743.     QDErr       result;
  744.  
  745.     GetGWorld (¤tPort, ¤tGDevice);
  746.     
  747.     //-- If there is not enough application memory, try MultiFinder 
  748.     //-- temporary memory.
  749.     
  750.     if ((result = NewGWorld (&offScreen, 0, theRect, nil, nil, 0L)) 
  751.         != noErr)
  752.         if ((result = NewGWorld (&offScreen, 0, theRect, nil, 
  753.             nil, useTempMem)) != noErr)
  754.             return (nil);
  755.             
  756.     SetGWorld (offScreen, nil);
  757.     
  758.     //-- Initialize the clipping "hole" to be the same as the 
  759.     //-- drawing area.
  760.  
  761.     ClipRect (&offScreen->portRect);    
  762.  
  763.     //-- The GWorld has random stuff in it, so we'll erase it to 
  764.     //-- white.
  765.     
  766.     if (LockPixels (GetGWorldPixMap (offScreen)))
  767.     {
  768.         ForeColor (blackColor);
  769.         BackColor (whiteColor);
  770.         EraseRect (&offScreen->portRect);
  771.         UnlockPixels (GetGWorldPixMap (offScreen));
  772.     }
  773.  
  774.     SetGWorld (currentPort, currentGDevice);
  775.     return offScreen;
  776. }
  777.  
  778. //*******************************************************************//
  779. // Shut down with charm, grace and decorum.
  780. //*******************************************************************//
  781.  
  782. void MoveAlongHome (void) 
  783. {
  784.     DisposeWindow (starsWindow);        // Not "CloseWindow"
  785.     DisposeGWorld (gOffscreenGWorld); 
  786. }
  787.  
  788. - --------------
  789. That's all, folks.
  790.  
  791. -Ken-
  792.  
  793. ---------------------------
  794.  
  795. >From rkwee@ee.pdx.edu (Roland Kwee)
  796. Subject: Easy file access functions [source]
  797. Date: 18 Jul 1994 20:35:28 -0700
  798. Organization: (none)
  799.  
  800. Some days ago I promised to upload some source code that makes handling
  801. Mac file functions as easy as the standard ANSI C library functions.
  802. Hopefully I didn't leave out code that is essential to understand and
  803. use my little system.
  804.  
  805. Here is my Macintosh ThinkC source code for accessing files pretty much like
  806. with the ANSI C library functions. Hopefully the code is sufficiently
  807. commented to be understandible. Note that there is a test function that
  808. demonstrates how to use the other functions.
  809.  
  810. Please let me know if this is useful, understandable, and if you see
  811. problems or improvements.
  812.  
  813. --Roland Kwee         email: RolandKwee@ACM.org
  814.  
  815. /*----------------------------------------------------------------------------------
  816.  * globals.h    Roland Kwee    May 25, 1994
  817.  * This file contains the declarations for the application-specific global data. 
  818.  *
  819.  * A good strategy may be to declare a number of global variables in a single
  820.  * structure. With the menu options, the user can change one or more of these
  821.  * global settings. These settings are global to allow easy access by the
  822.  * functions that actually perform tasks. By keeping them in a single
  823.  * structure, they are easy to keep track of.
  824.  *----------------------------------------------------------------------------------
  825.  */
  826.  
  827. #ifndef __GLOBALS_H__
  828. #define __GLOBALS_H__
  829.  
  830. enum Creators{CREATOR='TrRK'};
  831.  
  832. enum FileTypes{UNKNOWN, PostScript, Binary, 
  833.     TextDos, TextUnix, TextMac, 
  834.     Hathaway, Rochester, RochesterHeader, BEN5000, 
  835.     PPSM, Support, Spreadsheet};
  836.  
  837. /* This structure communicates user input to the process. */
  838. struct Option_s{
  839.     int Quit;
  840.     int SeparateDigCh, OutputType, LPFcorrection, DiagnosticWindow, ProgressDialog, Fast;
  841.     int debug, test_partly;   /* default: 0 (no debug output). */
  842.     void *OpenFileList, *PrintFileList;
  843.     float TimeZoneHourOffset;
  844.     char DefaultLocation[5];
  845. };
  846.  
  847. extern struct Option_s Option;
  848.  
  849. #endif /* __GLOBALS_H__ */
  850.  
  851.  
  852.  
  853.  
  854. /* MacFile.h   Roland Kwee   June 1, 1994 
  855.  * Functions to make handling files on the Mac almost as easy as in Unix.
  856.  * This will make it possible to port programs between Unix and the Mac.
  857.  */
  858.  
  859.  
  860. #ifndef _MACUTIL_H__
  861. #define _MACUTIL_H__
  862.  
  863. #include <stdio.h>
  864. #include <stdlib.h>
  865. #include <string.h>
  866. #include <errno.h>
  867.  
  868. //==============
  869. // Project Info:
  870. //==============
  871. // compiler: Symantec C++ for Macintosh, 1994, ThinkC (version 7 ?)
  872. // libraries: MacTraps, SANE, ANSI
  873.  
  874. // Executable:
  875. // file name: Translate
  876. // File Type: APPL, Creator: TrRK
  877.  
  878. // Compiler settings:
  879. // int: 2 bytes
  880. // float: 4 bytes
  881. // double: 8 bytes
  882. // don't use the "native" floating point format
  883. #if __option(native_fp)
  884. #error Don't use the "native" floating point format (Edit/Options/Compiler settings).
  885. #endif
  886. // printf can only handle float and doubles if double is not set to 8 bytes:
  887. #if __option(double_8)
  888. #error Don't set doubles to 8 bytes (Edit/Options/Compiler settings).
  889. #endif
  890. // REASONS FOR FLOATING POINT SETTINGS:
  891. // The input file has IEEE double numbers, but the input routine is able to convert these
  892. // to Mac format using the Mac type `short double' which is equal to IEEE double.
  893. // The library function printf is compiled with the standard settings, so the formats for
  894. // floating point will work incorrectly if the program is compiled with the `8-byte doubles' option.
  895. // Better not to recompile the library, so set all floating point options to Mac standard.
  896.  
  897.  
  898.  
  899. /* ===============definitions for byte order ===================== */
  900. enum {BigEndian /* Motorola, VAX */, LittleEndian /* Intel */};
  901.                             
  902. //extern int     computerbyteorder;
  903. #define computerbyteorder BigEndian
  904.  
  905. /*=========================== TIME ZONE ============================*/
  906. /* This should be a menu option. For now it is constant. 
  907.  * Valid values are -12.0 .. 12.0. Positive is East of Greenwich.
  908.  * Simple fractions like 9.5 (Adelaide, Australia) should work.
  909.  */
  910. #define TZ -7
  911.  
  912. /* This global can be used with sprintf to prepare a string to pass to Log(). */
  913. extern char buf[1000];
  914.  
  915. void Log(char *msg);
  916. void SystemError(char *msg, char *source, int code);
  917. void Warn(char *msg);
  918. char *PtoCstrPtr(void *Pstring);
  919. void LtoCstr(OSType l, char *s);
  920. char *FSStoCstrPtr(FSSpec *file);
  921. char *GetBaseName(FSSpec *file);
  922. char *GetFullPathName(FSSpec *file);
  923. void GetFullPath(int VolumeSpec, long ParentDirID, char *fullPath);
  924. int FSSpecRoutinesAvail(void);
  925. FSSpec *select_input_file(const int numTypes, SFTypeList myTypes);
  926. FSSpec *select_output_file(const char *prompt, const char *defname);
  927. void FinderInfo(FSSpec *fs);
  928. void PathInfo(FSSpec *fs);
  929. char *GetVolumeName(FSSpec *fs);
  930. void VolumeInfo(FSSpec *fs);
  931. void TestPathUtils(void);
  932.  
  933. #if 0    /* See Mac include file <files.h> */                                                                      
  934. struct FSSpec {                                                           
  935.     short vRefNum;                                                        
  936.     long parID;                                                           
  937.     Str63 name;                                                           
  938. };                                                                                                                                                  
  939. typedef struct FSSpec FSSpec;                                             
  940. typedef FSSpec *FSSpecPtr, **FSSpecHandle;                                                                                                          
  941. typedef FSSpecPtr FSSpecArrayPtr;       /* pointer to array of FSSpecs */ 
  942. #endif
  943.  
  944. typedef struct{
  945.     int     in_use;    /* To maintain the file table. */
  946.     FSSpec     fss;    /* Specification of the (closed) file selected with a dialog. */
  947.     short    refnum; /* Reference number, or access path of the open file. */
  948.     int        byteorder;
  949. }MacFILE;
  950.  
  951. /* This structure is currently only used to hold the year of a file.
  952.  * It doesn't really matter whether last access or last modify.
  953.  */
  954. struct MacStat{
  955.    long     st_size;       /* total size of file, in bytes */ 
  956.    int        year;
  957. #if 0 
  958.    time_t    st_atime;      /* file last access time */         
  959.    time_t    st_mtime;      /* file last modify time */         
  960.    time_t    st_ctime;      /* file last status change time */  
  961. #endif    
  962. };
  963.  
  964. #define File         MacFILE
  965. #define FileRead     macfread
  966. #define FWRITE        macfwrite
  967. #define FSEEK       macfseek
  968. #define FSTAT        macfstat
  969. #define STAT_T      struct MacStat
  970.  
  971. MacFILE *macftype(FSSpec *selection, long creator, long type);
  972. MacFILE *macfopen(FSSpec *selection, char *mode);
  973. int macfclose(MacFILE *fp);
  974. int macfread(void *buf, size_t recsize, size_t recnum, MacFILE *fp);
  975. int macfwrite(void *buf, size_t recsize, size_t recnum, MacFILE *fp);
  976. int macfseek(MacFILE *fp, long offset, int whence);
  977. long macftell(MacFILE *fp);
  978. int macfstat(MacFILE *fp, struct MacStat *buf);
  979. void copy_file(MacFILE *fp_in, MacFILE *fp_out);
  980. int TestFileType(MacFILE *fp);
  981. void TestFileUtils(void);
  982. void BetterMoveWindow(WindowPtr wp, float right, float down);
  983.  
  984. void SwapN(void *buf, int n);
  985. int NeedSwap(MacFILE *fp, void *buf, int n);
  986.  
  987. char GetInputByte(File *fp); // Reads and returns one byte.
  988. int  GetInputInt(File *fp); // Reads, converts and returns one integer.
  989. long GetInputLong(File *fp);
  990. unsigned long GetInputULong(File *fp);
  991. float GetInputFloat(File *fp);
  992. double GetInputDouble(File *fp); /* reads IEEE 8-byte double, returns Mac double. */
  993.  
  994. /* GetInputString - Reads a string and returns a null-terminated C-string.
  995.                     Reading stops when a '\0' char,  or `size' characters have
  996.                     been read. A '\0' is added.
  997. If you are certain that the string to read is terminated with a '\0', 
  998. then `size' can be the size of the buffer. Otherwise, the buffer needs to be 
  999. one character bigger, to hold the added '\0'.
  1000. */
  1001. char *GetInputString(char *buf, int size, File *fp);
  1002.  
  1003. /* GetInputNString - Reads n characters and returns a string in str. 
  1004.                     str needs to have room for an additional '\0'. */
  1005. char *GetInputNString(char *str, int n, File *fp);
  1006.  
  1007. /* SwapN - swaps n bytes of buf in place */
  1008. void SwapN(void *buf, int n);
  1009.  
  1010.  
  1011. // Writes a C string to the output file.
  1012. int WriteTxt(File *fp, char *str);
  1013.  
  1014. // Writes bytes to a binary output file.
  1015. int WriteBin(File *fp, void *buf, int size);
  1016.  
  1017. // Specialized functions to write data, argument may be a constant
  1018. void WriteULong(File *fp, unsigned long x);
  1019. void WriteLong(File *fp, long x);
  1020. void WriteShort(File *fp, signed short x);
  1021.  
  1022. #endif /* _MACUTIL_H__ */
  1023.  
  1024.  
  1025. /* MacFile.c   Roland Kwee   June 1, 1994 
  1026.  * Functions to make handling files on the Mac almost as easy as in Unix.
  1027.  * This will make it possible to port programs between Unix and the Mac.
  1028.  */
  1029.  
  1030. #include "MacFile.h"
  1031. #include "globals.h"
  1032. #include <GestaltEqu.h>
  1033. #include <console.h> /* cshow() */
  1034.  
  1035. /* This global can be used with sprintf to prepare a string to pass to Log(). */
  1036. char buf[1000];
  1037.  
  1038. /*----------------------------------------------------------------------------------
  1039.  * Log() - Diagnostic output. Adds a newline at the end.
  1040.  *----------------------------------------------------------------------------------*/
  1041. void Log(char *msg){
  1042.     if(Option.debug)
  1043.         puts(msg);
  1044.     return;
  1045. }
  1046.  
  1047. /*----------------------------------------------------------------------------------
  1048.  * SystemError() - Error output. Should be a alert box.
  1049.  *----------------------------------------------------------------------------------*/
  1050. void SystemError(char *msg, char *source, int code){
  1051.  
  1052.     /* Force visible output. */
  1053.     if(!Option.debug){
  1054.         Option.debug=1;
  1055.         cshow(stdout);
  1056.     }
  1057.     
  1058.     sprintf(buf, "Error: %s%s%s code: %d", msg, source?" in function: ":"",
  1059.         source?source:"", code);
  1060.     Log(buf);
  1061.     
  1062.     return;
  1063. }
  1064.  
  1065. /*----------------------------------------------------------------------------------
  1066.  * Warn() - Warning output.
  1067.  *
  1068.  * Should be a modal dialog box IF the diagnostic window is closed.
  1069.  * Or, there should be an option to suppress the modal dialog box to
  1070.  * allow unattended transfer of large batches of files.
  1071.  *
  1072.  *----------------------------------------------------------------------------------*/
  1073. void Warn(char *msg){
  1074.     Log(msg);
  1075.     return;
  1076. }
  1077.  
  1078. /*----------------------------------------------------------------------------------
  1079.  * PtoCstrPtr() - Converts a Pascal string to a pointer to a C String.
  1080.  *                The string the pointer points to is reused for each new call.
  1081.  *----------------------------------------------------------------------------------*/
  1082. char *PtoCstrPtr(void *Pstring){
  1083.     static char Cstring[257];
  1084.     char *str;
  1085.     int i, max;
  1086.     
  1087.     str=Pstring;
  1088.     max=str[0];
  1089.     memcpy(Cstring, str+1, max);
  1090.     Cstring[max]='\0';
  1091.     return Cstring;
  1092. }
  1093.  
  1094. /*----------------------------------------------------------------------------------
  1095.  * LtoCstr() - Converts an OSType (long) to a C-string (char[5]).
  1096.  *----------------------------------------------------------------------------------*/
  1097. void LtoCstr(OSType l, char *s){
  1098.     //sprintf(buf, "LtoCstr: 0x%08X", l); Log(buf); 
  1099.     memcpy(s, (char*)&l, 4);
  1100.     s[4]='\0';
  1101.     return;
  1102. }
  1103.  
  1104. /*----------------------------------------------------------------------------------
  1105.  * FSStoCstrPtr() - Converts a FSS file specification to a C string.
  1106.  *                The string the pointer points to is reused for each new call.
  1107.  * See: New Inside Mac, "Files", p. 2-45: Constructing Full Pathnames, Listing 2-5.
  1108.  *----------------------------------------------------------------------------------*/
  1109. char *FSStoCstrPtr(FSSpec *file){
  1110.     static char    fullPath[300];
  1111.     CInfoPBRec    myPB;
  1112.     Str255         dirName;
  1113.     OSErr        myErr;
  1114.     
  1115.     strcpy(fullPath, PtoCstrPtr(file->name));/* Start with base file name. */
  1116.     myPB.dirInfo.ioNamePtr=dirName;            /* Output buffer for PBGetCatInfo(). */
  1117.     myPB.dirInfo.ioVRefNum=file->vRefNum;    /* Volume ID */
  1118.     myPB.dirInfo.ioDrParID=file->parID;        /* Initialize parent dir. */
  1119.     myPB.dirInfo.ioFDirIndex= -1;            /* <0: Use ioDrDirID as input. */
  1120.     myPB.dirInfo.ioCompletion=NULL;
  1121.     for(    myPB.dirInfo.ioDrDirID=file->parID; 
  1122.             myPB.dirInfo.ioDrDirID!=fsRtDirID;
  1123.             myPB.dirInfo.ioDrDirID=myPB.dirInfo.ioDrParID){
  1124.         myErr=PBGetCatInfo(&myPB, FALSE);
  1125.         if(myPB.dirInfo.ioResult==noErr){
  1126.             strcat(fullPath, ":");
  1127.             strcat(fullPath, PtoCstrPtr(dirName));
  1128.         }else
  1129.             break;
  1130.     }
  1131.     return fullPath;
  1132. }
  1133.  
  1134. /*----------------------------------------------------------------------------------
  1135.  * GetBaseName() - Converts a FSS file specification to a C string containing
  1136.  *                 the base file name, i.e., without the path.
  1137.  * The string the pointer points to is reused for each new call.
  1138.  *----------------------------------------------------------------------------------*/
  1139. char *GetBaseName(FSSpec *file){
  1140.     static char fullPath[100];                            /* Semi-permanent, reused. */
  1141.     
  1142.     strcpy(fullPath, PtoCstrPtr(file->name));            /* Add file name.  */
  1143.     return fullPath;                                    /* Return pointer. */
  1144. }
  1145.  
  1146. /*----------------------------------------------------------------------------------
  1147.  * GetFullPathName() - Converts a FSS file specification to a C string containing
  1148.  *                     the full path and the file name.
  1149.  *                     The string the pointer points to is reused for each new call.
  1150.  * See: New Inside Mac, "Files", p. 2-45: Constructing Full Pathnames, Listing 2-5.
  1151.  *----------------------------------------------------------------------------------*/
  1152. char *GetFullPathName(FSSpec *file){
  1153.     static char fullPath[1000];                            /* Semi-permanent, reused. */
  1154.     
  1155.     strcpy(fullPath, GetVolumeName(file));                /* Start with disk name. */
  1156.     strcat(fullPath, ":");                                /* Path always ends with colon. */
  1157.     GetFullPath(file->vRefNum, file->parID, fullPath);    /* Find full path. */
  1158.     strcat(fullPath, PtoCstrPtr(file->name));            /* Add file name.  */
  1159.     return fullPath;                                    /* Return pointer. */
  1160. }
  1161.  
  1162. /*----------------------------------------------------------------------------------
  1163.  * GetFullPath() - Returns full path name (without file name) in fullPath. Recursive.
  1164.  *
  1165.  * See: New Inside Mac, "Files", p. 2-45: Constructing Full Pathnames, Listing 2-5.
  1166.  * Because strcat() cannot handle overlapping strings, recursion is easier than
  1167.  * an iteration. The parts of the path are pasted together AFTER all parts are found. 
  1168.  *----------------------------------------------------------------------------------
  1169.  */
  1170. void GetFullPath(int VolumeSpec, long ParentDirID, char *fullPath){
  1171.     Str255         dirName;
  1172.     CInfoPBRec    myPB;
  1173.     OSErr        myErr;
  1174.  
  1175.     myPB.dirInfo.ioVRefNum=VolumeSpec;
  1176.     myPB.dirInfo.ioDrDirID=ParentDirID;
  1177.     myPB.dirInfo.ioFDirIndex= -1;            /* <0: Use ioDrDirID as input. */
  1178.     myPB.dirInfo.ioCompletion=NULL;
  1179.     myPB.dirInfo.ioNamePtr=dirName;            /* Output buffer for PBGetCatInfo(). */
  1180.     myErr=PBGetCatInfo(&myPB, FALSE);        /* receive parent dir in dirName */
  1181.     if(myErr==noErr){
  1182.         if(myPB.dirInfo.ioDrParID!=fsRtDirID)    /* This is the root dir ID. */
  1183.             GetFullPath(VolumeSpec, myPB.dirInfo.ioDrParID, fullPath); /* RECURSION */
  1184.         strcat(fullPath, PtoCstrPtr(dirName));     /* paste parent to ancestors */
  1185.         strcat(fullPath, ":");                    /* Path always ends with colon. */
  1186.     }
  1187.     return;
  1188. }
  1189.  
  1190. /*----------------------------------------------------------------------------------
  1191.  * FSSpecRoutinesAvail() - Returns true if the FSS functions are available.
  1192.  *----------------------------------------------------------------------------------
  1193.  */
  1194. int FSSpecRoutinesAvail(void){
  1195.     OSErr        myErr = !noErr;
  1196.     long        myFeature;
  1197.     int            avail=0;
  1198.     
  1199.     if(1/*gHasGestalt()*/){
  1200.         myErr=Gestalt(gestaltFSAttr, &myFeature);
  1201.         if(myErr==noErr && (myFeature & gestaltHasFSSpecCalls))
  1202.             avail=1;
  1203.         else
  1204.             Log("Gestalt error");
  1205.     }else
  1206.         Log("Gestalt is not available");
  1207.         
  1208.     if(avail)
  1209.         Log("FSS Routines Available");
  1210.         
  1211.     return avail;
  1212. }
  1213.  
  1214. /*----------------------------------------------------------------------------------
  1215.  * select_input_file() - Allows the user to select an input file with a standard dialog box.
  1216.  *                       If numTypes == -1, all file types are displayed.
  1217.  *                       Returns: pointer to FSS record, or NULL on error or cancel.
  1218.  * See: New Inside Mac, "Files", p. 1-19: Opening a File, Listing 1-6.
  1219.  *----------------------------------------------------------------------------------*/
  1220. FSSpec *select_input_file(const int numTypes, SFTypeList myTypes){
  1221.     static StandardFileReply myReply;
  1222.     OSErr myErr=noErr;
  1223.     
  1224.     StandardGetFile(NULL, numTypes, myTypes, &myReply);
  1225.     if(myReply.sfGood){
  1226.         char type[5];
  1227.         LtoCstr(myReply.sfType, type);
  1228.         sprintf(buf, "select_input_file: Type: %s", type); Log(buf);
  1229.         return &myReply.sfFile;
  1230.     }else
  1231.         return NULL;
  1232. }
  1233.  
  1234. /*----------------------------------------------------------------------------------
  1235.  * select_output_file() - Allows the user to select an output file with a standard dialog box.
  1236.  *                        Returns: pointer to FSS record, or NULL on error or cancel.
  1237.  *----------------------------------------------------------------------------------*/
  1238. FSSpec *select_output_file(const char *prompt, const char *defname){
  1239.     Str255 Pprompt, Pdefname;
  1240.     static StandardFileReply myReply;
  1241.     OSErr myErr=noErr;
  1242.     
  1243.     strcpy((char *)Pprompt, prompt); CtoPstr((char *)Pprompt);    
  1244.     strcpy((char *)Pdefname, defname); CtoPstr((char *)Pdefname);    
  1245.     /* The cursor is set to an I-beam to edit the file name in the 
  1246.      * dialog box. Reset it to the default arrow. */
  1247.     StandardPutFile(Pprompt, Pdefname, &myReply);
  1248.     InitCursor();
  1249.     if(myReply.sfGood){
  1250.         return &myReply.sfFile;
  1251.     }else
  1252.         return NULL;
  1253. }
  1254.  
  1255. /*----------------------------------------------------------------------------------
  1256.  * FinderInfo() - Test output of Finder Info of a file: creator, type...
  1257.  *----------------------------------------------------------------------------------*/
  1258. void FinderInfo(FSSpec *fs){
  1259.     OSErr        myErr;
  1260.     FInfo        fndrInfo;
  1261.     char        creator[5], type[5];
  1262.     
  1263.     myErr=FSpGetFInfo(fs, &fndrInfo);
  1264.     LtoCstr(fndrInfo.fdType, type);
  1265.     LtoCstr(fndrInfo.fdCreator, creator);
  1266.     
  1267.     Log("-------------------------");
  1268.     strcpy(buf, "Getting Finder Info: ");
  1269.     switch(myErr){
  1270.     case noErr:    strcat(buf, "No error"); break;
  1271.     case nsvErr:   strcat(buf, "No such volume"); break;
  1272.     case ioErr:    strcat(buf, "I/O error"); break;
  1273.     case bdNamErr: strcat(buf, "Bad filename"); break;
  1274.     case fnfErr:   strcat(buf, "File not found"); break;
  1275.     case paramErr: strcat(buf, "No default volume"); break;
  1276.     case dirNFErr: strcat(buf, "Directory not found or incomplete pathname"); break;
  1277.     case afpAccessDenied: strcat(buf, "User does not have the correct access"); break;
  1278.     case afpObjectTypeErr: strcat(buf, "Directory not found or incomplete pathname"); break;
  1279.     default :      strcat(buf, "Unknown error"); break;
  1280.     }
  1281.     Log(buf);
  1282.     if(myErr==noErr){
  1283.         sprintf(buf, "Type: '%s'  Creator: '%s', Flags: 0x%04X, Location: X=%d Y=%d, Directory: %d", 
  1284.                 type, creator,
  1285.                 fndrInfo.fdFlags, fndrInfo.fdLocation.h, fndrInfo.fdLocation.v,
  1286.                 fndrInfo.fdFldr); Log(buf);
  1287.     }
  1288.     return;
  1289. }
  1290.  
  1291. /*----------------------------------------------------------------------------------
  1292.  * PathInfo() - Test output with info on the PathID.
  1293.  *----------------------------------------------------------------------------------*/
  1294. void PathInfo(FSSpec *fs){
  1295.     CInfoPBRec    myPB;
  1296.     Str255         dirName;
  1297.     OSErr        myErr;
  1298.     
  1299.     myPB.dirInfo.ioNamePtr=dirName;            /* Output buffer for PBGetCatInfo(). */
  1300.     myPB.dirInfo.ioVRefNum=fs->vRefNum;    /* Volume ID */
  1301.     myPB.dirInfo.ioDrDirID=fs->parID; 
  1302.     myPB.dirInfo.ioFDirIndex= -1;            /* <0: Use ioDrDirID as input. */
  1303.  
  1304.     Log("-------------------------");
  1305.     myErr=PBGetCatInfo(&myPB, FALSE);
  1306.     sprintf(buf, "Getting Path Info: %s", myErr==noErr?"OK":"Error"); Log(buf);
  1307.     sprintf(buf, "ID of this dir:   %ld, Parent dir: \"%s\"", 
  1308.         myPB.dirInfo.ioDrDirID, PtoCstr(dirName)); Log(buf);
  1309.     sprintf(buf, "ID of parent dir: %ld, Files in dir:     %d", 
  1310.         myPB.dirInfo.ioDrParID,  myPB.dirInfo.ioDrNmFls); Log(buf);
  1311.  
  1312.     return;
  1313. }
  1314.  
  1315. /*----------------------------------------------------------------------------------
  1316.  * GetVolumeName() - Returns pointer to the volume name specified in fs.
  1317.  *----------------------------------------------------------------------------------*/
  1318. char *GetVolumeName(FSSpec *fs){
  1319.     static char        name[35]; /* Volume names are up to 27 chars. */
  1320.     HParamBlockRec     myHPB;
  1321.     OSErr             myErr;
  1322.  
  1323.     myHPB.volumeParam.ioNamePtr=(StringPtr)name;
  1324.     myHPB.volumeParam.ioVRefNum=fs->vRefNum;
  1325.     myHPB.volumeParam.ioVolIndex=0;
  1326.     myErr=PBHGetVInfo(&myHPB, FALSE);
  1327.     PtoCstr((StringPtr)name);
  1328.     return name;
  1329. }
  1330.  
  1331. /*----------------------------------------------------------------------------------
  1332.  * VolumeInfo() - Test output.
  1333.  *----------------------------------------------------------------------------------*/
  1334. void VolumeInfo(FSSpec *fs){
  1335.     HParamBlockRec     myHPB;
  1336.     OSErr             myErr;
  1337.     char            name[35]; /* Volume names are up to 27 chars. */
  1338.     long            bytes, MB=1024L*1024L;
  1339.             
  1340.     myHPB.volumeParam.ioNamePtr=(StringPtr)name;
  1341.     myHPB.volumeParam.ioVRefNum=fs->vRefNum;
  1342.     myHPB.volumeParam.ioVolIndex=0;
  1343.     myErr=PBHGetVInfo(&myHPB, FALSE);
  1344.     Log("-------------------------");
  1345.     sprintf(buf, "Getting Volume Info: %s", myErr==noErr?"OK":"Error"); Log(buf);
  1346.     sprintf(buf, "Drive Number: %d, Volume Specification Number: %d", 
  1347.             myHPB.volumeParam.ioVDrvInfo, myHPB.volumeParam.ioVRefNum); Log(buf);
  1348.     sprintf(buf, "Allocation Block Size: %ld bytes", myHPB.volumeParam.ioVAlBlkSiz); Log(buf);
  1349.     sprintf(buf, "Clump Size: %ld bytes", myHPB.volumeParam.ioVClpSiz); Log(buf);
  1350.     sprintf(buf, "Free: %d Allocation Blocks", myHPB.volumeParam.ioVFrBlk); Log(buf);
  1351.     bytes=myHPB.volumeParam.ioVFrBlk * myHPB.volumeParam.ioVAlBlkSiz;
  1352.     sprintf(buf, "Name: %s, Free: %ld bytes = %g MB", 
  1353.             PtoCstrPtr(myHPB.volumeParam.ioNamePtr), bytes, (float)bytes/MB); Log(buf);
  1354.     return;
  1355. }
  1356.  
  1357. /*----------------------------------------------------------------------------------
  1358.  * TestPathUtils()
  1359.  *----------------------------------------------------------------------------------*/
  1360. void TestPathUtils(void){
  1361.     
  1362.     FSSpecRoutinesAvail();
  1363.     
  1364.     /* Test of PtoCstrPtr(). */
  1365.     {
  1366.         char *str;
  1367.         Str255 Pstr="\pHello";
  1368.         
  1369.         str=PtoCstrPtr(Pstr);
  1370.         Log(str);
  1371.     }
  1372.     
  1373.     /* Test of select_input_file(). */
  1374.     {
  1375.         SFTypeList myTypes;
  1376.         FSSpec *fs;
  1377.     
  1378.         //myTypes[0]='TEXT';
  1379.         fs=select_input_file(-1, myTypes);
  1380.         if(fs==NULL){
  1381.             Log("Error select_input_file() or user cancelled");
  1382.             return;
  1383.         }
  1384.         FinderInfo(fs);
  1385.         VolumeInfo(fs);
  1386.         PathInfo(fs);
  1387.         
  1388.         if(fs){
  1389.             Log("-------------------------");
  1390.             Log("Getting full name");
  1391.             {
  1392.             char *fullname=FSStoCstrPtr(fs);
  1393.             sprintf(buf, "FSStoCstrPtr: %s", fullname);Log(buf);
  1394.             fullname=GetFullPathName(fs);
  1395.             sprintf(buf, "GetFullPathName: %s", fullname);Log(buf);
  1396.             }
  1397.             Log("-------------------------");
  1398.         }
  1399.     }
  1400.         
  1401.     return;
  1402. }
  1403.  
  1404. /*----------------------------------------------------------------------------------
  1405.  * macftype() - Changes the file type and creator if specified.
  1406.  *              Example: macftype(fss, 0L, 'TEXT');
  1407.  *----------------------------------------------------------------------------------*/
  1408. MacFILE *macftype(FSSpec *selection, long creator, long type){
  1409.     short vRefNum=selection->vRefNum;
  1410.     long  dirID  =selection->parID;
  1411.     Str255 fileName;
  1412.     FInfo fndrInfo;
  1413.     
  1414.     /* FSSpec.name is 63 byte string */
  1415.     memcpy(fileName, selection->name, sizeof(selection->name));
  1416.     
  1417.     HGetFInfo(vRefNum, dirID, fileName, &fndrInfo);
  1418.     
  1419.     if(creator) fndrInfo.fdCreator=creator;
  1420.     if(type)    fndrInfo.fdType   =type;
  1421.     
  1422.     HSetFInfo(vRefNum, dirID, fileName, &fndrInfo);
  1423.     
  1424.     return;
  1425. }
  1426.  
  1427. /*----------------------------------------------------------------------------------
  1428.  * macfopen() - Returns a pointer to an entry in the file table, or NULL on error.
  1429.  *----------------------------------------------------------------------------------*/
  1430. MacFILE *macfopen(FSSpec *selection, char *mode){
  1431.  
  1432.         /* This is the file table. */
  1433.     static MacFILE mac_file_table[FOPEN_MAX]; /* Like ANSI C */
  1434.     
  1435.     int         i;
  1436.     OSErr         myErr;
  1437.     SignedByte    permissions;
  1438.     
  1439.     if(selection==NULL) return;
  1440.     
  1441.     /* Find a free slot. */
  1442.     for(i=0; i<FOPEN_MAX && mac_file_table[i].in_use; i++);
  1443.     if(i==FOPEN_MAX)
  1444.         return NULL;
  1445.         
  1446.     /* Translate mode to permissions. */
  1447.     if(strchr(mode, 'w')){
  1448.         HParamBlockRec     myHPB;
  1449.         OSErr             myErr;
  1450.         long            bytes, MB=1024L*1024L;
  1451.             
  1452.         myHPB.volumeParam.ioNamePtr=NULL;
  1453.         myHPB.volumeParam.ioVRefNum=selection->vRefNum;
  1454.         myHPB.volumeParam.ioVolIndex=0;
  1455.         myErr=PBHGetVInfo(&myHPB, FALSE);
  1456.         /* Check if the volume is locked. FSpOpenDF() will still open the
  1457.          * file for write access, but writing will cause an error.
  1458.          * See New Inside Mac, "Files", p. 2-8.
  1459.          * It recommends calling PGHGetVInfo(), which is described at p. 2-144.
  1460.          * HOWEVER, I can't find the description for the 
  1461.          * volume attributes ioVAtrb ???
  1462.          */
  1463.         //if(myHPB.volumeParam.ioVAtrb & ????????)
  1464.         //    return NULL;
  1465.         permissions=fsRdWrPerm;
  1466.     }else
  1467.         permissions=fsRdPerm;
  1468.     
  1469.     /* Open it. If file-to-write not found, create it and try again. */
  1470.     myErr=FSpOpenDF(selection, permissions, &mac_file_table[i].refnum);
  1471.     
  1472.     if(myErr==fnfErr && permissions==fsRdWrPerm)
  1473.         if(noErr==FSpCreate(selection, CREATOR, 'TEXT', smSystemScript))
  1474.             myErr=FSpOpenDF(selection, permissions, &mac_file_table[i].refnum);
  1475.             
  1476.     if(myErr!=noErr)
  1477.         return NULL;
  1478.     
  1479.     mac_file_table[i].in_use=1;
  1480.     mac_file_table[i].byteorder=BigEndian; /* Assume it is a Mac type file. */
  1481.     
  1482.     memcpy(&mac_file_table[i].fss, selection, sizeof(FSSpec));
  1483.     
  1484.     return &mac_file_table[i];
  1485. }
  1486.  
  1487. /*----------------------------------------------------------------------------------
  1488.  * macfclose() - Closes the file and flushes the volume, or returns non-zero on error.
  1489.  *----------------------------------------------------------------------------------*/
  1490. int macfclose(MacFILE *fp){
  1491.     OSErr myErr;
  1492.     
  1493.     if(fp==NULL) return;
  1494.     
  1495.     myErr=FSClose(fp->refnum);
  1496.     if(myErr==noErr){
  1497.         FlushVol(NULL, fp->fss.vRefNum);
  1498.         return 0;
  1499.     }else
  1500.         return EOF;
  1501. }
  1502.  
  1503. /*----------------------------------------------------------------------------------
  1504.  * macfread() - Like fread().
  1505.  *----------------------------------------------------------------------------------*/
  1506. int macfread(void *buf, size_t recsize, size_t recnum, MacFILE *fp){
  1507.     OSErr myErr=noErr;
  1508.     long  count=recsize;
  1509.     int   rec;
  1510.     char *Buffer=buf;
  1511.     
  1512.     if(fp==NULL) return;
  1513.     
  1514.     /* Transfer data in the chunks as specified. */
  1515.     for(rec=0; rec<recnum && myErr==noErr; rec++){
  1516.         myErr=FSRead(fp->refnum, &count, Buffer);
  1517.         Buffer += count;
  1518.     }
  1519.     
  1520.     /* Count only records that transferred successfully. */
  1521.     if(myErr!=noErr)
  1522.         rec--;
  1523.     
  1524.     /* Return how many records transferred successfully. */
  1525.     return rec;
  1526. }
  1527.  
  1528. /*----------------------------------------------------------------------------------
  1529.  * macfwrite() - Like fwrite().
  1530.  *----------------------------------------------------------------------------------*/
  1531. int macfwrite(void *buf, size_t recsize, size_t recnum, MacFILE *fp){
  1532.     OSErr myErr=noErr;
  1533.     long  count=recsize;
  1534.     int   rec;
  1535.     char *Buffer=buf;
  1536.     
  1537.     if(fp==NULL) return;
  1538.     
  1539.     /* Transfer data in the chunks as specified. */
  1540.     for(rec=0; rec<recnum && myErr==noErr; rec++){
  1541.         myErr=FSWrite(fp->refnum, &count, Buffer);
  1542.         Buffer += count;
  1543.     }
  1544.     
  1545.     /* Count only records that transferred successfully. */
  1546.     if(myErr!=noErr)
  1547.         rec--;
  1548.     
  1549.     /* Return how many records transferred successfully. */
  1550.     return rec;
  1551. }
  1552.  
  1553. /*----------------------------------------------------------------------------------
  1554.  * TestFileType() - Determines what kind the open file is.
  1555.  *----------------------------------------------------------------------------------*/
  1556. int TestFileType(MacFILE *fp){
  1557.     char buf[100];
  1558.     int i, ctrl=0, bin=0, ret=0, nl=0, esc=0, Rochester=0, Hathaway=0, ps=0;
  1559.     
  1560.     if(fp==NULL) return;
  1561.     
  1562.     if(1==macfread(buf, sizeof(buf), 1, fp)){
  1563.         /* Test for headers. */
  1564.         if(!strncmp(buf, "%!", 2)) ps++;
  1565.         if(!strncmp(buf, "DSM version ", 12)) Hathaway++;
  1566.         /* Does the Rochester file have a header? */
  1567.         
  1568.         /* Test the bytes. */
  1569.         for(i=0; i<sizeof(buf); i++){
  1570.             switch(buf[i]){
  1571.             case '\r': ret++; break;
  1572.             case '\n': nl++; break;
  1573.             case 0x1B: esc++; break;
  1574.             case '\t': case '\f': case '\b': case '\v': break;
  1575.             default:
  1576.                 if(buf[i]<0x1f) ctrl++;
  1577.                 if(buf[i]>0x7f) bin++;
  1578.                 break;
  1579.             }
  1580.         }
  1581.     }
  1582.     
  1583.     sprintf(buf, "ctrl=%d, bin=%d, ret=%d, nl=%d, esc=%d", 
  1584.                   ctrl,    bin,    ret,    nl,    esc); Log(buf);
  1585.     if(Rochester) Log("Rochester Transient Fault Recorder file");
  1586.     if(Hathaway)  Log("Hathaway Digital Signal Monitor file");
  1587.     if(ps)        Log("PostScript file");
  1588.     if(bin) 
  1589.         Log("Binary file");
  1590.     else{
  1591.         if(!ret &&  nl) Log("Unix text file");
  1592.         if( ret && !nl) Log("Macintosh text file");
  1593.         if( ret &&  nl) Log("MS-DOS text file");
  1594.     }
  1595.     
  1596.     return 0;
  1597. }
  1598.  
  1599. /*----------------------------------------------------------------------------------
  1600.  * macfseek() - Like fseek().
  1601.  *----------------------------------------------------------------------------------*/
  1602. int macfseek(MacFILE *fp, long offset, int whence){
  1603.     OSErr myErr;
  1604.     short posMode;
  1605.  
  1606.     if(!fp) return -1;
  1607.     
  1608.     switch(whence){
  1609.     case SEEK_SET: posMode=fsFromStart; break;
  1610.     case SEEK_CUR: posMode=fsFromMark;  break;
  1611.     case SEEK_END: posMode=fsFromLEOF;  break;
  1612.     default: return -1; break;
  1613.     }
  1614.     
  1615.     myErr=SetFPos(fp->refnum, posMode, offset);
  1616.     
  1617.     return myErr==noErr?0:-1;
  1618. }
  1619.  
  1620. /*----------------------------------------------------------------------------------
  1621.  * macftell() - Like ftell().
  1622.  *----------------------------------------------------------------------------------*/
  1623. long macftell(MacFILE *fp){
  1624.     OSErr myErr;
  1625.     long offset;
  1626.  
  1627.     if(!fp) return -1;
  1628.     
  1629.     myErr=GetFPos(fp->refnum, &offset);
  1630.     if(myErr!=noErr) errno=1; /* Required by ANSI C standard. */
  1631.     
  1632.     return myErr==noErr?offset:-1L;
  1633. }
  1634.  
  1635. /*----------------------------------------------------------------------------------
  1636.  * macfstat() - Get file status. Returns zero on success, or -1 on error.
  1637.  *              Not all unix features are implemented yet.
  1638.  *----------------------------------------------------------------------------------*/
  1639. int macfstat(MacFILE *fp, struct MacStat *buf){
  1640.     static char        name[35]; /* Volume names are up to 27 chars. */
  1641.     HParamBlockRec     myHPB; /* New Ins.Mac, `Files', p. 2-269 */
  1642.     OSErr             myErr;
  1643.     DateTimeRec        date;
  1644.  
  1645.     if(!buf) return -1;
  1646.     
  1647.     myHPB.volumeParam.ioCompletion=0;
  1648.     myHPB.volumeParam.ioNamePtr=(StringPtr)fp->fss.name;
  1649.     myHPB.volumeParam.ioVRefNum=fp->fss.vRefNum;
  1650.     myHPB.fileParam.ioFDirIndex=0;
  1651.     myHPB.fileParam.ioDirID=fp->fss.parID;
  1652.     myErr=PBHGetFInfo(&myHPB, FALSE); /* New Ins.Mac, `Files', p. 2-194 */
  1653.     
  1654.     Secs2Date(myHPB.fileParam.ioFlMdDat, &date);
  1655.     buf->year=date.year;
  1656.     
  1657.     return myErr==noErr?0:-1;
  1658. }
  1659.  
  1660. /*----------------------------------------------------------------------------------
  1661.  * copy_file() - For testing.
  1662.  *----------------------------------------------------------------------------------*/
  1663. void copy_file(MacFILE *fp_in, MacFILE *fp_out){
  1664. #define recsiz 100
  1665.     char rec[recsiz];
  1666.     int  irec, nrec, lrec;
  1667.     long fsiz;
  1668.     
  1669.     if(!fp_in || !fp_out) return;
  1670.     
  1671.     /* File size. */
  1672.     macfseek(fp_in,  0L, SEEK_END);
  1673.     fsiz=macftell(fp_in);
  1674.     nrec=fsiz/recsiz;
  1675.     lrec=fsiz-(nrec*recsiz); /* Size of last, partial, record. */
  1676.     macfseek(fp_in,  0L, SEEK_SET);
  1677.     macfseek(fp_out, 0L, SEEK_SET);
  1678.     sprintf(buf, "File size: %ld bytes = %d chunks of %d bytes plus one of %d bytes",
  1679.                             fsiz,      nrec,      recsiz,                lrec); Log(buf);
  1680.     
  1681.     /* Transfer full records. */
  1682.     for(irec=0; irec<nrec; irec++){
  1683.         if(1!=macfread (rec, recsiz, 1, fp_in)) break;
  1684.         if(1!=macfwrite(rec, recsiz, 1, fp_out)) break;
  1685.     }
  1686.     
  1687.     /* Transfer the last, partial record. */
  1688.     if(lrec && 1==macfread(rec, lrec, 1, fp_in))
  1689.         macfwrite(rec, lrec, 1, fp_out);
  1690.     
  1691.     Log("Copy Done.");    
  1692.     return;
  1693. }
  1694.  
  1695. /*----------------------------------------------------------------------------------
  1696.  * TestFileUtils()
  1697.  *----------------------------------------------------------------------------------*/
  1698. void TestFileUtils(void){
  1699.     MacFILE *fp_in, *fp_out;
  1700.     FSSpec  *fs_in, *fs_out;
  1701.     SFTypeList             myTypes;
  1702.     StandardFileReply     myReply;
  1703.     
  1704.     Log("Testing the file utility functions");
  1705.     
  1706.     fs_in=select_input_file(-1, myTypes); /* Input file */
  1707.     fp_in=macfopen(fs_in, "r");
  1708.     
  1709.     TestFileType(fp_in);
  1710.     
  1711.     StandardPutFile("\pFormat: see diagnostic window", "\pdummy", &myReply);
  1712.     fs_out=myReply.sfGood?&myReply.sfFile:NULL;
  1713.     fp_out=macfopen(fs_out, "w");
  1714.     
  1715.     copy_file(fp_in, fp_out);
  1716.     
  1717.     macfclose(fp_in);
  1718.     macfclose(fp_out);
  1719.     
  1720.     return;
  1721. }
  1722.  
  1723. /*----------------------------------------------------------------------------------
  1724.  * BetterMoveWindow() - Moves the window partially down and to the right with 
  1725.  *                      amounts between 0 and 1, where the entire screen size is one.
  1726.  *  The window will not get too close to the border.
  1727.  *----------------------------------------------------------------------------------*/
  1728. void BetterMoveWindow(WindowPtr wp, float right, float down){
  1729.     Rect r;
  1730.     short h, w, x, y;
  1731.     
  1732.     /* Move the box to the center of the screen, horizontally, and
  1733.      * one-third down, but not too close to the border.
  1734.      * This is difficult to do with RezEdit. 
  1735.      */
  1736.     r=wp->portRect;
  1737.     h=r.bottom-r.top; /* height */
  1738.     w=r.right-r.left; /* width */
  1739.     x=(screenBits.bounds.right-w) * right;
  1740.     if(x<10) x=10;
  1741.     y=(screenBits.bounds.bottom-30-h) * down +30; /* Menubar is 30 pixels high. */
  1742.     if(y<30) y=30;
  1743.     MoveWindow(wp, x, y, TRUE);
  1744. }
  1745.  
  1746.  
  1747. /*----------------------------------------------------------------------------------
  1748.  * SwapN() - swaps n bytes of buf in place, also convert IEEE 8-byte double to 
  1749.  *           Macintosh double (12-byte)
  1750.  *----------------------------------------------------------------------------------*/
  1751. void SwapN(void *buf, int n){
  1752.     char c, *b, *e;
  1753.     for(b=buf, e=b+n-1; b<e; b++, e--){
  1754.          c = *b;
  1755.         *b = *e;
  1756.         *e =  c;
  1757.     }    
  1758.     return;
  1759. }
  1760.  
  1761. /*----------------------------------------------------------------------------------
  1762.  * NeedSwap() - swaps n bytes of buf in place, also convert IEEE 8-byte double to 
  1763.  *           Macintosh double (12-byte), BUT ONLY IF NEEDED, i.e., if the byte 
  1764.  *              order of the CPU running this program is different from the file type.
  1765.  * Returns: True if swap was needed.
  1766.  *----------------------------------------------------------------------------------*/
  1767. int NeedSwap(MacFILE *fp, void *buf, int n){
  1768.     if(computerbyteorder != fp->byteorder){
  1769.         SwapN(buf, n);
  1770.         return 1;
  1771.     }else
  1772.         return 0;
  1773. }
  1774.  
  1775. /*==================== INPUT FUNCTIONS =================*/
  1776.  
  1777. char GetInputByte(File *fp){
  1778.     char buf;
  1779.     long size=sizeof(buf);
  1780.     FileRead(&buf, size, 1, fp);
  1781.     return buf;
  1782. }
  1783.  
  1784. int GetInputInt(File *fp){
  1785.     int buf;
  1786.     long size=sizeof(buf);
  1787.     FileRead((char *)&buf, size, 1, fp);
  1788.     NeedSwap(fp, &buf, sizeof(buf));
  1789.     return buf;
  1790. }
  1791.  
  1792. long GetInputLong(File *fp){
  1793.     long buf;
  1794.     long size=sizeof(buf);
  1795.     FileRead((char *)&buf, size, 1, fp);
  1796.     NeedSwap(fp, &buf, sizeof(buf));
  1797.     return buf;
  1798. }
  1799.  
  1800. unsigned long GetInputULong(File *fp){
  1801.     unsigned long buf;
  1802.     long size=sizeof(buf);
  1803.     FileRead((char *)&buf, size, 1, fp);
  1804.     NeedSwap(fp, &buf, sizeof(buf));
  1805.     return buf;
  1806. }
  1807.  
  1808. float GetInputFloat(File *fp){
  1809.     float buf;
  1810.     long size=sizeof(buf);
  1811.     FileRead((char *)&buf, size, 1, fp);
  1812.     NeedSwap(fp, &buf, sizeof(buf));
  1813.     return buf;
  1814. }
  1815.  
  1816. /*
  1817. Note: make sure to use the 8-byte IEEE-compatible short double on the Mac
  1818. and not one of the Mac native 80 or 96 bit (10 or 12 byte) formats. 
  1819. */
  1820. double GetInputDouble(File *fp){
  1821.     double retval;
  1822. #ifdef THINK_C
  1823.     short double buf; /* IEEE-compatible 8-byte floating point on Mac. */
  1824. #else
  1825.     double buf;
  1826. #endif
  1827.     long size=sizeof(buf);
  1828.     FileRead((char *)&buf, size, 1, fp);
  1829.     NeedSwap(fp, &buf, sizeof(buf));
  1830.     retval=buf; /* Convert to Mac native format. */
  1831.     return retval;
  1832. }
  1833.  
  1834. char *GetInputString(char *str, int len, File *fp){
  1835.     int i, itemsread;
  1836.     char buf;    
  1837.     long size=sizeof(buf);
  1838.     
  1839.     for(i=0; i<len && buf && itemsread; i++){
  1840.         itemsread=FileRead((char *)&buf, size, 1, fp);
  1841.         *str=buf;
  1842.         str++;
  1843.     }
  1844.     
  1845.     *str='\0';
  1846.         
  1847.     return str;
  1848. }
  1849.  
  1850. char *GetInputNString(char *str, int len, File *fp){
  1851.     int itemsread;
  1852.     
  1853.     itemsread=FileRead(str, 1, len, fp);
  1854.     if(str[itemsread-1]!='\0')
  1855.         str[itemsread]='\0';
  1856.         
  1857.     return str;
  1858. }
  1859.  
  1860. /*==================== OUTPUT FUNCTIONS =================*/
  1861.  
  1862. // Writes a C string to the output file.
  1863. int WriteTxt(File *fp, char *str){
  1864.     return FWRITE(str, strlen(str), 1, fp);
  1865. }
  1866.  
  1867. // Writes bytes to a binary output file.
  1868. int WriteBin(File *fp, void *buf, int size){
  1869.     return FWRITE(buf, size, 1, fp);
  1870. }
  1871.  
  1872. void WriteULong(File *fp, unsigned long x){
  1873.     unsigned long buf;                // copy the data x, it may be a constant
  1874.     buf=x;
  1875.     NeedSwap(fp, &buf, sizeof(buf));
  1876.     WriteBin(fp, &buf, sizeof buf);
  1877. }
  1878.  
  1879. void WriteLong(File *fp, long x){
  1880.     long buf;
  1881.     buf=x;
  1882.     NeedSwap(fp, &buf, sizeof(buf));
  1883.     WriteBin(fp, &buf, sizeof buf);
  1884. }
  1885.  
  1886. void WriteShort(File *fp, signed short x){
  1887.     signed short buf;
  1888.     buf=x;
  1889.     NeedSwap(fp, &buf, sizeof(buf));
  1890.     WriteBin(fp, &buf, sizeof buf);
  1891. }
  1892.  
  1893. ---------------------------
  1894.  
  1895. >From reinder@neuretp.biol.ruu.nl (Reinder Verlinde)
  1896. Subject: How to detect whether Debugger is installed?
  1897. Date: Mon, 11 Jul 1994 12:10:44 GMT
  1898. Organization: Rijksuniversiteit Utrecht
  1899.  
  1900. The subject says it all: How do you detect whether MacsBug is present?
  1901. I want to know this since I have this FKEY which should activate
  1902. MacsBug,
  1903. and not do anything when MacsBug is not present. The usual
  1904. TrapAvailable
  1905. method does not seem to work since
  1906.  
  1907.   GetTrapAddress( _Unimplemented) == GetTrapAddress( _Debugger)
  1908.  
  1909. irrespective of the presence of MacsBug. I also looked up the Gestalt
  1910. selectors, and there is one to check whether the Debugger Utilities are
  1911. present, but I can't find one to check the presence of the Debugger.
  1912.  
  1913. I can think of numerous imperfect ways to check this (comparing first
  1914. bytes of _Unimplemented with a copy in my code, checking for MacsBug in
  1915. the System Folder, etcetera), but there should be a perfect way.
  1916.  
  1917. reinder@neuretp.biol.ruu.nl (Reinder Verlinde)
  1918.  
  1919. +++++++++++++++++++++++++++
  1920.  
  1921. >From busfield@hurricane.seas.ucla.edu (John D. Busfield)
  1922. Date: Wed, 13 Jul 1994 16:14:40 GMT
  1923. Organization: School of Engineering & Applied Science, UCLA.
  1924.  
  1925. In <1994Jul11.121044.4311@cc.ruu.nl> reinder@neuretp.biol.ruu.nl (Reinder Verlinde) writes:
  1926.  
  1927. >The subject says it all: How do you detect whether MacsBug is present?
  1928. >I want to know this since I have this FKEY which should activate
  1929. >MacsBug,
  1930. >and not do anything when MacsBug is not present.
  1931.  
  1932. Here's what it says in Macsbug Reference and Debugging Guide pg 412
  1933.  
  1934. How MacsBug installs itself.
  1935.  
  1936. When a system error or 68000 exception occurs, the ROM code examines
  1937. the global variable MacJmp to obtain the address of the debuggers entry
  1938. point. MacJmp might contain additional information, depending on whether you
  1939. are running under a 24-bit or 32-bit Memory Manager.
  1940.  
  1941. If you are running under a 24-bit Memory Manager, the high-order byte
  1942. of MacJmp is a flags byte that contains the following information.
  1943.  
  1944. Bit        Meaning
  1945. 7        Set if debugger is running
  1946. 6        Set if debugger can handle system errors
  1947. 5        Set if debugger is installed
  1948. 4        Set if debugger can support the Discipline utility
  1949.  
  1950. The lower 3 bytes of MacJmp are used to store the address of the debugger's 
  1951. entry point.
  1952.  
  1953. If you are running under a 32-bit Memory Manager, the flags byte is
  1954. moved to address $BFF and the long word at MacJmp becomes a full 32-bit
  1955. address that points to the debugger's entry point.
  1956.  
  1957. So to answer your question, you should only need to look at bit 5 of
  1958. the flags byte.
  1959.  
  1960. -- 
  1961. - ----------------------------------------------------------------------------
  1962. John Busfield                | All my realities are virtual
  1963. busfield@hurricane.seas.ucla.edu
  1964. _____________________________________________________________________________
  1965.  
  1966. +++++++++++++++++++++++++++
  1967.  
  1968. >From dlamkins@tiac.net (David B. Lamkins)
  1969. Date: 17 Jul 1994 00:48:29 GMT
  1970. Organization: DBL Systems
  1971.  
  1972. In article <1994Jul11.121044.4311@cc.ruu.nl>
  1973. reinder@neuretp.biol.ruu.nl (Reinder Verlinde) writes:
  1974.  
  1975. > The subject says it all: How do you detect whether MacsBug is present?
  1976.  
  1977. The following Pascal unit does everything you need (except give you C
  1978. code.)  The Apple manual doesn't tell the entire story -- the comments
  1979. in the code tell which debuggers and system patches break the rules.
  1980.  
  1981. unit DebuggerTest;
  1982.  
  1983. interface
  1984.  
  1985.     type
  1986.         DebuggerKind = ( {}
  1987.             debuggerKindNone, {}
  1988.             debuggerKindMacsBug, {}
  1989.             debuggerKindTMON, {}
  1990.             debuggerKindJasik, {}
  1991.             debuggerKindABZmon, {}
  1992.             debuggerKindOther {}
  1993.             );
  1994.         DebuggerSignature = packed array[1..2] of Char;
  1995.  
  1996. {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
  1997.     procedure GetDebuggerInfo (var present, active: Boolean; var kind:
  1998. DebuggerKind; var signature: DebuggerSignature);
  1999. {$ENDC}
  2000.  
  2001. {ABZmon can load Ron top ofS another debugger. In this case, the
  2002. underlying debugger}
  2003. {becomes the secondary debugger, but is the only one reported by
  2004. GetDebuggerInfo, which}
  2005. {looks in the RnormalS places before trying to find ABZmon. The
  2006. ABZMonIsLoaded function}
  2007. {can be used to detect ABZmonUs presence when not the only debugger.}
  2008.     function ABZMonIsLoaded: Boolean;
  2009.  
  2010.     function DebuggerPresent: Boolean;
  2011.  
  2012. implementation
  2013.  
  2014.     function ValidDebuggerWorldAddress (p: univ Ptr): Boolean;
  2015.     begin
  2016.     {Address must be even and somewhere within addressable RAM or ROM.}
  2017.         ValidDebuggerWorldAddress := not ODD(ORD(p)) and (ORD(p) >= 0) and
  2018. (ORD(p) < ORD(MFTopMem));
  2019.     end;
  2020.  
  2021.     type
  2022.         LongPtr = ^Longint;
  2023.         IntPtr = ^Integer;
  2024.         PtrPtr = ^Ptr;
  2025.  
  2026.     function GetVBR: Ptr;
  2027.     inline
  2028.         $7008,             {MOVEQ #$EnterSupervisorMode,D0}
  2029.         $A08D,            {_DebugUtil}
  2030.         $4E7A, $8801,    {MOVEC VBR,A0}
  2031.         $46C0,            {MOVE D0,SR    ;restore user mode}
  2032.         $2E88;            {MOVE.L A0,(A7)}
  2033.  
  2034.     function ABZMonIsLoaded: Boolean;
  2035.         const
  2036.             _DebugUtil = $A08D;
  2037.             _Unimplemented = $A89F;
  2038.         var
  2039.             VBR: Ptr;
  2040.             vectorPtr: PtrPtr;
  2041.             codePtr: LongPtr;
  2042.             err: OSErr;
  2043.     begin
  2044.     {Alain BirtzUs ABZmon doesnUt use MacJmp at all. In fact, it doesnUt
  2045. even use}
  2046.     {the trap dispatcher table. Instead, it patches the trap dispatcher!
  2047. The hint for}
  2048.     {finding this, aside from not finding it anywhere else, is that ABZmon
  2049. defines}
  2050.     {a private trap _DebugNum $AAFF - this has reserved bit 9 set.
  2051. ABZmonUs trap}
  2052.     {dispatcher can be identified by its first instruction, ORI #$700,SR.
  2053. In hex, this}
  2054.     {is $007C0700.}
  2055.         if GetOSTrapAddress(_DebugUtil) = GetToolTrapAddress(_Unimplemented)
  2056. then
  2057.             VBR := Ptr(0)
  2058.         else
  2059.             begin
  2060.                 if DebuggerGetMax >= 8 then
  2061.                     VBR := GetVBR
  2062.                 else
  2063.                     VBR := Ptr(0);
  2064.             end;
  2065.         if ValidDebuggerWorldAddress(VBR) then
  2066.             begin
  2067.                 vectorPtr := PtrPtr(ORD(VBR) + $28);
  2068.                 codePtr := LongPtr(vectorPtr^);
  2069.                 ABZMonIsLoaded := ValidDebuggerWorldAddress(codePtr) & (codePtr^ =
  2070. $007C0700);
  2071.             end
  2072.         else
  2073.             ABZMonIsLoaded := False;
  2074.     end;
  2075.  
  2076. {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
  2077.     function NonStandardDebuggerKind (entry: univ Ptr): DebuggerKind;
  2078.     begin
  2079.         NonStandardDebuggerKind := debuggerKindOther;    {If we canUt decideI}
  2080.  
  2081.     {JasikUs RThe DebuggerS doesnUt have a world pointer. Its
  2082. distinguishing}
  2083.     {feature is a test for whether it was entered via an F-line trap, by
  2084. executing}
  2085.     {the instruction CMPI #10,DSErrCode. In hex this is $0C7800100AF0.}
  2086.         if (LongPtr(entry)^ = $0C780010) and (IntPtr(ORD(entry) +
  2087. SIZEOF(Longint))^ = $0AF0) then
  2088.             NonStandardDebuggerKind := debuggerKindJasik
  2089.         else
  2090.  
  2091.     {Add other tests as needed.}
  2092.             ;
  2093.     end;
  2094. {$ENDC}
  2095.  
  2096. {This is based on info from RMacsBug Reference and Debugging Guide for
  2097. MacsBug version 6.2S}
  2098. {The MacsBug reference doesnUt mention that the ROM debugger
  2099. masquerades as a real debugger.}
  2100. {Because the ROM debugger doesnUt have a RworldS pointer, we have to do
  2101. some extra checks.}
  2102.     procedure GetDebuggerInfo (var present, active: Boolean; var kind:
  2103. DebuggerKind; var signature: DebuggerSignature);
  2104.         const
  2105.     {The first and current universal ROM is rev 1660. Assume}
  2106.     {that future universal ROMs will have higher rev numbers.}
  2107.             UnivROMVersion = 1660;
  2108.             MacJmp = $120;
  2109.             Debug32Flags = $BFF;
  2110.             ROMBase = $2AE;
  2111.             DebugInstalledFlagBit = 5;
  2112.             DebugActiveFlagBit = 7;
  2113.             Megabyte = $100000;
  2114.     {The following gestalt selectors are from Rene G.A. RosU SGSL.}
  2115.             gestaltEnablerAttr = 'bugy'; {32-bit System Enabler [1.0]}
  2116.             gestaltEnabler32bit = 7; {32-bit enabler present}
  2117.         type
  2118.             PtrPtr = ^Ptr;
  2119.             IntPtr = ^Integer;
  2120.             SigPtr = ^DebuggerSignature;
  2121.         var
  2122.             err: OSErr;
  2123.             gestaltResult: Longint;
  2124.             MM32Bit, univROM, apple32BitEnabler, broken: Boolean;
  2125.             debugFlagsAddr: Ptr;
  2126.             debugEntryAddr, debugWorldAddr, ROMBaseAddr: Ptr;
  2127.     begin
  2128.         err := Gestalt(gestaltAddressingModeAttr, gestaltResult);
  2129.         MM32Bit := (err = noErr) & BTST(gestaltResult,
  2130. gestalt32BitAddressing);
  2131.         err := Gestalt(gestaltROMVersion, gestaltResult);
  2132.         UnivROM := (err = noErr) & (gestaltResult >= UnivROMVersion);
  2133.         err := Gestalt(gestaltEnablerAttr, gestaltResult);
  2134.         apple32BitEnabler := (err = noErr) & BTST(gestaltResult,
  2135. gestaltEnabler32bit);
  2136.     {According to the reference, debugger flags are located in the high
  2137. byte of}
  2138.     {MacJmp unless the machine is 32-bit capable, in which case they move
  2139. to}
  2140.     {$BFF. IUm not sure I believe that the 32-bit enablers (ConnectixUs
  2141. MODE32}
  2142.     {and AppleUs 32-bit System Enabler) report the right thing w.r.t.
  2143. 32-bit capability.}
  2144.     {Clearly, if the machine is running in 32-bit mode, itUs 32-bit
  2145. capable even under}
  2146.     {the enablers. But when running under a 32-bit enabler in 24-bit mode,
  2147. the enabler}
  2148.     {would seem to be obliged to report 32-bit capability. In this state,
  2149. I wouldnUt expect}
  2150.     {the enabler to put up enough of a charade to move the debugger flags
  2151. Q theyUd almost}
  2152.     {certainly end up in the high byte of MacJmp. Also, AppleUs enabler is
  2153. damaged in}
  2154.     {the opposite case Q the debugger traps still look at the high byte of
  2155. MacJmp even in}
  2156.     {32-bit mode. This requires a special test to pretend thereUs no
  2157. debugger present under}
  2158.     {AppleUs 32-bit System Enabler in 32-bit addressing mode; 24-bit mode
  2159. is OK.}
  2160.         broken := apple32BitEnabler and MM32Bit;
  2161.         if not broken then
  2162.             begin
  2163.                 if MM32Bit or UnivROM then
  2164.                     debugFlagsAddr := Ptr(Debug32Flags)
  2165.                 else
  2166.                     debugFlagsAddr := Ptr(MacJmp);
  2167.                 present := BTST(debugFlagsAddr^, DebugInstalledFlagBit);
  2168.                 active := BTST(debugFlagsAddr^, DebugActiveFlagBit);
  2169.             end
  2170.         else
  2171.             begin
  2172.                 present := False;
  2173.                 active := False;
  2174.             end;
  2175.         if present then
  2176.             begin
  2177.                 debugEntryAddr := StripAddress(PtrPtr(MacJmp)^);
  2178.                 ROMBaseAddr := StripAddress(PtrPtr(ROMBase)^);
  2179.                 if ORD(debugEntryAddr) > ORD(ROMBaseAddr) then    {Could be the ROM
  2180. debuggerI}
  2181.                     if MM32Bit then
  2182.                         begin    {In 32-bit mode, any address in or beyond ROM is not in
  2183. RAM.}
  2184.                             present := False;
  2185.                             Exit(GetDebuggerInfo);
  2186.                         end
  2187.                     else if ORD(debugEntryAddr) <= ORD(ROMBaseAddr) + Megabyte then
  2188.                         begin    {In 24-bit mode, the ROM gets 1MB and can be followed by
  2189. RAM.}
  2190.                             present := False;
  2191.                             Exit(GetDebuggerInfo);
  2192.                         end;
  2193. {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
  2194.                 debugWorldAddr := PtrPtr(ORD(debugEntryAddr) - SIZEOF(Ptr))^;
  2195.                 if ValidDebuggerWorldAddress(debugWorldAddr) then
  2196.                     signature := SigPtr(debugWorldAddr)^
  2197.                 else
  2198.                     signature := '??';
  2199.                 case Integer(signature) of
  2200.                     $4D54:     {MT}
  2201.                         kind := debuggerKindMacsBug;
  2202.         {% This is from memory; I _think_ TMON registers itself this wayI}
  2203.                     $5748:     {WH}
  2204.                         kind := debuggerKindTMON;
  2205.                     otherwise
  2206.                         kind := NonStandardDebuggerKind(debugEntryAddr);
  2207.                 end;
  2208. {$ENDC}
  2209.             end
  2210.     {Alain BirtzUs ABZmon doesnUt put anything in MacJmp, but patches the
  2211. trap dispatcher.}
  2212.         else if ABZMonIsLoaded then
  2213.             begin
  2214.                 kind := debuggerKindABZmon;
  2215. {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
  2216.                 signature := '??';
  2217. {$ENDC}
  2218.                 present := True;
  2219.             end
  2220.         else    {No debugger present.}
  2221.             begin
  2222.                 kind := debuggerKindNone;
  2223. {$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
  2224.                 signature := '  ';
  2225. {$ENDC}
  2226.             end;
  2227.     end;
  2228.  
  2229.     function DebuggerPresent: Boolean;
  2230.         var
  2231.             present, active: Boolean;
  2232.             kind: DebuggerKind;                {this never gets a value}
  2233.             signature: DebuggerSignature;    {this never gets a value}
  2234.     begin
  2235.         GetDebuggerInfo(present, active, kind, signature);
  2236.         DebuggerPresent := present;
  2237.     end;
  2238.  
  2239. end.
  2240.  
  2241. Dave
  2242. - --
  2243. CPU Cycles: Use them now or lose them forever...
  2244.  
  2245. ---------------------------
  2246.  
  2247. >From bb@lightside.com (Bob Bradley)
  2248. Subject: Q: Converting PB to FSSpec
  2249. Date: Fri, 22 Jul 1994 08:56:47 -0800
  2250. Organization: SS Software Inc.
  2251.  
  2252. I'm writing an application that needs to process all files/folders in a
  2253. folder/disk.
  2254.  
  2255. I have this much so far (hasn't been tested) that I've mostly copied &
  2256. modified from DragonSmith and DropShell 2.0 to make them work FSSpec's:
  2257.  
  2258. OSErr FSpProcessDirectoryContents( FSSpec *directory, FSSpecList fileList, 
  2259.                                    Boolean addDirectories, 
  2260.                                    Boolean lookInsideDirectories, 
  2261.                                    Boolean skipOnError )
  2262. {  
  2263.    OSErr            error = noErr;
  2264.    CInfoPBRec       pb;
  2265.    short            i;
  2266.    Str63            name;
  2267.    Boolean          keepGoing;
  2268.    long             directoryID;
  2269.    FSSpec           file;
  2270.    
  2271.    error = FSpGetDirectoryID( directory, &directoryID );
  2272.    if( error != noErr ) return( error );
  2273.    pb.hFileInfo.ioCompletion = NULL;
  2274.    pb.hFileInfo.ioNamePtr = &name[0];
  2275.    for( i = 1, keepGoing = TRUE; keepGoing; i++ )
  2276.    {
  2277.       pb.hFileInfo.ioVRefNum = directory->vRefNum;
  2278.       pb.hFileInfo.ioDirID = directoryID;
  2279.       pb.hFileInfo.ioFDirIndex = i;
  2280.       error = PBGetCatInfoSync( &pb );
  2281.       if( error == noErr )
  2282.       {
  2283.  
  2284.            // Right here I need something to convert the parameter block to
  2285.            // an FSSpec for this item in the directory. So I can pass it
  2286.            // my routine that either adds it to the FSSpec List (if it's a
  2287.            // file) or calls this routine again (if it's a folder).
  2288.  
  2289.       }
  2290.       else if( error == fnfErr || !skipOnError )
  2291.       {
  2292.          keepGoing = FALSE;
  2293.       }
  2294.    }
  2295.    if( error == fnfErr ) error = noErr;
  2296.    return( error );
  2297. }
  2298.  
  2299. Can I just copy the pb->h.fileParam.ioNamePtr, pb->c.hFileInfo.ioFlParID,
  2300. and pb.hFileInfo.ioVRefNum fields of the parameter block to the the
  2301. FSSpec? or do I need to do some other stuff? Do I need to any special
  2302. handling of alias's?
  2303.  
  2304. If you find errors in the above routine, I'd like to know about that too.
  2305.  
  2306. +++++++++++++++++++++++++++
  2307.  
  2308. >From woody@alumni.caltech.edu (William Edward Woody)
  2309. Date: 24 Jul 1994 19:37:26 GMT
  2310. Organization: California Institute of Technology, Alumni Association
  2311.  
  2312. >   FSSpec           file;
  2313. >   
  2314. >   error = FSpGetDirectoryID( directory, &directoryID );
  2315. >   if( error != noErr ) return( error );
  2316. >   pb.hFileInfo.ioCompletion = NULL;
  2317. >   pb.hFileInfo.ioNamePtr = &name[0];
  2318. >   for( i = 1, keepGoing = TRUE; keepGoing; i++ )
  2319. >   {
  2320. >      pb.hFileInfo.ioVRefNum = directory->vRefNum;
  2321. >      pb.hFileInfo.ioDirID = directoryID;
  2322. >      pb.hFileInfo.ioFDirIndex = i;
  2323. >      error = PBGetCatInfoSync( &pb );
  2324. >      if( error == noErr )
  2325. >      {
  2326. >
  2327. >           // Right here I need something to convert the parameter block to
  2328. >           // an FSSpec for this item in the directory. So I can pass it
  2329. >           // my routine that either adds it to the FSSpec List (if it's a
  2330.         /*
  2331.          *  Then there's my favorite way to do this
  2332.          */
  2333.  
  2334.         FSMakeFSSpec(directory->vRefNum,directoryID,pb.hFIleInfo.ioNamePtr,&file);
  2335.  
  2336.         /*
  2337.          *  Or something like that, your milege may vary.
  2338.          */
  2339.  
  2340. >           // file) or calls this routine again (if it's a folder).
  2341. >
  2342. >      }
  2343.  
  2344. I hope this helps.
  2345.  
  2346. Like Apple says: Don't build the FSSpec by hand yourself. Instead,
  2347. use FSMakeFSSpec() [IM VI Ch 25, pg 30] to do the dirty work.
  2348.  
  2349.                     - Bill
  2350. -- 
  2351. - William Edward Woody                  | Disclamer:
  2352.   woody@alumni.cco.caltech.edu             | "He who knows does not speak;
  2353. - In Phase Consulting                   |  He who speaks does not know."
  2354.   337 West California #4; Glendale, CA 91203 |            - Lao Tzu
  2355.  
  2356. +++++++++++++++++++++++++++
  2357.  
  2358. >From mclow@san_marcos.csusm.edu (Marshall Clow)
  2359. Date: Sat, 23 Jul 1994 15:40:48 -0800
  2360. Organization: Aladdin Systems
  2361.  
  2362. In article <bb-2207940856470001@user59.lightside.com>, bb@lightside.com
  2363. (Bob Bradley) wrote:
  2364.  
  2365. > I'm writing an application that needs to process all files/folders in a
  2366. > folder/disk.
  2367. > I have this much so far (hasn't been tested) that I've mostly copied &
  2368. > modified from DragonSmith and DropShell 2.0 to make them work FSSpec's:
  2369.    I always like to see people using DropShell! I will admit to being a
  2370. little confused, though. The folder walking code in DropShell uses FSSpecs
  2371. already, so I don't know what modifications you need to make.
  2372.  
  2373. [ start of included code deleted ]
  2374. >       error = PBGetCatInfoSync( &pb );
  2375. >       if( error == noErr )
  2376. >       {
  2377. >            // Right here I need something to convert the parameter block to
  2378. >            // an FSSpec for this item in the directory. So I can pass it
  2379. >            // my routine that either adds it to the FSSpec List (if it's a
  2380. >            // file) or calls this routine again (if it's a folder).
  2381. [ end of included code deleted ]
  2382. > Can I just copy the pb->h.fileParam.ioNamePtr, pb->c.hFileInfo.ioFlParID,
  2383. > and pb.hFileInfo.ioVRefNum fields of the parameter block to the the
  2384. > FSSpec? or do I need to do some other stuff? Do I need to any special
  2385. > handling of alias's?
  2386.  
  2387.  
  2388. Well, let's take your q's one at a time. 
  2389.  
  2390. 1) You _can_ just copy the relevant fields of the param block into an
  2391. FSSpec, and go from there. This is what the DropShell does, and it will
  2392. work. However, Apple has advised against building FSSpecs by hand, and
  2393. recomends calling FSMakeFSSpec instead. 
  2394.  
  2395. 2) If you want to resolve alias files while you are walking the file tree,
  2396. you can just call ResolveAliasFile () which will do all the alias
  2397. traversal for you. _However_, you need to ensure that your loop will
  2398. terminate. Imagine the following case:
  2399.  
  2400.    You have a folder "one"
  2401.       Inside it is a folder "two"
  2402.          inside it is a file "three"
  2403.          and a file "four", which is an alias to "one".
  2404.  
  2405. Have fun.
  2406. -- Marshall
  2407.  
  2408. -- 
  2409. Marshall Clow
  2410. Aladdin Systems
  2411. mclow@san_marcos.csusm.edu
  2412.  
  2413. ---------------------------
  2414.  
  2415. >From afrancke@netcom.com (Andrew Francke)
  2416. Subject: Q: Reentrancy and PowerMac Runtime Model
  2417. Date: Mon, 11 Jul 1994 03:13:46 GMT
  2418. Organization: Netcom Online Communications Services (408-241-9760 login: guest)
  2419.  
  2420. Even after scouring IM:PowerPC System Software, I yet labor under the
  2421. thick delusion that there is no way to prevent concurrency/reentrancy
  2422. on the PowerMac running native code. Whereas poking the SR worked just
  2423. fine before to keep interrupt code from unhappily butting in while
  2424. regular code was updating head and tail pointers on lists, there seems
  2425. to be no such mention of an equivalent "Critical Section" API on
  2426. PowerMac. Yea, verily, I believe it is not possible and am now
  2427. contemplating abandoning all Macintosh development. Say it ain't so.
  2428.  
  2429.  
  2430. P.S. While you're at it, tell me how it's possible to page-lock an
  2431. arbitrary range of memory while running native. Does the VM API
  2432. described in IM:Memory still apply? Or is it just, "tough luck --
  2433. you'll have to put everything you want in the system heap." Finally,
  2434. when (if ever) is the device driver interface going to be revved so
  2435. that drivers can be written native? IMHO, this is the dirtiest secret
  2436. kept by the Mac rags as device drivers far and away make the machine.
  2437.  
  2438. +++++++++++++++++++++++++++
  2439.  
  2440. >From rmah@panix.com (Robert Mah)
  2441. Date: Mon, 11 Jul 1994 01:04:22 -0500
  2442. Organization: One Step Beyond
  2443.  
  2444. afrancke@netcom.com (Andrew Francke) wrote:
  2445.  
  2446. ) Even after scouring IM:PowerPC System Software, I yet labor under the
  2447. ) thick delusion that there is no way to prevent concurrency/reentrancy
  2448. ) on the PowerMac running native code. Whereas poking the SR worked just
  2449. ) fine before to keep interrupt code from unhappily butting in while
  2450. ) regular code was updating head and tail pointers on lists, there seems
  2451. ) ...
  2452.  
  2453. What an extremely nasty way to check for interupts :-)
  2454.  
  2455. I simply use the OS queue routines.  Enqueue and Dequeue both disable
  2456. interupts so you can be SURE you're VBL's, callbacks and whatnot all
  2457. work nicely together.
  2458.  
  2459. Cheers,
  2460. Rob
  2461. _____________________________________________________________________
  2462. Robert S. Mah    :  Macintosh software development  :    212.947.6507
  2463. One Step Beyond  :      and network consulting      :  rmah@panix.com
  2464.  
  2465. +++++++++++++++++++++++++++
  2466.  
  2467. >From zstern@adobe.com (Zalman Stern)
  2468. Date: Mon, 11 Jul 1994 08:26:28 GMT
  2469. Organization: Adobe Systems Incorporated
  2470.  
  2471. Andrew Francke writes
  2472. > Even after scouring IM:PowerPC System Software, I yet labor under the
  2473. > thick delusion that there is no way to prevent concurrency/reentrancy
  2474. > on the PowerMac running native code. Whereas poking the SR worked just
  2475. > fine before to keep interrupt code from unhappily butting in while
  2476. > regular code was updating head and tail pointers on lists, there seems
  2477. > to be no such mention of an equivalent "Critical Section" API on
  2478. > PowerMac. Yea, verily, I believe it is not possible and am now
  2479. > contemplating abandoning all Macintosh development. Say it ain't so.
  2480.  
  2481. For updating queues in native code, the load-reserved/store-conditional  
  2482. mechanism is what you want to use. The mnemonics are lwarx and stwcx.  
  2483. respectively. There are examples on their usage in Appendix G of the MPC601  
  2484. User's Manual.
  2485.  
  2486. > P.S. While you're at it, tell me how it's possible to page-lock an
  2487. > arbitrary range of memory while running native. Does the VM API
  2488. > described in IM:Memory still apply?
  2489.  
  2490. It certainly should. (I.e. I haven't tried this, but I expect there's a  
  2491. moderate amount of 68k Mac software that would break if things did not work  
  2492. this way.)
  2493. --
  2494. Zalman Stern           zalman@adobe.com            (415) 962 3824
  2495. Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900
  2496. `Wait a second! This is just an octahedron suspended in blue liquid.' - JT
  2497.  
  2498. +++++++++++++++++++++++++++
  2499.  
  2500. >From mxmora@unix.sri.com (Matthew Xavier Mora)
  2501. Date: Mon, 11 Jul 1994 14:32:15 -0700
  2502. Organization: SRI International
  2503.  
  2504. In article <afranckeCsrAAz.95I@netcom.com>, afrancke@netcom.com (Andrew
  2505. Francke) wrote:
  2506.  
  2507. > on the PowerMac running native code. Whereas poking the SR worked just
  2508. > fine before to keep interrupt code from unhappily butting in while
  2509. > regular code was updating head and tail pointers on lists, there seems
  2510. > to be no such mention of an equivalent "Critical Section" API on
  2511. > PowerMac.
  2512.  
  2513. This is one thing that they say will die a horrible death in Copland.
  2514.  
  2515. Do not set SR!
  2516.  
  2517.  
  2518.  
  2519. > you'll have to put everything you want in the system heap." Finally,
  2520. > when (if ever) is the device driver interface going to be revved so
  2521. > that drivers can be written native? IMHO, this is the dirtiest secret
  2522. > kept by the Mac rags as device drivers far and away make the machine.
  2523.  
  2524. You'll have to wait for Copland release for the new Native Driver
  2525. support. Write  them at their Applink address if you want more information.
  2526. I don't know the address offhand. Its microkernel.<something>.
  2527.  
  2528.  
  2529.  
  2530. Xavier
  2531.  
  2532. -- 
  2533. Matt Mora mxmora@unix.sri.com
  2534. Testing Neswatcher
  2535.  
  2536. +++++++++++++++++++++++++++
  2537.  
  2538. >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
  2539. Date: Tue, 12 Jul 1994 10:45:59 +0800
  2540. Organization: Department of Computer Science, The University of Western Australia
  2541.  
  2542. In article <afranckeCsrAAz.95I@netcom.com>, afrancke@netcom.com (Andrew
  2543. Francke) wrote:
  2544.  
  2545. >Finally,
  2546. >when (if ever) is the device driver interface going to be revved so
  2547. >that drivers can be written native? IMHO, this is the dirtiest secret
  2548. >kept by the Mac rags as device drivers far and away make the machine.
  2549.  
  2550. You can write your drivers native, it's just that you have to have some
  2551. 68K glue at the front and thereby take a mixed-mode switch on every entry
  2552. to them.  But even if there was a native API you'd still be taking a
  2553. mixed-mode switch because the Device Manager (including the bit that
  2554. fields interrupts) is emulated.  So if you do a *lot* of work in your
  2555. device driver then writing it native would make sense.
  2556.  
  2557. All this mess is going to be sorted out in Copland.  Which means that a
  2558. lot of device drivers are going to have to be rewritten.
  2559. -- 
  2560. Quinn "The Eskimo!"      <quinn@cs.uwa.edu.au>     "Support HAVOC!"
  2561. Department of Computer Science, The University of Western Australia
  2562.   Who missed that session at WWDC and is desperately seeking the
  2563.   presentation CD.
  2564.  
  2565. +++++++++++++++++++++++++++
  2566.  
  2567. >From steele@isi.edu (Craig Steele)
  2568. Date: Tue, 12 Jul 1994 12:14:30 -0800
  2569. Organization: USC Information Sciences Institute
  2570.  
  2571. In article <mxmora-1107941432150001@xavier.sri.com>, mxmora@unix.sri.com 
  2572. (Matthew Xavier Mora) writes:
  2573. > You'll have to wait for Copland release for the new Native Driver 
  2574. > support. Write  them at their Applink address
  2575.  
  2576. Judging from the preliminary draft of "Designing PCI Cards and Drivers for 
  2577. Power Macintosh Computers" that arrived in my mailbox yesterday, bits of the 
  2578. future are coming a bit sooner.  A final PCI Card Developer's Kit for 
  2579. PowerMacs is said to be scheduled for APDA release in the "summer of 1994."  
  2580. The PCI runtime drivers use native interfaces.  You might be able to get a 
  2581. copy of the preliminary draft by contacting them at 
  2582. apple.pci.applelink.apple.com.
  2583.  
  2584.  
  2585. Craig S. Steele, steele@isi.edu - Not yet Institutionalized
  2586.  
  2587.  
  2588. +++++++++++++++++++++++++++
  2589.  
  2590. >From telesis@ecf.toronto.edu (Telesis North)
  2591. Date: Wed, 13 Jul 1994 04:19:47 GMT
  2592. Organization: telesis north & screen door company
  2593.  
  2594. In article <quinn-1207941045590001@edu-dynamic1.educ.ecel.uwa.edu.au>,
  2595. Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
  2596. >All this mess is going to be sorted out in Copland.  Which means that a
  2597. >lot of device drivers are going to have to be rewritten.
  2598.  
  2599. Actually, _all_ the device drivers are going to have to be re-written (or
  2600. break). That was my favourite quote out of the WWCC,
  2601.  
  2602.     "Under Copland, (current) 68K device drivers will not run."
  2603.  
  2604. Heh.
  2605.  
  2606. --
  2607. Roger Pantos                 Telesis North, Inc.           telesisnorth
  2608. Mac Software Guy             telesis@ecf.toronto.edu       (AppleLink)
  2609. Contrary to popular belief, green eggs & ham suck big time.
  2610.  
  2611. +++++++++++++++++++++++++++
  2612.  
  2613. >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
  2614. Date: Thu, 14 Jul 1994 11:20:10 +0800
  2615. Organization: Department of Computer Science, The University of Western Australia
  2616.  
  2617. In article <Csv2oz.KKK@ecf.toronto.edu>, telesis@ecf.toronto.edu (Telesis
  2618. North) wrote:
  2619.  
  2620. >In article <quinn-1207941045590001@edu-dynamic1.educ.ecel.uwa.edu.au>,
  2621. >Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
  2622. >>All this mess is going to be sorted out in Copland.  Which means that a
  2623. >>lot of device drivers are going to have to be rewritten.
  2624. >
  2625. >Actually, _all_ the device drivers are going to have to be re-written (or
  2626. >break). That was my favourite quote out of the WWCC,
  2627. >
  2628. >        "Under Copland, (current) 68K device drivers will not run."
  2629.  
  2630. Well this is an interesting question.  I didn't catch that session at WWDC
  2631. but I can see no reason why software only device drivers (such .Notify and
  2632. .Reminder) couldn't be supported.  These are just using the Device Manager
  2633. as a kludgy share library system that gives you non-interrupt time.  So
  2634. was there any comment about non-hardware device drivers?
  2635.  
  2636. >Roger Pantos
  2637.  
  2638. Hi Roger!  Maybe if your real name was something other that Telesis North
  2639. I'd catch your postings more often (:
  2640. -- 
  2641. Quinn "The Eskimo!"      <quinn@cs.uwa.edu.au>     "Support HAVOC!"
  2642. Department of Computer Science, The University of Western Australia
  2643.  
  2644. +++++++++++++++++++++++++++
  2645.  
  2646. >From rang@winternet.com (Anton Rang)
  2647. Date: 14 Jul 1994 04:24:00 GMT
  2648. Organization: Trillium Research, Inc.
  2649.  
  2650. In article <afranckeCsrAAz.95I@netcom.com> afrancke@netcom.com (Andrew Francke) writes:
  2651. >Even after scouring IM:PowerPC System Software, I yet labor under the
  2652. >thick delusion that there is no way to prevent concurrency/reentrancy
  2653. >on the PowerMac running native code.
  2654.  
  2655.   You're right!  Well, more or less.  You can change the SR by going
  2656. back into 68K code, and since all interrupts are currently dispatched
  2657. through the emulator, this will block them from being processed until
  2658. you change the SR back.  But (a) this will break, and (b) this will be
  2659. incredibly slow.  Don't do it if you don't have to.
  2660.  
  2661. >Whereas poking the SR worked just
  2662. >fine before to keep interrupt code from unhappily butting in while
  2663. >regular code was updating head and tail pointers on lists
  2664.  
  2665.   Well, in this case you can either (a) call Enqueue/Dequeue, which is
  2666. slow because of the mode switch but will be atomic, or (b) use a
  2667. little assembly language to call the lwarx/stwcx instructions.  Check
  2668. your manual for details.
  2669.  
  2670. >there seems to be no such mention of an equivalent "Critical Section"
  2671. >API on PowerMac.
  2672.  
  2673.   There will be.  Unfortunately, it's not there yet.  The hardware is
  2674. ahead of the software, currently.
  2675.  
  2676. >P.S. While you're at it, tell me how it's possible to page-lock an
  2677. >arbitrary range of memory while running native. Does the VM API
  2678. >described in IM:Memory still apply?
  2679.  
  2680.   Yes, that API still works.  (All the current APIs work, actually.)
  2681.  
  2682. >Finally, when (if ever) is the device driver interface going to be
  2683. >revved so that drivers can be written native?
  2684.  
  2685.   With the release of PCI-based Macintoshes, at first, and then with
  2686. the next major system release (for older PowerMacs too presumably).  I
  2687. wish it were sooner, I *hate* debugging my current driver.  :)
  2688. --
  2689. Anton Rang (rang@winternet.com)
  2690.  
  2691. +++++++++++++++++++++++++++
  2692.  
  2693. >From telesis@ecf.toronto.edu (Telesis North)
  2694. Date: Thu, 14 Jul 1994 04:47:49 GMT
  2695. Organization: Roger @ Telesis North
  2696.  
  2697. In article <quinn-1407941120100001@edu-dynamic1.educ.ecel.uwa.edu.au>,
  2698. Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
  2699. >
  2700. >Well this is an interesting question.  I didn't catch that session at WWDC
  2701. >but I can see no reason why software only device drivers (such .Notify and
  2702. >.Reminder) couldn't be supported.  These are just using the Device Manager
  2703. >as a kludgy share library system that gives you non-interrupt time.  So
  2704. >was there any comment about non-hardware device drivers?
  2705.  
  2706. I don't remember any; I just remember the speaker (Russell?) being
  2707. pretty blunt about it. My understanding is that they're planning on
  2708. ripping out the entire toolbox-level I/O architecture, along with
  2709. the 68K-centric interrupt services, and heaving it off the dock with
  2710. a huge sigh of relief. (It will of course be replaced with a spiffy
  2711. new re-entrant driver model with a message-passing interface to the
  2712. microkernel that will make life wonderful for everyone, once they've
  2713. re-written their drivers.)
  2714.  
  2715. I agree with your point, though. I'd say an easy 50% of the drivers
  2716. running on my machine are just there to provide user interface hacks
  2717. (or other software-only goodies). Come to think of it, it's probably
  2718. mostly intercine warfare between the Now Utilities and everyone else...
  2719.  
  2720. The problem is that most of these are so skanky, I'm not sure how far
  2721. you'd have to go, emulation-wise, to get any level of backward
  2722. compatibility.
  2723.  
  2724. I suppose that one could write an early-load INIT that patched
  2725. OpenDriver(), GetDCtlEntry() and friends, and used a faceless
  2726. background app to provide non-interrupt time to the drivers in
  2727. the custom entry table, but you'd still have people looking
  2728. for familiar things in the global Unit Table in the Toolbox
  2729. space, not to mention making asynchronous PBControl calls with
  2730. oddball semantics... I shudder even to think about it. :-)
  2731.  
  2732. Copland is going to break a lot of software, in the name of
  2733. performance. Not necessarily straight-line application software,
  2734. but lots of stand-alone gadgets and integrated systems. (Anyone
  2735. holding out any hope for FaxSTF?) 
  2736.  
  2737. Should Apple devote engineer and QA time to emulating the old driver
  2738. model? Tough question. I know I'm not going to - I'm going to re-write
  2739. our drivers (and turn them into processes, most likely).
  2740.  
  2741. >Hi Roger!  Maybe if your real name was something other that Telesis North
  2742. >I'd catch your postings more often (:
  2743.  
  2744. Yeah, yeah. :-)  I still get my news fix through an ancient Unix shell
  2745. account that we pay a university through the nose for. I'm thinking that
  2746. the time I could spend reading through the man pages might be better
  2747. spent pestering people to get my Mac IP-connected. (Still, beats
  2748. chipping out TCP packets on stone tablets, which is what we did in the
  2749. old days...)
  2750.  
  2751. --
  2752. Roger Pantos                 Telesis North, Inc.           telesisnorth
  2753. Mac Software Guy             telesis@ecf.toronto.edu       (AppleLink)
  2754. I can think of nothing more odious than a philosophy that forces its
  2755. beliefs or its conscriptions on those who are unwilling or uninterested
  2756. in having them.
  2757.  
  2758. +++++++++++++++++++++++++++
  2759.  
  2760. >From chewey@nesw.mv.com (Matthew E. Axsom)
  2761. Date: Fri, 15 Jul 1994 13:30:42 GMT
  2762. Organization: New England Software Works
  2763.  
  2764. In article <quinn-1407941120100001@edu-dynamic1.educ.ecel.uwa.edu.au>,
  2765. quinn@cs.uwa.edu.au (Quinn "The Eskimo!") wrote:
  2766.  
  2767. > In article <Csv2oz.KKK@ecf.toronto.edu>, telesis@ecf.toronto.edu (Telesis
  2768. > North) wrote:
  2769. > >In article <quinn-1207941045590001@edu-dynamic1.educ.ecel.uwa.edu.au>,
  2770. > >Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
  2771. > >>All this mess is going to be sorted out in Copland.  Which means that a
  2772. > >>lot of device drivers are going to have to be rewritten.
  2773. > >
  2774. > >Actually, _all_ the device drivers are going to have to be re-written (or
  2775. > >break). That was my favourite quote out of the WWCC,
  2776. > >
  2777. > >        "Under Copland, (current) 68K device drivers will not run."
  2778. > Well this is an interesting question.  I didn't catch that session at WWDC
  2779. > but I can see no reason why software only device drivers (such .Notify and
  2780. > .Reminder) couldn't be supported.  These are just using the Device Manager
  2781. > as a kludgy share library system that gives you non-interrupt time.  So
  2782. > was there any comment about non-hardware device drivers?
  2783. I believe that they used that as a blanket statement at first and later
  2784. backed away from that and said that the current driver model would still
  2785. run as long as it was a "softwre driver" (e.g. .Reminder or .Notify) and
  2786. not a "hardware driver".  I believe they said that as long as it doesn't
  2787. touch the hardware directly, the old drivers could still be used.
  2788.  
  2789. -Chewey
  2790. struct Matthew: E, Axsom { //chewey@nesw.mv.com
  2791.   Matthew(void) : E(), Axsom() {}
  2792.   Boolean macSoftwareEngineer(long future) {return future==Random();}
  2793.   Boolean newEnglandSoftwareWorks(StringPtr name) {return true;}
  2794. };
  2795.  
  2796. +++++++++++++++++++++++++++
  2797.  
  2798. >From absurd@apple.com (Tim Dierks)
  2799. Date: Fri, 22 Jul 1994 23:27:05 GMT
  2800. Organization: Apple Computer, Inc.
  2801.  
  2802. In article <Cswynq.Bx1@ecf.toronto.edu>, telesis@ecf.toronto.edu (Telesis
  2803. North) wrote:
  2804. > In article <quinn-1407941120100001@edu-dynamic1.educ.ecel.uwa.edu.au>,
  2805. > Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
  2806. > >
  2807. > >Well this is an interesting question.  I didn't catch that session at WWDC
  2808. > >but I can see no reason why software only device drivers (such .Notify and
  2809. > >.Reminder) couldn't be supported.  These are just using the Device Manager
  2810. > >as a kludgy share library system that gives you non-interrupt time.  So
  2811. > >was there any comment about non-hardware device drivers?
  2812. > I don't remember any; I just remember the speaker (Russell?) being
  2813. > pretty blunt about it. My understanding is that they're planning on
  2814. > ripping out the entire toolbox-level I/O architecture, along with
  2815. > the 68K-centric interrupt services, and heaving it off the dock with
  2816. > a huge sigh of relief. (It will of course be replaced with a spiffy
  2817. > new re-entrant driver model with a message-passing interface to the
  2818. > microkernel that will make life wonderful for everyone, once they've
  2819. > re-written their drivers.)
  2820. > I agree with your point, though. I'd say an easy 50% of the drivers
  2821. > running on my machine are just there to provide user interface hacks
  2822. > (or other software-only goodies). Come to think of it, it's probably
  2823. > mostly intercine warfare between the Now Utilities and everyone else...
  2824. > The problem is that most of these are so skanky, I'm not sure how far
  2825. > you'd have to go, emulation-wise, to get any level of backward
  2826. > compatibility.
  2827.  
  2828. Copland will support the Device manager driver model for dispatching to
  2829. old-style drivers; this level of compatibility should allow many drivers
  2830. to continue to work, especially those which are software-only, and just
  2831. manipulate data or dispatch to other drivers or toolboxes. Of course, this
  2832. doesn't guarantee the software inside the driver will still work
  2833. (depending on its assumptions), but we'll try to support the mechanism as
  2834. best we can. 68K drivers which touch hardware or which get invoked to
  2835. handle hardware interrupts will most likely not be compatible.
  2836.  
  2837. > Copland is going to break a lot of software, in the name of
  2838. > performance. Not necessarily straight-line application software,
  2839. > but lots of stand-alone gadgets and integrated systems. (Anyone
  2840. > holding out any hope for FaxSTF?) 
  2841. > Should Apple devote engineer and QA time to emulating the old driver
  2842. > model? Tough question. I know I'm not going to - I'm going to re-write
  2843. > our drivers (and turn them into processes, most likely).
  2844.  
  2845. Copland won't be 100% compatible, but a lot of the stuff we break we'll
  2846. break because it's fundamentally incompatible with progress; stuff that's
  2847. bad, but not that bad, we'll just have to see...
  2848.  
  2849. > Roger Pantos                 Telesis North, Inc.           telesisnorth
  2850.  
  2851. -- 
  2852. Tim Dierks
  2853. absurd@apple.com
  2854.  
  2855. ---------------------------
  2856.  
  2857. >From stk@uropax.contrib.de (Stefan Kurth)
  2858. Subject: Std filter proc trashes register D3!
  2859. Date: 18 Jul 1994 14:40:50 +0200
  2860. Organization: Contributed Software GbR
  2861.  
  2862. Just discovered another system software bug: the standard filter proc
  2863. (the one that you get with GetStdFilterProc() ) distroys the contents
  2864. of the D3 register. Took me quite some time to figure out why one my
  2865. variables kept changing all by itself...
  2866.  
  2867. Is this a known bug? If not, how do I go about reporting it to Apple?
  2868.  
  2869. ________________________________________________________________________
  2870. Stefan Kurth                 Berlin, Germany              stk@contrib.de
  2871.  
  2872. +++++++++++++++++++++++++++
  2873.  
  2874. >From D.A.G.Gillies@bradford.ac.uk (David Gillies)
  2875. Date: Mon, 18 Jul 1994 15:13:25 GMT
  2876. Organization: Unseen University, Ankh-Morpork
  2877.  
  2878. In article <30dt8i$32d@uropax.contrib.de> stk@uropax.contrib.de (Stefan Kurth) writes:
  2879. >Just discovered another system software bug: the standard filter proc
  2880. >(the one that you get with GetStdFilterProc() ) distroys the contents
  2881. >of the D3 register. Took me quite some time to figure out why one my
  2882. >variables kept changing all by itself...
  2883. >Is this a known bug? If not, how do I go about reporting it to Apple?
  2884. >
  2885. This definitely sounds like a bug. If nothing else, the compiler should make
  2886. callbacks safe by padding where necessary with MOVEM. It's only D0-D2 and
  2887. A0/A1 that routines are meant to be allowed to stamp on, and compilers
  2888. should recognize this and guard against it. I might be wrong, but this does
  2889. seem suspicious.
  2890.  
  2891. Personally I hate the standard filter proc, but I always prefer to roll my own.
  2892.  
  2893. ______________________________________________________________________
  2894. David A. G. Gillies                     (D.A.G.Gillies@bradford.ac.uk)
  2895.       University of Bradford, Bradford, West Yorkshire, England
  2896. (c) 1994 Wittgenstein and The Furniture Depository of The Living Dead
  2897.  
  2898. A little learning is a dangerous thing - but not half as dangerous as a
  2899. lot of ignorance.
  2900. - ---------------------REPLIES VIA EMAIL PLEASE-----------------------
  2901. _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  2902.  
  2903. +++++++++++++++++++++++++++
  2904.  
  2905. >From stk@uropax.contrib.de (Stefan Kurth)
  2906. Date: 19 Jul 1994 01:16:49 +0200
  2907. Organization: Contributed Software GbR
  2908.  
  2909. In article <1994Jul18.151325.8525@bradford.ac.uk>,
  2910. David Gillies <D.A.G.Gillies@bradford.ac.uk> wrote:
  2911.  
  2912. > In article <30dt8i$32d@uropax.contrib.de> stk@uropax.contrib.de
  2913. > (Stefan Kurth) writes:
  2914. >
  2915. > > Is this a known bug? If not, how do I go about reporting it to Apple?
  2916. >
  2917. > This definitely sounds like a bug.
  2918.  
  2919. Sure it is - my question was if it is a _known_ bug...  :-)
  2920.  
  2921. > If nothing else, the compiler should make callbacks safe by padding where
  2922. > necessary with MOVEM. It's only D0-D2 and A0/A1 that routines are meant
  2923. > to be allowed to stamp on, and compilers should recognize this and guard
  2924. > against it.
  2925.  
  2926. In this case it's not the compiler's job to save registers (I mean, not _my_
  2927. compiler's; it would have been the job of whatever compiler Apple used to
  2928. compile their system software). The standard filter proc should save the
  2929. registers that it uses; however, it saves only D4-D7, but also uses D3.
  2930.  
  2931. > Personally I hate the standard filter proc, but I always prefer to roll
  2932. > my own.
  2933.  
  2934. Would you explain why? I have found it extremely handy. It does a lot of
  2935. work for you.
  2936.  
  2937. ________________________________________________________________________
  2938. Stefan Kurth                 Berlin, Germany              stk@contrib.de
  2939.  
  2940. +++++++++++++++++++++++++++
  2941.  
  2942. >From Alexander M. Rosenberg <alexr@apple.com>
  2943. Date: Tue, 19 Jul 1994 02:20:19 GMT
  2944. Organization: Hackers Anonymous
  2945.  
  2946. In article <30dt8i$32d@uropax.contrib.de> Stefan Kurth, stk@uropax.contrib.de
  2947. writes:
  2948. > Just discovered another system software bug: the standard filter proc
  2949. > (the one that you get with GetStdFilterProc() ) distroys the contents
  2950. > of the D3 register. Took me quite some time to figure out why one my
  2951. > variables kept changing all by itself...
  2952. >  
  2953. > Is this a known bug? If not, how do I go about reporting it to Apple?
  2954.  
  2955. Yes. Thank you for taking the time to track it down. I believe that it is
  2956. under consideration for our next System Update release.
  2957. - -------------------------------------------------------------------------
  2958. -  Alexander M. Rosenberg  - INTERNET: alexr@apple.com      - Yoyodyne    -
  2959. -  330 Waverley St., Apt B - UUCP:ucbvax!apple!alexr        - Propulsion  -
  2960. -  Palo Alto, CA 94301     -                                - Systems     -
  2961. -  (415) 329-8463          - Nobody is my employer so       - :-)         -
  2962. -                          - nobody cares what I say.       -             -
  2963.  
  2964. +++++++++++++++++++++++++++
  2965.  
  2966. >From David A Lyons <dlyons@apple.com>
  2967. Date: Tue, 19 Jul 1994 06:00:07 GMT
  2968. Organization: Apple Computer, Inc.
  2969.  
  2970. In article <30dt8i$32d@uropax.contrib.de> Stefan Kurth,
  2971. stk@uropax.contrib.de writes:
  2972. > Just discovered another system software bug: the standard filter proc
  2973. > (the one that you get with GetStdFilterProc() ) distroys the contents
  2974. > of the D3 register. Took me quite some time to figure out why one my
  2975. > variables kept changing all by itself...
  2976. >  
  2977. > Is this a known bug? If not, how do I go about reporting it to Apple?
  2978.  
  2979. It's a known bug in ROMs earlier than the Quadra 840av/660av; for now
  2980. you'll have to work around it in your application.
  2981.  
  2982. Dave Lyons
  2983. Mr Tangent
  2984.  
  2985. +++++++++++++++++++++++++++
  2986.  
  2987. >From jonasw@lysator.liu.se (Jonas Wallden)
  2988. Date: 19 Jul 1994 16:59:31 GMT
  2989. Organization: (none)
  2990.  
  2991. David A Lyons <dlyons@apple.com> writes:
  2992. >In article <30dt8i$32d@uropax.contrib.de> Stefan Kurth,
  2993. >stk@uropax.contrib.de writes:
  2994. >> Just discovered another system software bug: the standard filter proc
  2995. >> (the one that you get with GetStdFilterProc() ) distroys the contents
  2996. >> of the D3 register. Took me quite some time to figure out why one my
  2997. >> variables kept changing all by itself...
  2998. >>  
  2999. >> Is this a known bug? If not, how do I go about reporting it to Apple?
  3000. >
  3001. >It's a known bug in ROMs earlier than the Quadra 840av/660av; for now
  3002. >you'll have to work around it in your application.
  3003. >
  3004. >Dave Lyons
  3005. >Mr Tangent
  3006.  
  3007. On a related subject: I installed a memory grow proc in an application that
  3008. uses a small heap, and that also uses StandardFile to select folders. I
  3009. noticed that my grow proc was called while the SF dialog was being shown,
  3010. and that SF tried to allocate a large memory block (size > 64 Kb). Of course
  3011. it failed to find the free memory but everything works ok anyway.
  3012.  
  3013. Is this just some cache memory that it tries to allocate for the fancy
  3014. color icons used by Hardware System Update 3.0? I will have to check again
  3015. to make sure it's not one of my system extensions playing a trick on me.
  3016.  
  3017. -- Jonas Wallden
  3018. --
  3019. -- Jonas Wallden -- Internet: jonasw@lysator.liu.se -- AppleLink: sw1369 --
  3020.  
  3021. +++++++++++++++++++++++++++
  3022.  
  3023. >From dean@genmagic.com (Dean Yu)
  3024. Date: 19 Jul 1994 18:35:23 GMT
  3025. Organization: General Magic, Inc.
  3026.  
  3027. In article <30dt8i$32d@uropax.contrib.de>, stk@uropax.contrib.de (Stefan
  3028. Kurth) wrote:
  3029. > Just discovered another system software bug: the standard filter proc
  3030. > (the one that you get with GetStdFilterProc() ) distroys the contents
  3031. > of the D3 register. Took me quite some time to figure out why one my
  3032. > variables kept changing all by itself...
  3033. >  
  3034. > Is this a known bug? If not, how do I go about reporting it to Apple?
  3035.  
  3036.   This is a known bug. (Well, I knew about it when I was there...) I seem
  3037. to remember writing some inline code to work around this problem, but I
  3038. don't remember what that was for.
  3039.  
  3040. -- Dean Yu
  3041.    Negative Ethnic Role Model
  3042.    General Magic, Inc.
  3043.  
  3044. ---------------------------
  3045.  
  3046. >From Jim Conner <jc30@cornell.edu>
  3047. Subject: Which NIM for serial port info?
  3048. Date: 25 Jul 1994 02:13:58 GMT
  3049. Organization: Cornell University
  3050.  
  3051. Hello,
  3052.  
  3053. I have been developing a somewhat specialized application for analysis of
  3054. data generated by an instrument in our lab.  Currently, the data is taken
  3055. from the instrument's small display unit and entered by hand into the
  3056. application.  The data is also available from the instrument's RS-232
  3057. port.  The hope is that this data can be sent directly from the
  3058. instrument to the Mac by way of one of the Mac's serial ports.
  3059.  
  3060. I think that I have a grip on the hardware aspect of this connection
  3061. (wiring one of the Mac's RS-422 serial ports so it looks like RS-232, and
  3062. making the correct cable to the instrument).  I would like to know,
  3063. though, (1) which New Inside Macintosh book covers serial port
  3064. manipulations, and (2) if anyone has any other references that have been
  3065. helpful with this sort of problem.
  3066.  
  3067. Thanks,
  3068. Jim Conner
  3069.  
  3070. +++++++++++++++++++++++++++
  3071.  
  3072. >From bierman@caelab1.cae.wisc.edu (Peter Bierman)
  3073. Date: Sun, 24 Jul 1994 23:43:13 -0500
  3074. Organization: The Metropolis BBS <614/846-1911> Info-Mac on CD!
  3075.  
  3076. In article <30v756$ghq@newsstand.cit.cornell.edu>, Jim Conner
  3077. <jc30@cornell.edu> wrote:
  3078.  
  3079.  
  3080. > I would like to know,
  3081. > though, (1) which New Inside Macintosh book covers serial port
  3082. > manipulations, and (2) if anyone has any other references that have been
  3083. > helpful with this sort of problem.
  3084.  
  3085. NIM: Devices. (I don't even know if it's out yet) Chapter 5.
  3086.  
  3087. Many people suggest "Terminal 2.2" as a great source for example code, in C.
  3088.  
  3089. -Peter
  3090.  
  3091. -- 
  3092. Peter Bierman                |"Sometimes I think that the surest sign
  3093. bierman@caelab1.cae.wisc.edu | that intelligent life exists elsewhere
  3094. The Metropolis 614/846-1911  | in the universe is that none of it has
  3095. 600+MB, 2CDs, 2Lines@14.4    | tried to contact us." --Calvin
  3096.  
  3097. ---------------------------
  3098.  
  3099. End of C.S.M.P. Digest
  3100. **********************
  3101.  
  3102.  
  3103.