home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Mac Game Programming Gurus
/
TricksOfTheMacGameProgrammingGurus.iso
/
Information
/
CSMP Digest
/
volume 1
/
csmp-v1-218.txt
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
NeXTSTEP
RISC OS/Acorn
UTF-8
Wrap
Text File
|
1994-12-08
|
57.7 KB
|
1,670 lines
|
[
TEXT/R*ch
]
C.S.M.P. Digest Tue, 24 Nov 92 Volume 1 : Issue 218
Today's Topics:
Best way to get A5 into VBLTaskProc?
How to flip images?
Genetic Algorithems
Scratch area low-memory globals
The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
The digest is a collection of article threads from the internet newsgroup
comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
regularly and want an archive of the discussions. If you don't know what a
newsgroup is, you probably don't have access to it. Ask your systems
administrator(s) for details. You can post articles to any newsgroup by
mailing your article to newsgroup@ucbvax.berkeley.edu. So, to post an
article to comp.sys.mac.programmer, you mail it to
comp-sys-mac-programmer@ucbvax.berkeley.edu. Note the '-' instead of '.'
in the newsgroup name.
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject. The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
cs.uoregon.edu). Article threads are not added to the digest until the last
article added to the thread is at least one month old (this is to ensure that
the thread is dead before adding it to the digest). Article threads that
consist of only one message are generally not included in the digest.
The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
[128.223.8.8] in the directory /pub/mac/csmp-digest. Be sure to read the
file /pub/mac/csmp-digest/README before downloading any files. The most
recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
directory /info-mac/digest/csmp. If you don't have ftp capability, the sumex
archive has a mail server; send a message with the text '$MACarch help' (no
quotes) to LISTSERV@ricevm1.rice.edu for more information.
The digest is also available via email. Just send a note saying that you
want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
automatically receive each new issue as it is created. Sorry, back issues
are not available through the mailing list.
Send administrative mail to mkelly@cs.uoregon.edu.
-------------------------------------------------------
From: sherman@michael.nmr.upmc.edu (Sherman Uitzetter)
Subject: Best way to get A5 into VBLTaskProc?
Date: 14 Oct 92 15:58:34 GMT
Organization: Pittsburgh NMRI
Hi, I want to synchronize some animation to the
vertical blanking of the main monitor (to avoid tearing
and flickering). I figure I create a VBLTask and use
SlotVInstall so I know when a vertical blank occurs.
The thing is, I need the VBLTaskProc to update some
variable that my program can poll to wait for a vertical
blank. Ok, I declare a global in my application,
gVBLCount, but I need a way for the VBLTaskProc to get
at this global to increment it. "Oh this is easy", I
say, before I realize there's no convenient place to put
A5 (as returned by CurrentA5()) so that the VBLTaskProc
can get at my applications globals. What I end up doing
works, but is hideous (see code below). I know there
are game-writers out there who have done this. Here's
your chance to spread your knowledge - how did you do
it?
Thanks in advance,
- -Sherman.
P.S. what is the "phase" field in the VBLTask record?
The code I was talking about above (THINK C 5.0.3) :
#include <Retrace.h>
/* so that the way this code compiles won't change if the project's
options are changed: */
#pragma options(!profile, force_frame, !global_optimizer, !defer_adjust,
!redundant_loads, !assign_registers)
long gVBLCount = 0L; /* the variable that is incremented by theVBLProc()
*/
VBLTask gTask;
/* here is the VBLTaskProc (called during vertical blanking interrupt) */
pascal void theVBLProc(void)
{
unsigned long oldA5;
/* set the A5 world to this application's A5 world */
oldA5 = SetA5(0x12345678); /* the 0x12345678 is what needs to be
modified by InitVBLTask() */
gVBLCount++;
/* restore the A5 world */
SetA5(oldA5);
}
/* initializes the VBLTask record and modifies theVBLProc */
void InitVBLTask(void)
{
unsigned long *procPtr; /* used to modify theVBLProc() */
gTask.qType = vType;
gTask.vblAddr = theVBLProc;
gTask.vblCount = 1; /* trigger right away */
gTask.vblPhase = 0; /* phase??? */
/* this is awful, but I have to modify code so that I can use globals in
theVBLProc() */
procPtr = (unsigned long *) ((unsigned long) gTask.vblAddr + 2);
procPtr = (unsigned long *) ((unsigned long) *procPtr + 6); /* the + 6
is very compiler dependent */
*procPtr = SetCurrentA5(); /* theVBLProc() is now correctly modified (I
hope, I hope :-} ) */
}
/* wastes time until a vertical blank occurs */
void SpinUntilVBL(void)
{
gVBLCount = 0;
gTask.vblCount = 1; /* trigger right away */
if (SlotVInstall((QElemPtr) &gTask, 0) != noErr)
return;
while (gVBLCount == 0)
;
}
+++++++++++++++++++++++++++
From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
Organization: Kalamazoo College
Date: Wed, 14 Oct 1992 17:07:45 GMT
sherman@michael.nmr.upmc.edu (Sherman Uitzetter) writes:
>
>Ok, I declare a global in my application,
>gVBLCount, but I need a way for the VBLTaskProc to get
>at this global to increment it. "Oh this is easy", I
>say, before I realize there's no convenient place to put
>A5 (as returned by CurrentA5()) so that the VBLTaskProc
>can get at my applications globals.
You can stick it right next to the VBLTask struct itself (see below).
> What I end up doing
>works, but is hideous
> [self-modifying code deleted]
Ow! You're not kidding! If you _do_ do something like this, remember
to flush the instruction cache. But, fortunately, there's an easier
way.
Just write something like:
long gVBLCount = 0L;
/***********
* Keep these two declarations together! The code depends on it!
*/
long gMyA5;
VBLTask gTask;
/*
***********/
/* See Tech Notes 180 and 208. */
long getVBLRec(void) = 0x2008; // move.l a0,d0
pascal void theVBLProc(void)
{
long myVBLRecAddr;
unsigned long oldA5;
myVBLRecAddr = getVBLRec();
oldA5 = SetA5( * ( (long*) myVBLRecAddr - 1 ) );
// Do your ++gVBLCount, or whatever, here. Globals are valid.
SetA5(oldA5);
}
And, in your InitVBLTask procedure, be sure to assign your app's A5 to
the global:
gMyA5 = SetCurrentA5();
- --
Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy
"I don't think we should have to have them wandering the streets
frightening women and people." - Pat Buchanan
+++++++++++++++++++++++++++
From: time@ice.com (Tim Endres)
Date: Wed, 14 Oct 92 15:46:29 EST
Organization: ICE Engineering, Inc.
In article <16947@pitt.UUCP> (comp.sys.mac.programmer), sherman@michael.nmr.upmc.edu (Sherman Uitzetter) writes:
> blank. Ok, I declare a global in my application,
> gVBLCount, but I need a way for the VBLTaskProc to get
> at this global to increment it. "Oh this is easy", I
One way is to extend your VBLTask structure:
typedef struct {
VBLTask gTask;
long A5;
} MyVBLTask;
And then you can set this field in your app, and send a pointer to
the extended struct into the VBL manager to install. Now, you get
the extended structure in your VBL task. If you are paranoid about
Apple later extending the VBLTask structure themselves, you might
try:
typedef struct {
VBLTask gTask;
char paranoia[32];
long A5;
} MyVBLTask;
or similar approaches to pad out your value...
tim.
tim endres - time@ice.com -or- tbomb!time
ICE Engineering, Inc - 8840 Main St, Whitmore Lake, MI 48189
Phone (313) 449 8288 - FAX (313) 449-9208
USENET - a slow moving self parody... ph
+++++++++++++++++++++++++++
From: absurd@applelink.apple.com (Tim Dierks, software saboteur)
Date: Wed, 14 Oct 1992 21:21:38 GMT
Organization: MacDTS Marauders
In article <1CE00001.g3sal8@tbomb.ice.com>, time@ice.com (Tim Endres)
wrote:
>
>
> In article <16947@pitt.UUCP> (comp.sys.mac.programmer), sherman@michael.nmr.upmc.edu (Sherman Uitzetter) writes:
> > blank. Ok, I declare a global in my application,
> > gVBLCount, but I need a way for the VBLTaskProc to get
> > at this global to increment it. "Oh this is easy", I
>
> One way is to extend your VBLTask structure:
>
> typedef struct {
> VBLTask gTask;
> long A5;
> } MyVBLTask;
>
> And then you can set this field in your app, and send a pointer to
> the extended struct into the VBL manager to install. Now, you get
> the extended structure in your VBL task. If you are paranoid about
> Apple later extending the VBLTask structure themselves, you might
> try:
>
> typedef struct {
> VBLTask gTask;
> char paranoia[32];
> long A5;
> } MyVBLTask;
>
> or similar approaches to pad out your value...
>
> tim.
Wow! You _are_ paranoid! Allow me to say that there is no way Apple
can make the VBLTask structure larger in this way; if we were to do
so, we would break every single application that uses a VBLTask; they
all allocate a standard amount of room, whether it is in a heap block,
global data space, or on the stack; if Apple we suddenly to start writing
to space after the end of this agreed-upon size, data would be trashed
in virtually every application that uses a VBLTask variable. Since
we're unlikely to invalidate our entire application base just to avoid
having to use something like an ExtendedVBLTask structure, I would say
your extra 32 bytes of storage are entirely unneeded. Other than that,
the concept of storing values after a VBLTask so they can be used by
the VBL is just great, and is an Officially Sanctioned Apple Solution (TM).
In fact, if you didn't want to screw around with A5 and all that other
garbage, you could just set up your structure like this:
typedef struct {
VBLTask gTask;
long gVBLCount;
} MyVBLTask;
and mess with the variable directly; this way, you don't use globals,
so you don't have to sweat the whole A5 thing.
Tim Dierks
MacDTS, but why not?
+++++++++++++++++++++++++++
From: mhall@abc.comp.sys.mac.programmer (Matthew Hall)
Date: 15 Oct 92 01:13:13 GMT
Organization: Oberlin College Computer Science
Hello-
I asked this same question recently and got the same answer.
However, that the address of the task is stored in A0 is not
documented in any IM that I can find. If it isn't documented, isn't
it about as safe as self modifying code? (I know for revised and
x-time tasks it is stored in reg A1, but it explicitly says in IMVI
that for slot tasks you may need to use self modifying code)
Confused about what Apple is doing,
- -matt hall
- --
- -------------------------------------------------------------------------------
Matt Hall. mhall@occs.oberlin.edu OR SMH9666@OBERLIN.BITNET
(216)-775-6613 (That's a Cleveland Area code. Lucky Me)
"Life's good, but not fair at all" -Lou Reed
+++++++++++++++++++++++++++
From: absurd@applelink.apple.com (Tim Dierks, software saboteur)
Date: 15 Oct 92 01:55:43 GMT
Organization: MacDTS Marauders
In article <MHALL.92Oct14201313@abc.comp.sys.mac.programmer>,
mhall@abc.comp.sys.mac.programmer (Matthew Hall) wrote:
>
> Hello-
> I asked this same question recently and got the same answer.
> However, that the address of the task is stored in A0 is not
> documented in any IM that I can find. If it isn't documented, isn't
> it about as safe as self modifying code? (I know for revised and
> x-time tasks it is stored in reg A1, but it explicitly says in IMVI
> that for slot tasks you may need to use self modifying code)
You're right- I can't find any place where this is documented.
Nonetheless, it's far more compatible than self-modifying code
if only because of the "safety in numbers" principle; Apple would
just as soon not break a large number of applications when releasing
a system release, if only because we always seem to take all the
blame, so you're safer if you're doing something a lot of people
are doing.
If you don't like it anyway, here's another way which isn't as
preferable (to me) as the VBLTask method, but which is much better
than your self-modifying code: if you're using MPW, put this in
an assembly file:
CASE ON
Stash PROC EXPORT ; Returns a pointer to the globals storage
LEA Store,A0 ; Load the address of the storage
MOVE.L A0,D0 ; into D0
RTS
Store
DC.L 0 ; Where the globals pointer is stored
ENDPROC
and add the following declaration to your C file:
extern long *Stash(void);
(If you're using Think, you'll need to translate this to inline assembly.)
Now, if you want to store a variable for later retrieval (your value of
A5, a counter, or the price of lettuce in Zanzibar), you just do the
following:
*(Stash()) = myImportantValue;
When you want to get it back later, such as from your VBL, you can just
do the following:
superImportantNumber = *(Stash());
If you wanted to store something else, like a Handle, you would just change
the prototype:
extern Handle *Stash(void);
This is safer because it doesn't actually modify code; thus, it won't run
afoul of data or instruction caches; however, it does store data in code
space, and therefore it would break if Apple ever decided to write-protect
program code.
> Confused about what Apple is doing,
> -matt hall
You think *you're* confused about what Apple is doing...
Tim Dierks
MacDTS, but I speak for the little men in my head
+++++++++++++++++++++++++++
From: peirce@outpost.SF-Bay.org (Michael Peirce)
Date: 15 Oct 92 17:20:11 GMT
Organization: Peirce Software
In article <absurd-141092140055@seuss.apple.com> (comp.sys.mac.programmer), absurd@applelink.apple.com (Tim Dierks, software saboteur) writes:
>
> Wow! You _are_ paranoid! Allow me to say that there is no way Apple
> can make the VBLTask structure larger in this way; if we were to do
> so, we would break every single application that uses a VBLTask; they
> all allocate a standard amount of room, whether it is in a heap block,
> global data space, or on the stack; if Apple we suddenly to start writing
> to space after the end of this agreed-upon size, data would be trashed
> in virtually every application that uses a VBLTask variable. Since
> we're unlikely to invalidate our entire application base just to avoid
> having to use something like an ExtendedVBLTask structure, I would say
> your extra 32 bytes of storage are entirely unneeded.
What I do to advoid the whole subject is to store my value right before
the parameter block. This way, I can always access it using the same
negative offset no matter which type of parameter block is used (be
it for a time manager task, an ioCompletion, etc).
- -- Michael Peirce -- peirce@outpost.SF-Bay.org
- -- Peirce Software -- Suite 301, 719 Hibiscus Place
- -- -- San Jose, California USA 95117
- -- Makers of... -- voice: (408) 244-6554 fax: (408) 244-6882
- -- SMOOTHIE -- AppleLink: peirce & America Online: AFC Peirce
+++++++++++++++++++++++++++
From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
Date: 15 Oct 92 21:11:47 GMT
Organization: Kalamazoo College
mhall@abc.comp.sys.mac.programmer (Matthew Hall) writes:
>However, that the address of the task is stored in A0 is not
>documented in any IM that I can find. If it isn't documented, isn't
>it about as safe as self modifying code? (...it explicitly says in IMVI
>that for slot tasks you may need to use self modifying code)
It _does_!? Tsk, tsk, tsk.
To quote from a comment in TN 180 ("Multifinder Miscellanea"), p. 5:
"GetVBLRec() returns the address of the VBLRec associated with our VBL
task. This works because on entry into the VBL task, A0 points to the
theVBLTask field in the VBLRec record, which is the first field in the
record and that is the address we return. Note that this method works
whether the VBLRec is allocated globally, in the heap...or...on the
stack. ... This trick allows us to get to the saved A5, but it could
also be used to get to anything we wanted to store in the record."
Safety in numbers, as someone else pointed out--if Apple changes this
little feature, hundreds of apps that trusted this Tech Note will die
horrible deaths. Apple won't want that to happen any more than you
will.
(And self-modifying code is never a good idea unless every cycle counts,
and that's not the case here. I imagine the PowerPC will write-protect
code segments and--who knows?--may compile 680x0 code into its native
language and cache it, in which case self-modifying programs will be
very unhappy.)
- --
Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy
I suppose ya don't think I was run over by a streetcar!
+++++++++++++++++++++++++++
From: kpm@well.sf.ca.us (Keith Morgan)
Date: 24 Oct 92 01:00:06 GMT
Organization: Whole Earth 'Lectronic Link
In article <16947@pitt.UUCP> sherman@michael.nmr.upmc.edu (Sherman Uitzetter) writes:
>
>
> Hi, I want to synchronize some animation to the
>vertical blanking of the main monitor (to avoid tearing
>and flickering). I figure I create a VBLTask and use
>SlotVInstall so I know when a vertical blank occurs.
>The thing is, I need the VBLTaskProc to update some
>variable that my program can poll to wait for a vertical
>blank. Ok, I declare a global in my application,
>gVBLCount, but I need a way for the VBLTaskProc to get
>at this global to increment it. "Oh this is easy", I
>say, before I realize there's no convenient place to put
>A5 (as returned by CurrentA5()) so that the VBLTaskProc
>can get at my applications globals. What I end up doing
>works, but is hideous (see code below). I know there
>are game-writers out there who have done this. Here's
>your chance to spread your knowledge - how did you do
>it?
I use a modified vbltask struct that has two extra fields.
One holds a pointer to a clock variable that is incremented every
vbl period; the other holds the app A5. (Code follows.) One problem
I have had is that if the appl crashes, the vbl task wants to continue
running, and since the application is dead, the entire machine is
hosed. I have installed a signal handler for errors that I catch
inside the app, but this doesn't work otherwise, making it necessary
to restart. Ideas anyone?
Keith Morgan | kpm@well.sf.ca.us
******** VTask.h:
#include <Retrace.h>
typedef unsigned long VClock, *VClockPtr;
struct VTask;
typedef void (*VTaskProcPtr) (struct VTask *theVTaskPtr);
typedef struct VTask
{
VBLTask vblTask;
long applA5;
VClockPtr vblClockPtr;
} VTask, *VTaskPtr;
void InstallVTask (VClockPtr theClockPtr, short count,
short theSlot, VTaskPtr theVTaskPtr);
void RemoveVTask (VTaskPtr theVTaskPtr, short theSlot);
short GetMainVideoSlot (void);
extern VClock gMainVideoVBLTicks;
void InitializeMainVideoVBLClock (void);
void CleanupMainVideoVBLClock (void);
void WaitForMainVideoVBL (void);
******** VTask.c
#include <stddef.h>
#include "VTask.h"
#include "Start.h"
/*
VBL task implementation that allows access to global variables.
*/
pascal void RunVTask (void);
void InstallVTask (VClockPtr theClockPtr, short count,
short theSlot, VTaskPtr theVTaskPtr)
{
theVTaskPtr->vblTask.qType = vType;
theVTaskPtr->vblTask.vblAddr = RunVTask;
theVTaskPtr->vblTask.vblCount = count;
theVTaskPtr->vblTask.vblPhase = 0; /* do it now */
theVTaskPtr->applA5 = SetCurrentA5();
theVTaskPtr->vblClockPtr = theClockPtr;
SlotVInstall((QElemPtr)theVTaskPtr, theSlot);
}
/*
While not documented in IM, Tech Note180 states that
the current task is in A0 when task exection is begun
*/
pascal void RunVTask ()
{
asm
{
move.l a5, -(sp) ; push A5 on stack
move.l offsetof(VTask,applA5)(a0), a5 ; load applA5 -> A5
move.l offsetof(VTask,vblClockPtr)(a0), a1 ; load clock pointer -> A1
addq.l #1, (a1) ; increment clock
move.w #1, offsetof(VBLTask,vblCount)(a0) ; store vblCount = 1
move.l (sp)+, A5 ; restore A5
}
}
void RemoveVTask (VTaskPtr theVTaskPtr, short theSlot)
{
SlotVRemove((QElemPtr)theVTaskPtr, theSlot);
}
/* main video VBL clock */
short gMainVideoSlot;
VClock gMainVideoVBLTicks;
VTask gMainVideoVBLTask;
short GetMainVideoSlot ()
{
DefVideoRec defvidrec;
GetVideoDefault(&defvidrec);
return defvidrec.sdSlot;
}
void InitializeMainVideoVBLClock ()
{
gMainVideoSlot = GetMainVideoSlot();
gMainVideoVBLTicks = 0;
InstallVTask(&gMainVideoVBLTicks, 1, gMainVideoSlot, &gMainVideoVBLTask);
}
void CleanupMainVideoVBLClock ()
{
RemoveVTask(&gMainVideoVBLTask, gMainVideoSlot);
}
void WaitForMainVideoVBL ()
{
VClock oldMainVideoVBLTicks = gMainVideoVBLTicks;
while (oldMainVideoVBLTicks == gMainVideoVBLTicks)
/* do nothing */;
}
---------------------------
From: mssmith@afterlife.ncsc.mil (M. Scott Smith)
Subject: How to flip images?
Date: 17 Oct 92 17:32:16 GMT
Organization: The Great Beyond
Hello..
I'm still learning how to do animation.. [ugh.]
Here's my latest question:
I've got pictures of a fish swimming to the right that I want to animate.
No problem. Now, I need pictures of the fish swimming left as well. As I
was about to load up my paint program to flip these images and save
"fish_swimming_left," it occurred to me this wasn't a good idea, and that
there must be a way to flip an image within QuickDraw.
And so I submersed myself in the IM's but didn't find anything. (Surprised?)
So, is there an easy way to do this?
Right now I'm drawing the "sprites" in offscreen GWorlds and CopyBitting
them to a window on the screen.
In theory, I know how to write my own "flip" routine, but I'm still so new
to GWorlds and etc. that I wouldn't know how to get down to the actual data.
(I want to keep this as high-level as possible until I begin to understand it
more.)
Any pointers, sample code, etc. would be greatly appreciated.
Thanks!
M. Scott Smith
(mssmith@afterlife.ncsc.mil)
+++++++++++++++++++++++++++
From: d88-jwa@alv.nada.kth.se (Jon Wtte)
Date: 18 Oct 92 14:00:44 GMT
Organization: Royal Institute of Technology, Stockholm, Sweden
> mssmith@afterlife.ncsc.mil (M. Scott Smith) writes:
was about to load up my paint program to flip these images and save
"fish_swimming_left," it occurred to me this wasn't a good idea, and that
there must be a way to flip an image within QuickDraw.
So, is there an easy way to do this?
Yes, draw into an offscreen GWorld. Do a LockPixels on its
PixMap. Do a GetPixBaseAddress. Now, with the Rect of your
fish, and rowBytes, and the size of a pixel, you have all you
need to write a flipping routine; walking from left to middle
and flipping the rightmost/leftmost pixels. Excercise for the
interested reader: what will happen if you walk from left to
extreme right and flip pixels? :-)
UnlockPixels afterwards.
- --
-- Jon W{tte, h+@nada.kth.se, Mac Hacker Suedoise (not french speaking) --
There's no problem that can't be solved using brute-force algorithms
and a sufficiently fast computer. Ergo, buy more hardware.
+++++++++++++++++++++++++++
From: Bruce@hoult.actrix.gen.nz
Date: Mon, 19 Oct 92 19:00:41 +1300 (NZDT)
References: <1992Oct17.173216.6223@afterlife.ncsc.mil>
Subject: Re: How to flip images?
M. Scott Smith asks:
> I've got pictures of a fish swimming to the right that I want to animate.
> No problem. Now, I need pictures of the fish swimming left as well. As I
> was about to load up my paint program to flip these images and save
> "fish_swimming_left," it occurred to me this wasn't a good idea, and that
> there must be a way to flip an image within QuickDraw.
> In theory, I know how to write my own "flip" routine, but I'm still so new
> to GWorlds and etc. that I wouldn't know how to get down to the actual data.
> (I want to keep this as high-level as possible until I begin to understand it
> more.)
You're right -- there's no way to flip images directly in QuickDraw, but you
don't
need to get down and dirty yourself either. Well, not *too* dirty...
Here's what comes to mind immediately:
Method 1) use CopyBits to copy a column of pixels at a time: copy the first
column of the source to the last column of the dest, then copy the second
column of the source to the next-to-last column of the dest etc etc. This
is real easy to write, but will call CopyBits once for every column in the
image.
Mathod 2) use CopyBits and several temporary bitmaps of different shapes:
abcdefgh
...becomes...
abcd
efgh
...becomes...
ab
ef
cd
gh
...becomes...
a
e
c
g
b
f
d
h
...becomes...
ba
fe
dc
hg
...becomes...
dcba
hgfe
...becomes...
hgfedcba
This will call copybits a number of times proportional to Log2(#columns), but
has the disadvantage of needing very tall intermediate bitmaps that are very
inefficient to store (because bitmaps are always a multiple of 16 wide)
Method 3) combine methods 1 and 2. Use 2 until the temp bitmap is 16 or 32
pixels
wide, then switch to 1, then back to 2.
Method 4) use CopyMask to do much the same thing, but without needing the
different shaped intermediate bitmaps. Creating the mask regions will be a
pain.
I.e. first use a region like this "XXXXXXXX " to swap the left and right
halves, then one like "XXXX XXXX " then one like "XX XX XX XX ",
then
finally one like "X X X X X X X X ".
Mathod 5) there is no method five right now :-)
- -- Bruce
+++++++++++++++++++++++++++
From: ivanski@world.std.com (Ivan M CaveroBelaunde)
Date: 21 Oct 92 01:10:22 GMT
Organization: The World Public Access UNIX, Brookline, MA
mssmith@afterlife.ncsc.mil (M. Scott Smith) writes:
> I've got pictures of a fish swimming to the right that I want to animate.
>No problem. Now, I need pictures of the fish swimming left as well. As I
>was about to load up my paint program to flip these images and save
>"fish_swimming_left," it occurred to me this wasn't a good idea, and that
>there must be a way to flip an image within QuickDraw.
> So, is there an easy way to do this?
Here's some sample code:
pascal void FixPC()
= {0x41FA, 0x000A, /* LEA *+$000C,A0 */
0x2008, /* MOVE.L A0,D0 */
0xA055, /* _StripAddress */
0x2040, /* MOVEA.L D0,A0 */
0x4ED0}; /* JMP (A0) ;jmps to next instruction */
void HorizontalFlipPixMap (PixMapHandle src)
/*
Assumes pixmaps are locked, depth is 32 bpp.
Depth is determined via the type of srcPtr and dstPtr in
the inner loop (long*: 32bpp, short*:16bpp,char*:8bpp).
*/
{
Rect theRect;
short width,height,hcount;
register short rowBytes;
unsigned char *srcBase, *dstBase;
char mmuMode;
mmuMode = GetMMUMode();
if ((PixMap32Bit(src)) && !mmuMode) {
mmuMode = true32b;
FixPC();
SwapMMUMode (&mmuMode);
}
theRect = (**src).bounds;
height = theRect.bottom - theRect.top;
width = theRect.right - theRect.left;
rowBytes = (**src).rowBytes&0x3fff;
hcount = height;
srcBase = GetPixBaseAddr(src) +
(rowBytes * theRect.top)
+ (((**src).pixelSize/8)*theRect.left);
dstBase = srcBase + (((**src).pixelSize/8) * (width-1));
while (hcount) {
register unsigned long *srcPtr, *dstPtr;
register short wcount;
srcPtr = (unsigned long*)srcBase;
dstPtr = (unsigned long*)dstBase;
wcount = width/2;
while (wcount) {
*(dstPtr--) = *(srcPtr++);
--wcount;
}
srcBase += rowBytes;
dstBase += rowBytes;
--hcount;
}
SwapMMUMode(&mmuMode);
}
Hope this helps,
- -Ivan
- ---
Ivan Cavero Belaunde
DiVA Corporation
+++++++++++++++++++++++++++
From: Roger.W.Brown@dartmouth.edu (Roger W. Brown)
Date: 21 Oct 92 15:52:27 GMT
Organization: Dartmouth College, Hanover, NH
In article <1992Oct17.173216.6223@afterlife.ncsc.mil>
mssmith@afterlife.ncsc.mil (M. Scott Smith) writes:
> I've got pictures of a fish swimming to the right that I want to animate.
> No problem. Now, I need pictures of the fish swimming left as well. As I
> was about to load up my paint program to flip these images and save
> "fish_swimming_left," it occurred to me this wasn't a good idea, and that
> there must be a way to flip an image within QuickDraw.
Just a thought...
If you are being a perfectionist and/or the look of the image is really
important in some way, then flipping an image in code won't give you
the right result if your image has shading. The shadows will then
appear on the wrong side. Better to use the paint program and have two
different images.
- --------------------------------------------------------------------
Roger Brown roger.brown@dartmouth.edu
Software Development
Kiewit Computation Center, Dartmouth College, Hanover, NH
+++++++++++++++++++++++++++
From: James_Zuchelli@qm.claris.com (James Zuchelli)
Date: 24 Oct 92 00:18:03 GMT
Organization: Claris Corp
In article <1992Oct21.155227.27633@dartvax.dartmouth.edu>, Roger.W.Brown@dartmouth.edu (Roger W. Brown) writes:
>
> In article <1992Oct17.173216.6223@afterlife.ncsc.mil>
> mssmith@afterlife.ncsc.mil (M. Scott Smith) writes:
>
> > I've got pictures of a fish swimming to the right that I want to animate.
> > No problem. Now, I need pictures of the fish swimming left as well. As I
> > was about to load up my paint program to flip these images and save
> > "fish_swimming_left," it occurred to me this wasn't a good idea, and that
> > there must be a way to flip an image within QuickDraw.
>
(deleted)
There wasa program out there called Aquarium, that featured a fish that
kept swimming from side to side, and off screen. The application and source
code were available. You could take a look at how the programmer did it there.
It's probably availabe on Compuserv of AOL. The version I had wasn't compatible
with system 7 and maybe not with Multifinder. But the fish still worked.
James Zuchelli
- ----------------------
The above is my personal opinion and not that of Claris Corp or my Employer.
---------------------------
Subject: Genetic Algorithems
From: $stephan@sasb (Stephan Fassmann, Software)
Date: 19 Oct 92 16:36:40 -0700
Organization: BYU
Does anyone know where to get information about Genetic Algorithems. I have
heard several things about it but nothing concrete.
Thanks.
_____________________________________________________________________
|Stephan Fassmann Internet: $stephan@sasb.byu.edu GEnie: S.FASSMANN
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|The Random Acts of Kindness will Continue until Morale Deteriorates|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+++++++++++++++++++++++++++
From: ewright@convex.com (Edward V. Wright)
Date: 20 Oct 92 19:12:53 GMT
Organization: Engineering, CONVEX Computer Corp., Richardson, Tx., USA
In <$stephan.268.0@sasb> $stephan@sasb (Stephan Fassmann, Software) writes:
>Does anyone know where to get information about Genetic Algorithems. I have
>heard several things about it but nothing concrete.
>Thanks.
Well, this may be a dumb answer, but there's a textbook called
Genetic Algorithms. Don't know the author, but I've seen in at
the local technical bookstore. Kind of expensive, though, as I
recall.
+++++++++++++++++++++++++++
From: peter@sysnext.library.upenn.edu (Peter C. Gorman)
Date: 21 Oct 92 13:00:02 GMT
Hello -
Here's the citation for Goldberg's excellent intro to GAs:
Author: Goldberg, David E. 1953-
Title: Genetic algorithms in search, optimization, and machine
learning / David E. Goldberg.
Edition: Repr. with corrections.
Published: Reading, Mass. : Addison-Wesley Pub. Co., 1989.
Description: xiii, 412 p. : ill. ; 25 cm.
There are also conference proceedings published annually; check Goldberg's
bibliography.
- --
Peter Gorman
University of Pennsylvania
Library Systems Office
peter@sysnext.library.upenn.edu
+++++++++++++++++++++++++++
From: cfhacc@ritvax.isc.rit.edu (Christopher Haupt)
Date: 22 Oct 92 17:28:42 GMT
Organization: Rochester Institute of Technology
In article <ewright.719608373@convex.convex.com>, ewright@convex.com
(Edward V. Wright) wrote:
>
> In <$stephan.268.0@sasb> $stephan@sasb (Stephan Fassmann, Software) writes:
>
> >Does anyone know where to get information about Genetic Algorithems. I have
> >heard several things about it but nothing concrete.
> >Thanks.
>
> Well, this may be a dumb answer, but there's a textbook called
> Genetic Algorithms. Don't know the author, but I've seen in at
> the local technical bookstore. Kind of expensive, though, as I
> recall.
David Goldberg's "Genetic Algorithms in search, optimization and
machine learning" (Addison-Wesley)
Goldberg may have earlier work as well.
I think there is a "Handbook of Genetic Algorithms", but am not sure of
the exact publishing info.
There are also a number of precedings, etc.
Most of the above are available in decent University libraries if
you access to such, otherwise technical bookstores.
There are some pd and freeware software floating around
the net as well.
Christopher Haupt--RIT/ISC/ACUS Soft.Supp. & RIT/CS (716) 475 5342
RIT;ISC;One Lomb Memorial Dr.;PO BOX 9887;Rochester NY 14623-0887 USA
cfhacc@ritvax.isc.rit.edu -or- cfhacc@ritvax.bitnet [AppleLink:HAUPT.C]
"Looking for reality in a virtual world..."
+++++++++++++++++++++++++++
From: mpc@biosys.apldbio.COM (Morgan Conrad)
Date: 22 Oct 92 23:58:49 GMT
Organization: Applied Biosystems Inc, Foster City, CA
There is a Genetic Algorithms mailing list and ftp site.
mailing list: GA-List-Request@AIC.NRL.NAVY.MIL
anonymous ftp archive: FTP.AIC.NRL.NAVY.MIL (see v6n5 for details)
A recent (last half year or so) Scientific American had an intro
article about genetic algorithms.
Morgan Conrad Cthulu for President!
Applied Biosystems
mpc@apldbio.com Why settle for
415-570-6667 the lesser evil?
+++++++++++++++++++++++++++
From: mrn@eplunix.UUCP (Mark R. Nilsen)
Date: 22 Oct 92 23:08:13 GMT
Organization: Eaton-Peabody Lab, Boston, MA
In article <ewright.719608373@convex.convex.com>,
ewright@convex.com (Edward V. Wright) writes:
> Nntp-Posting-Host: bach.convex.com
> X-Disclaimer: This message was written by a user at CONVEX Computer
> Corp. The opinions expressed are those of the user and
> not necessarily those of CONVEX.
>
>In<$stephan.268.0@sasb> $stephan@sasb (Stephan Fassmann, Software) writes:
>
>Does anyone know where to get information about Genetic Algorithems. I have
>heard several things about it but nothing concrete.
>Thanks.
An excellent book is "Handbook of Genetic Algorythms". I think it's
by Davis. It is an excellent introduction and survey of real-world
applications.
- --Mark.
- --
Mark Nilsen. == mrn%eplunix.UUCP@eddie.mit.edu
The world has changed and we can no longer think that logic is going to
prevail ...
- A. Scott Crossfield, Proceeding of X-15 first flight anniversary.
---------------------------
From: resnick@cogsci.uiuc.edu (Pete Resnick)
Subject: Scratch area low-memory globals
Organization: University of Illinois at Urbana
Date: Mon, 19 Oct 1992 01:41:42 GMT
A gross situation, but something that would make my life *much*
easier:
Way back in IM 1, several scratch areas are mentioned, including
Scratch20, Scratch8, ToolScratch, and ApplScratch. I would like to use
one of them to throw two instructions into and JMP to it. (The two
instructions being _DisposePtr and RTS; i.e. I want to dispose of the
block containing the code I am currently executing.) Questions:
1. Are these scratch areas still "supported"? I assume the *real*
answer is "no, low-memory globals are not supported", but I would like
to know if these will work as documented through System 7.1.
2. IM 1 says "Scratch20, Scratch8, and ToolScratch will not be
preserved across calls to the routines in the Macintosh ROM." Is this
true of _HwPriv? If I'm gonna put some code in there, I'm gonna have
to flush the cache.
3. Anyone got a better way to do this? Someone once suggested that I
could use the autopop bit, but of course DisposePtr is not a Toolbox
call, and therefore doesn't allow autopop.
Sorry for such an icky question.
pr
- --
Pete Resnick (...so what is a mojo, and why would one be rising?)
Graduate assistant - Philosophy Department, Gregory Hall, UIUC
System manager - Cognitive Science Group, Beckman Institute, UIUC
Internet: resnick@cogsci.uiuc.edu
+++++++++++++++++++++++++++
From: keith@taligent.com (Keith Rollin)
Date: 19 Oct 92 12:23:12 GMT
Organization: Taligent
In article <BwCI1J.BG8@news.cso.uiuc.edu>, resnick@cogsci.uiuc.edu (Pete
Resnick) wrote:
>
> A gross situation, but something that would make my life *much*
> easier:
>
> Way back in IM 1, several scratch areas are mentioned, including
> Scratch20, Scratch8, ToolScratch, and ApplScratch. I would like to use
> one of them to throw two instructions into and JMP to it. (The two
> instructions being _DisposePtr and RTS; i.e. I want to dispose of the
> block containing the code I am currently executing.) Questions:
>
> 1. Are these scratch areas still "supported"? I assume the *real*
> answer is "no, low-memory globals are not supported", but I would like
> to know if these will work as documented through System 7.1.
>
> 2. IM 1 says "Scratch20, Scratch8, and ToolScratch will not be
> preserved across calls to the routines in the Macintosh ROM." Is this
> true of _HwPriv? If I'm gonna put some code in there, I'm gonna have
> to flush the cache.
>
> 3. Anyone got a better way to do this? Someone once suggested that I
> could use the autopop bit, but of course DisposePtr is not a Toolbox
> call, and therefore doesn't allow autopop.
I don't think there's anything wrong with calling DisposePtr on yourself
while you're executing. Nothing will happen to your code block between the
call to DisposePtr and the RTS. It's not like there's a DisposePtrClear
call or anything. I could imagine that with all the work Apple is doing
with Power PC and such that they might come out with a funky new OS where
DiposePtr would act differently, but I can't see that happening for a LONG
time, if at all.
That answers your specific question, but I suggest you take a look at what
you are doing and see if you can't take a different approach. I've been
trying to think of what you might be doing where you'd want to do what you
ask above. The only thing I can think of is that you are writing a trap
patch that wants to remove itself after it's completed its task. If that's
so, keep in mind that removing a trap patch is not simple. If anyone over
patched you, they'll have a pointer to your code. If you remove that code,
you'll crash the system.
- -----
Keith Rollin
Phantom Programmer
Taligent, Inc.
+++++++++++++++++++++++++++
From: resnick@cogsci.uiuc.edu (Pete Resnick)
Date: 19 Oct 92 14:38:06 GMT
Organization: University of Illinois at Urbana
keith@taligent.com (Keith Rollin) writes:
>I don't think there's anything wrong with calling DisposePtr on yourself
>while you're executing. Nothing will happen to your code block between the
>call to DisposePtr and the RTS.
Yikes. I will go on this if noone comes up with anything better. I have
a great deal of faith in your comments Keith. Pretty darn frightening
though.
>That answers your specific question, but I suggest you take a look at what
>you are doing and see if you can't take a different approach. I've been
>trying to think of what you might be doing where you'd want to do what you
>ask above.
Actually, I am trying to post a notification using the Notification
Manager that is self deleting. If I want to post a notification from an
INIT (or other places I wont get back to), it's nice to have it delete
itself including its response code so that nothing is left lying
around. Joe Holt had some code to do this posted to the net a while
back where he put the _DisposPtr and RTS instructions into ToolScratch
and then jumped to it. Of course, this was highly Quadra incompatible
(as some of my users have let me know) because ToolScratch is not
updated in the instruction cache correctly.
Any more ideas?
pr
- --
Pete Resnick (...so what is a mojo, and why would one be rising?)
Graduate assistant - Philosophy Department, Gregory Hall, UIUC
System manager - Cognitive Science Group, Beckman Institute, UIUC
Internet: resnick@cogsci.uiuc.edu
+++++++++++++++++++++++++++
From: phils@chaos.cs.brandeis.edu (Phil Shapiro)
Date: 19 Oct 92 15:23:00 GMT
Organization: Symantec Corp.
>>>>> On Mon, 19 Oct 1992 12:23:12 GMT, keith@taligent.com (Keith Rollin) said:
In article <keith-191092051243@kip-55.taligent.com> keith@taligent.com (Keith Rollin) writes:
> In article <BwCI1J.BG8@news.cso.uiuc.edu>, resnick@cogsci.uiuc.edu (Pete
> Resnick) wrote:
>>
>> Way back in IM 1, several scratch areas are mentioned, including
>> Scratch20, Scratch8, ToolScratch, and ApplScratch. I would like to
>> use one of them to throw two instructions into and JMP to it. (The
>> two instructions being _DisposePtr and RTS; i.e. I want to dispose
>> of the block containing the code I am currently executing.)
> I don't think there's anything wrong with calling DisposePtr on
> yourself while you're executing. Nothing will happen to your code
> block between the call to DisposePtr and the RTS. It's not like
> there's a DisposePtrClear call or anything. I could imagine that
> with all the work Apple is doing with Power PC and such that they
> might come out with a funky new OS where DiposePtr would act
> differently, but I can't see that happening for a LONG time, if at
> all.
I have some code that installs a patch on the fly, and then needs to
remove itself later. My original version copied itself to a handle,
and then ended with DisposHandle, RTS; when I changed it to use a
pointer, this technique no longer worked. I changed it to put the
DisposPtr and RTS in ToolScratch, and it works fine. (_HwPriv doesn't
affect ToolScratch.)
I don't know why DisposPtr, RTS didn't work, but that's what happened.
Besides, what if a user is running your hack with a debugging utility
that *does* overwrite disposed blocks, like HeapQC or the Zap Handles
dcmd?
> That answers your specific question, but I suggest you take a look
> at what you are doing and see if you can't take a different
> approach. I've been trying to think of what you might be doing
> where you'd want to do what you ask above. The only thing I can
> think of is that you are writing a trap patch that wants to remove
> itself after it's completed its task. If that's so, keep in mind
> that removing a trap patch is not simple. If anyone over patched
> you, they'll have a pointer to your code. If you remove that code,
> you'll crash the system.
In my case I have an FKEY (project printer) that installs a couple
patches on the current application's heap. It has a very brief
lifetime, and I've never heard of any problems with it and other
patches.
-phil
- --
Phil Shapiro Software Engineer
Language Products Group Symantec Corporation
Internet: phils@cs.brandeis.edu
+++++++++++++++++++++++++++
From: resnick@cogsci.uiuc.edu (Pete Resnick)
Date: 20 Oct 92 06:38:59 GMT
Organization: University of Illinois at Urbana
ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
>OK, if it makes you happier, how about putting the DisposePtr/RTS sequence
>on the stack:
Actually, someone else recommended this to me in e-mail, and
personally I like it the best, except of course it won't run on a
68000. I think I am going to use the ToolScratch method if I am on a
68000 and use the stack method otherwise. Though I trust everyone that
_HwPriv doesn't change ToolScratch, why push my luck, right? Who knows
what will happen in the next version of the OS? At least as far as
stuff is documented now, this solution will work across the board.
Thanks to everyone for some great (and some *amusing*) suggestions!
pr
- --
Pete Resnick (...so what is a mojo, and why would one be rising?)
Graduate assistant - Philosophy Department, Gregory Hall, UIUC
System manager - Cognitive Science Group, Beckman Institute, UIUC
Internet: resnick@cogsci.uiuc.edu
+++++++++++++++++++++++++++
From: ivanski@world.std.com (Ivan M CaveroBelaunde)
Date: 20 Oct 92 07:37:40 GMT
Organization: The World Public Access UNIX, Brookline, MA
ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
>In article <BwDHzJ.9xM@news.cso.uiuc.edu>, resnick@cogsci.uiuc.edu (Pete Resnick) writes:
>> keith@taligent.com (Keith Rollin) writes:
>>
>>>I don't think there's anything wrong with calling DisposePtr on yourself
>>>while you're executing. Nothing will happen to your code block between the
>>>call to DisposePtr and the RTS.
>>
>> Yikes. I will go on this if noone comes up with anything better. I have
>> a great deal of faith in your comments Keith. Pretty darn frightening
>> though.
>OK, if it makes you happier, how about putting the DisposePtr/RTS sequence
>on the stack:
[ code deleted]
Am I totally missing something in this discussion? The first thing
that popped into my head was to do GetTrapAddress on DisposePtr
and do a JMP to it. Or will that break because of something else
regarding the context in which this code is executing?
- -Ivan
- ---
Ivan Cavero Belaunde
DiVA Corporation
+++++++++++++++++++++++++++
From: resnick@cogsci.uiuc.edu (Pete Resnick)
Date: 20 Oct 92 18:20:42 GMT
Organization: University of Illinois at Urbana
ivanski@world.std.com (Ivan M CaveroBelaunde) writes:
>Am I totally missing something in this discussion? The first thing
>that popped into my head was to do GetTrapAddress on DisposePtr
>and do a JMP to it. Or will that break because of something else
>regarding the context in which this code is executing?
I discussed this with someone in e-mail a little. Though it would
probably work for my purposes, jumping to the trap address is a really
bad idea, especially for memory management stuff, just in term of
future compatibility. Remember, when the processor hits the trap in
code, it generates an unimplemented instruction trap, meaning that the
processor will go from user mode to supervisor mode. If there is any
hope of having fancy stuff go on in future releases of the OS, the trap
mechanism is going to be a sure fire way of getting the machine to
switch modes. If anything is going to have to be in supervisor mode
when executing, the Memory Manager will.
All in all, the best answer seems to be avoid jumping directly to
traps if you can.
pr
- --
Pete Resnick (...so what is a mojo, and why would one be rising?)
Graduate assistant - Philosophy Department, Gregory Hall, UIUC
System manager - Cognitive Science Group, Beckman Institute, UIUC
Internet: resnick@cogsci.uiuc.edu
+++++++++++++++++++++++++++
From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
Date: 20 Oct 92 17:58:10 +1300
Organization: University of Waikato, Hamilton, New Zealand
In article <BwDHzJ.9xM@news.cso.uiuc.edu>, resnick@cogsci.uiuc.edu (Pete Resnick) writes:
> keith@taligent.com (Keith Rollin) writes:
>
>>I don't think there's anything wrong with calling DisposePtr on yourself
>>while you're executing. Nothing will happen to your code block between the
>>call to DisposePtr and the RTS.
>
> Yikes. I will go on this if noone comes up with anything better. I have
> a great deal of faith in your comments Keith. Pretty darn frightening
> though.
OK, if it makes you happier, how about putting the DisposePtr/RTS sequence
on the stack:
subq.l #6, sp ; make room for return-and-deallocate sequence
move.l 6(sp), (sp) ; move up return address
move.w #$A01F, 4(sp) ; _DisposePtr
move.w #$4E74, 6(sp) ; RTD #n
move.w #$0006, 8(sp) ; value of n for RTD
_FlushInstructionCache ; for brain-damaged processors that can't
_FlushDataCache ; keep their own caches straight
lea myself, a0 ; pointer to block to be freed
jmp 4(sp) ; enter deallocate-and-return sequence
> Joe Holt had some code to do this posted to the net a while
> back where he put the _DisposPtr and RTS instructions into ToolScratch
> and then jumped to it. Of course, this was highly Quadra incompatible
> (as some of my users have let me know) because ToolScratch is not
> updated in the instruction cache correctly.
So, flush the caches (as I did above). Any code that's running an event loop
that allows notifications to get in isn't going to lose much more speed
anyway. :-)
Lawrence D'Oliveiro fone: +64-7-856-2889
Computer Services Dept fax: +64-7-838-4066
University of Waikato electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00
Moderate positions are so sensible, somehow, although I've never taken one
myself. -- Bruce Tognazzini, "Tog on Interface"
+++++++++++++++++++++++++++
From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
Date: 21 Oct 92 16:52:40 +1300
Organization: University of Waikato, Hamilton, New Zealand
In article <BwEqGz.6yr@news.cso.uiuc.edu>, resnick@cogsci.uiuc.edu (Pete Resnick) writes:
> ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
>
>>OK, if it makes you happier, how about putting the DisposePtr/RTS sequence
>>on the stack:
>
> Actually, someone else recommended this to me in e-mail, and
> personally I like it the best, except of course it won't run on a
> 68000.
The only thing that won't work on a 68000 is the cache-flushing calls. So
check if the _HWPriv trap is implemented, and don't call it if not. The rest
should run fine on a 68000.
Further thought: to be 107.5% safe, you should flush the data cache BEFORE
flushing the instruction cache.
Lawrence D'Oliveiro fone: +64-7-856-2889
Computer Services Dept fax: +64-7-838-4066
University of Waikato electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00
Multiprocessing and multitasking offer the opportunity for change, but only if
we take it. We have the ability to design the overpasses that will lead our
users to the superhighways of computing. Let us not get bogged down in
designing high-speed traffic lights because we're still thinking in terms of
intersections. -- Bruce Tognazzini, "Tog on Interface"
+++++++++++++++++++++++++++
From: resnick@cogsci.uiuc.edu (Pete Resnick)
Organization: University of Illinois at Urbana
Date: Wed, 21 Oct 1992 16:17:00 GMT
ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
>>>OK, if it makes you happier, how about putting the DisposePtr/RTS sequence
>>>on the stack:
>>
>> Actually, someone else recommended this to me in e-mail, and
>> personally I like it the best, except of course it won't run on a
>> 68000.
>The only thing that won't work on a 68000 is the cache-flushing calls. So
>check if the _HWPriv trap is implemented, and don't call it if not. The rest
>should run fine on a 68000.
No, the thing that won't work on the 68000 is the RTD instruction;
there ain't no such thing on the 68000 processor, only the 68010 and
up. So I am stuck with the ToolScratch solution on the 68000.
>Further thought: to be 107.5% safe, you should flush the data cache BEFORE
>flushing the instruction cache.
Doesn't the _FlushInstructionCache (_HwPriv selector 1) flush both the
data and instruction caches? It was somewhere in Tech Note 261.
pr
- --
Pete Resnick (...so what is a mojo, and why would one be rising?)
Graduate assistant - Philosophy Department, Gregory Hall, UIUC
System manager - Cognitive Science Group, Beckman Institute, UIUC
Internet: resnick@cogsci.uiuc.edu
+++++++++++++++++++++++++++
From: resnick@cogsci.uiuc.edu (Pete Resnick)
Date: 22 Oct 92 08:51:35 GMT
Organization: University of Illinois at Urbana
ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
>In article <BwFMyK.7tv@news.cso.uiuc.edu>, resnick@cogsci.uiuc.edu (Pete Resnick) writes:
>> All in all, the best answer seems to be avoid jumping directly to
>> traps if you can.
>Says who? Has an official pronouncement come down from DTS that this is a
>Bad Idea?
I take the fifth on this one; actually, avoiding direct calls to traps
is something I think I picked up at last year's MacWorld, though I
can't tell you for sure what session we were talking about this in
(perhaps it was the INIT session). There is also a line in Tech Note
212 in reference to patching traps where it says, "Do not bypass the
Trap Dispatcher to call traps directly. The performance gains are
small, and there may be serious side effects." Aside from possible
reasons I gave in my posting, I think the reason for this had to do
with the way Apple deals with tail patching.
But again, I plead the fifth here; I'm not totally sure I have my
facts straight now that you press me.
>Traps are dumb way of calling OS services, anyway. Think of the overhead and
>of that dispatcher bottleneck, not to mention the inflexibility of a single,
>limited space of trap IDs. A direct procedure call is much simpler.
I can think of at least three advantages to traps as opposed to
procedure calls:
1. Easily updateable system routines. There are obvious problems with
statically linked libraries (you have to re-link with the new libraries
every time they are updated), and even dynamically linked libraries are
not pure joy (anyone upgraded SunOS lately?). With traps, all you need
to do is update the trap table, and you can deal with whether the
routine is now in RAM, ROM, or in some on-disk code resource that you
have to load up. Very flexible. (There are, BTW, almost 4100 possible
traps, plus the possibility of trap selectors; running out is not going
to be a problem.)
2. You get the switch up to supervisor mode if you are currently in
user mode. Again, this hasn't been taken advantage of by the MacOS to
date, but it could be.
3. Saves code size. Procedure calls will take 2-3 instructions, traps
are 1 word. This was probably important back when the original Mac came
out, though it is obviously less so today.
pr
- --
Pete Resnick (...so what is a mojo, and why would one be rising?)
Graduate assistant - Philosophy Department, Gregory Hall, UIUC
System manager - Cognitive Science Group, Beckman Institute, UIUC
Internet: resnick@cogsci.uiuc.edu
+++++++++++++++++++++++++++
Date: 22 Oct 92 14:13:19 GMT
Organization: Royal Institute of Technology, Stockholm, Sweden
resnick@cogsci.uiuc.edu (Pete Resnick) writes:
>> All in all, the best answer seems to be avoid jumping directly to
>> traps if you can.
>Says who? Has an official pronouncement come down from DTS that this is a
>Bad Idea?
212 in reference to patching traps where it says, "Do not bypass the
Trap Dispatcher to call traps directly. The performance gains are
small, and there may be serious side effects." Aside from possible
reasons I gave in my posting, I think the reason for this had to do
with the way Apple deals with tail patching.
Imagine something that does not run plain Motorola 68k code,
but intead interpreted it like SoftAT interprets 286 code.
Now, imagine a cool way to speed it up: as soon as you hit
an A trap, just call the corresponding NATIVE code, which will
run much faster than an emulated ROM routine would.
Now, what platform due in '93 would this apply to? :-)
- --
-- Jon W{tte, h+@nada.kth.se, Mac Hacker Suedoise (not french speaking) --
_/~| Yellow
/ * \_ Shark (This signature has won the "Worst ASCII
~~~~\/ Software Logo of the Year" award)
+++++++++++++++++++++++++++
From: buckeye@spf.trw.com (John Wallace)
Organization: TRW Sensor Data Processing Center, Redondo Beach, CA
Date: Thu, 22 Oct 92 21:31:30 GMT
In article <1992Oct22.165524.11609@waikato.ac.nz> ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
>>
>> All in all, the best answer seems to be avoid jumping directly to
>> traps if you can.
>
>Says who? Has an official pronouncement come down from DTS that this is a
>Bad Idea?
>
>Traps are dumb way of calling OS services, anyway. Think of the overhead and
>of that dispatcher bottleneck, not to mention the inflexibility of a single,
>limited space of trap IDs. A direct procedure call is much simpler.
The problem with jumping directly to a trap's code is that someone may
have patched the trap _after_ you got the address to call. In that
case you will miss their patch and their code won't work. The trap
dispatch takes very little time to execute (about 10 instructions) and does
not add significantly to the time it takes your code to execute. The
one level of indirection that traps provide gives lot of flexibility to
the Mac's OS and most system extensions rely on them. Seeing all of the
ingenious additions to the Mac OS written by third parties validates
Apple's patchable trap mechanism.
Realize that the trap dispatcher does more than call the trap's code.
It also saves and restores registers that are used by the OS. If
you jump directly to the trap's code then you become responsible for
saving these registers. Because of this you won't achieve the huge
speed improvement that you might expect.
The bottom line: don't save the address of a trap and then jump
directly to it unless you have extremely tight performance problems.
The nominal performance you gain isn't worth the compatibility problems
that may crop up.
Cheers!
John
- ------------
John Wallace buckeye@spf.trw.com
+++++++++++++++++++++++++++
From: bwilliam@iat.holonet.net (Bill Williams)
Date: 24 Oct 92 05:30:57 GMT
Organization: HoloNet (BBS: 510-704-1058)
keith@taligent.com (Keith Rollin) writes:
>I don't think there's anything wrong with calling DisposePtr on yourself
>while you're executing. Nothing will happen to your code block between the
>call to DisposePtr and the RTS.
Arrrgg!! I run a set of debugging aids from Apple called to check if bad
programmers accidentally dispose of resources as normal handles and
another one that clears handles that are disposed of (called "DoubleTrouble")
"DoubleTrouble" is GREAT. I run it all the time despite the slight
overhead of immediately corrupting contents of all deleted memory structures.
It of course would KILL a program that deletes the handle it is in before
it ever gets a chance to return!!!
Only ONE INIT out of tons that I use seems to have a problem and thought
that it was an innocent act to do.
A Good scratch area for jumping back would be a simple solution, or a
stack based trick that works.
Bill Williams
---------------------------
End of C.S.M.P. Digest
**********************