[comp.sys.mac.programmer] Tail patches

jeremyr@cs.qmc.ac.uk (Jeremy Roussak) (11/05/89)

I hope the net will pardon my ignorance, but I have seen a few comments
recently about "tail patching" of traps and have a couple of questions:

1. What exactly are "tail patches"?
2. If they are what I suspect they are, why are they bad?

Thank you for your help!

Jeremy Roussak

marc@Apple.COM (Mark Dawson) (11/06/89)

In article <1459@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy Roussak) writes:
>
>I hope the net will pardon my ignorance, but I have seen a few comments
>recently about "tail patching" of traps and have a couple of questions:
>
>1. What exactly are "tail patches"?
>2. If they are what I suspect they are, why are they bad?
>

1.  There are times that you may wish to replace or modify a Mac trap call
   (Say for example, _Write).  Suppose you have this horribly gross program
   that passes the volume name, instead of the drive # to the _Write call.
   You could write an intercept routine that would decode this name into the
   correct drive # and drive refnum for the "real" system _Write call.  It
   would then call the system _Write (This would be a "head" patch).  You
   could direct the system _Write to return to another piece of code (the
   "tail" patch) to do some special cleanup if there was some error.

   The problem with the "tail" patch is that there is some possibility that
   an Apple patch to that routine (to fix some bug/enhance it)  might be
   checking the return address to see if it should do something.  Since your
   return address would be on the stack first, this check would fail.  Before
   I worked at Apple I did use both the "head" and "tail" patches; I didn't see
   anyway around them.  I also never ran into this "return address check".  I
   am always crossing my fingers, hoping this case will never happen (it would
   REALLY break my code).   

   Someone else in Apple will have to comment on if they know of any of patches
that DO check the return addresses.  I don't know of any, but I don't claim to 
know the whole system.    Below is a snippet of code to do head & tail patches.
   
; 
; get address of system trap
;
   move.l	WRITE_TRAP,D0		; WRITE_TRAP = $A003 (_Write)
   _GetTrapAddress
   lea  SysTrapAdd,A1
   move.l A0,(A1)                       ; save system trap @
;
; make system _Write goto my trap
;   
   move.l      WRITE_TRAP,D0            ; WRITE_TRAP = $A003 (_Write)
   lea	MyWriteTrap,A0
   _SetTrapAddress 
....
....
;
; My write trap...does translation before & after call
;
MyWriteTrap
	bsr  DoDecode  			; adjust parm block
  	pea  AfterWrite			; write to return to	
	move.l	SysTrapAdd,-(sp)
        RTS				; goto system routine	
AfterWrite
       bsr  DoCleanUp
       RTS				; return to system	

chewy@apple.com (Paul Snively) (11/07/89)

In article <36250@apple.Apple.COM> marc@Apple.COM (Mark Dawson) writes:
> In article <1459@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy 
Roussak) writes:
> >
> >I hope the net will pardon my ignorance, but I have seen a few comments
> >recently about "tail patching" of traps and have a couple of questions:
> >
> >1. What exactly are "tail patches"?
> >2. If they are what I suspect they are, why are they bad?
> >
> 
> 1.  There are times that you may wish to replace or modify a Mac trap 
call
>    (Say for example, _Write).  Suppose you have this horribly gross 
program
>    that passes the volume name, instead of the drive # to the _Write 
call.
>    You could write an intercept routine that would decode this name into 
the
>    correct drive # and drive refnum for the "real" system _Write call.  
It
>    would then call the system _Write (This would be a "head" patch).  You
>    could direct the system _Write to return to another piece of code (the
>    "tail" patch) to do some special cleanup if there was some error.
> 
>    The problem with the "tail" patch is that there is some possibility 
that
>    an Apple patch to that routine (to fix some bug/enhance it)  might be
>    checking the return address to see if it should do something.  Since 
your
>    return address would be on the stack first, this check would fail.  
Before
>    I worked at Apple I did use both the "head" and "tail" patches; I 
didn't see
>    anyway around them.  I also never ran into this "return address 
check".  I
>    am always crossing my fingers, hoping this case will never happen (it 
would
>    REALLY break my code).   
> 
>    Someone else in Apple will have to comment on if they know of any of 
patches
> that DO check the return addresses.  I don't know of any, but I don't 
claim to 
> know the whole system.    Below is a snippet of code to do head & tail 
patches.

[Evil code deleted...]

ARRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRGH!!!

PLEASE PLEASE PLEASE don't do tail patches!  Mark gives a reasonably 
cogent explanation as to WHY you shouldn't tail patch, and then explains 
how to do it!?  [sigh...]

Listen now, and listen hard: you CAN'T KNOW AHEAD OF TIME WHETHER ANY TRAP 
WILL EVER HAVE "COME-FROM" RETURN-ADDRESS CHECKING OR NOT.  Just because 
it doesn't under System 6.0.3.7.2.1.8 on the Macintosh IIsex doesn't mean 
that it NEVER has or NEVER will!

DON'T TAIL PATCH.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

johnte@microsoft.UUCP (John Terranova) (11/07/89)

In article <1459@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy Roussak) writes:
>
>I hope the net will pardon my ignorance, but I have seen a few comments
>recently about "tail patching" of traps and have a couple of questions:
>
>1. What exactly are "tail patches"?

A patch is a lump of code that you want to execute instead of/in addition to
normal system/ROM code.  You make the system jump table point to your
code and you remember the previous contents so that you can replace it
later, if needed.

A tail patch is a patch whose first action (or, atleast, an early action)
is to call the original code, then process some data based on the original
results.  A very good example of a tail patch was in MacTutor some months
ago (I have no idea which issue).  That tail patch patched GetNextEvent
and modified events such that any key event with both the shift and caps
lock key down would generate a lower case letter.  As is done on PCs.
I will leave it to the reader to decide if one would actually want the
Mac to emulate the PC in this regard.

>2. If they are what I suspect they are, why are they bad?
 
I don't know what you suspect they are, but they are bad for a fairly 
simple reason.  Apple patches the ROM.  Apple patches much of the ROM.
Apple patches so much of the ROM that sometimes I think it would be
easier to just issue a replacement ROM (at a nominal charge, of course
:-).  If Apple were to replace entire routines which need a small patch,
then the system would grow that much more.  Instead, they pull off some
tricks to replace only pieces of routines.  I'm not exactly clear why,
but this requires some routines to need to check who called them to
determine what to do.  This code needs to know if the ROM called them
or an app did.  It determines this by checking the return address on
the stack.  If you tail patch then the routine is never called from
ROM (it's called from the heap).  Some ROM code then becomes confused,
which is a bad thing.

I hope this helps.  I hope this makes sense.  I heard this explanation
once some time ago.  Probably about the time of that MacTutor article.

BTW: a recent MacTutor article says that Apple won't outlaw tail patches
and they beat the alternative (lots of grungy assembly code).  Don't
mind that article.  Tail patches are evil.  They already break the system.
Avoid them.

>Thank you for your help!

Your Welcome.

>Jeremy Roussak

-----------------------+----------------------------+-------------------------
    John Terranova     |  What the Hell do I know?  |  I speak/type for me
johnte@microsoft.uucp  |  I come from Waunakee!     |  and no one else.
-----------------------+----------------------------+-------------------------
"You look so good; you feel good, too.  When they see you shake it, baby
 everybody's gonna pay attention to you and you and you." --Gerard, Shake It

shebanow@Apple.COM (Andrew Shebanow) (11/07/89)

Tail patches are trap patchs which do processing
after calling the original trap, or modify the stack
before calling the original patch. They're called
tail patches because the typically look like this:

	LEA	origTrapAddress,A0
	; do preprocessing
	JSR	(A0)
	; do postprocessing

Since the bad part is at the end of the patch, its a
tail patch.

A "clean" patch will have a format like this:

	; do processing
	LEA	origTrapAddr,A0
	JMP	(A0)

Tail patching is bad because of the techniques that Apple
uses in its System Software to fix bugs. Sometimes, a trap
(lets call it _TrapA) has bugs in it which would be very
difficult to fix without rewriting the trap's entire code.
Rather than do that, Apple will sometimes patch a different
trap (_TrapB) which is called by the broken trap (_TrapA).
_TrapB will check the address of the caller on the stack
and compare it to the hardcoded address of _TrapA's call,
and, if the addresses match, behave in a different manner
to fix the bug. This can cause a huge savings in speed and
memory usage, but it prevents the use of tail patches.
Continuing our example, if you patch _TrapA and then JSR to
the original _TrapA code, you will have changed the
contents of the stack. And believe it or not, some of the
patches are involved enough that they look two or three
stack levels high.

Hope this clears it up,

Andy Shebanow
Mr. Clean, MacDTS
Apple Computer, Inc.

omullarn@oracle.oracle.com (Oliver Mullarney) (11/08/89)

OK - I understand why we shouldn't use tail patches, but sometimes
you just gotta. How else can you catch a function result from a
trap call?
Now why doesn't Apple keep everyone happy by being a little bit
more inventive in their scheme for hacking patches called by traps
called by patches called by ...
Instead of maintaining hard coded return addresses (a bad move anyway,
considering TN 110, "Processor Compatibility", final para.) it would
be possible to examine the trap table for the address of the trap of
interest (in case it has been patched), scan forward from this address 
to find the RTS, and check to see if the return address on the stack 
lies between the trap/patch start and the RTS. Not lightning fast, but...
Maybe in the 50Hz machine we wouldn't even notice.

While on the subject, anyone out there got assembly to do stack crawling?
I need it for some of my tail patches... :-)
(No, really - I would be grateful if someone's done it already, and
wants to share their experience).

 Oliver
| Oliver Mullarney     |  "I have knowledge of Digital Watches,  and soon I   |
| Oracle Corporation   |   shall have knowledge of Video Cassette Recorders"  |
| omullarn@oracle.com  |                                      Time Bandits    |
 --------------- "Universally acknowledged to work just fine" ----------------

thecloud@dhw68k.cts.com (Ken McLeod) (11/08/89)

In article <1459@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy Roussak) writes:
>
>I hope the net will pardon my ignorance, but I have seen a few comments
>recently about "tail patching" of traps and have a couple of questions:
>
>1. What exactly are "tail patches"?
>2. If they are what I suspect they are, why are they bad?

  "Tail" patches call the original routine as a subroutine
call, after which control returns to the patch code again.
In pseudocode, they'd look something like this:

TailPatchProc()
   Call(originalRoutineAddr);
   MessWithResult();
end

  This type of patch can and does break, and tech note #212 specifically
warns against it. Some of Apple's patches check the return address on the
stack when they're called; this address will be at the "MessWithResult"
line in the above example (as opposed to in the routine the Apple patch is
looking for.)  Suppose, for example, you wanted to patch CopyBits to act
differently IF AND ONLY IF it was being called from routine X. To do that,
you might look at where CopyBits is going to return to after it's done
and compare that address to the known address (or range) in routine X.
If CopyBits has been "tail-patched" somewhere along the way, your patch
will be broken: the return address will NEVER match your assumption. Now,
when CopyBits DOES get called from routine X, the patch doesn't catch it,
and depending on why the patch was written in the first place, the Mac
may find the nearest cliff to jump over.

GoodPatchProc()
  DoEverythingFirst();
  move.l  oldRoutineAddr,A0
  jmp     (A0)
end // we never get here! //

  A much better way to write patches is to do everything you need to BEFORE
calling the original trap. When you're ready, you JMP directly to the old
routine, so that the original return address remains intact. Usually, this
sort of patch only needs to alter parameters on the stack, or some external
variable, so that the original routine will return the desired result. If
the patch must wait to see what the original routine is returning, then it's
time to think about a) writing your own replacement routine, or b) finding
a better place to patch into.  A lot of people make the mistake of patching
GetNextEvent instead of using the jGNEFilter mechanism, for example.

  Disclaimer: All I know is what I read in technotes... :-)
-- 
==========     .......     =============================================
Ken McLeod    :.     .:    UUCP: ...{spsd,zardoz,felix}!dhw68k!thecloud
==========   :::.. ..:::   INTERNET: thecloud@dhw68k.cts.com
                ////       =============================================

chewy@apple.com (Paul Snively) (11/09/89)

In article <1989Nov7.212837.5146@oracle.com> omullarn@oracle.oracle.com 
(Oliver Mullarney) writes:
> OK - I understand why we shouldn't use tail patches, but sometimes
> you just gotta. How else can you catch a function result from a
> trap call?
> Now why doesn't Apple keep everyone happy by being a little bit
> more inventive in their scheme for hacking patches called by traps
> called by patches called by ...
> Instead of maintaining hard coded return addresses (a bad move anyway,
> considering TN 110, "Processor Compatibility", final para.) it would
> be possible to examine the trap table for the address of the trap of
> interest (in case it has been patched), scan forward from this address 
> to find the RTS, and check to see if the return address on the stack 
> lies between the trap/patch start and the RTS. Not lightning fast, but...
> Maybe in the 50Hz machine we wouldn't even notice.

As for "sometimes you just gotta," all I can say is: don't do whatever it 
is you're doing that's "just gotta."  Find a "more inventive" way.

As for finding the trap address and looking "just within that trap" for 
the return address, I can only assume that you've never disassembled our 
ROMs.  Essentially what you're saying is that we should write a 680x0 
global flow-analysis routine that gets called for EVERY patch in the 
system.  Even at 50 MHz that would be UNBELIEVABLY slow, and that's 
assuming that your flow-analysis heuristic for 680x0 code was totally 
flawless.  Anyone here ever write a 680x0 flow-analysis program (Steve 
Jasik excepted)?  Didn't think so.

Don't tail patch.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

lsr@Apple.COM (Larry Rosenstein) (11/10/89)

In article <1989Nov7.212837.5146@oracle.com> omullarn@oracle.oracle.com 
(Oliver Mullarney) writes:

> OK - I understand why we shouldn't use tail patches, but sometimes
> you just gotta. How else can you catch a function result from a
> trap call?

As the Black Knight would say "No Way!"  If trap X has been tail patched 
to fix a bug, then your patch to trap X must call the original trap 
address with the same return address on the stack.  Otherwise the bug fix 
won't get activated.

> Instead of maintaining hard coded return addresses (a bad move anyway,
> considering TN 110, "Processor Compatibility", final para.) it would

Hard coding a ROM address means you are tied to a particular ROM.  Patches 
are already machine-specific, so it makes sense to use hard-coded 
addresses to simplify the patches.

> be possible to examine the trap table for the address of the trap of
> interest (in case it has been patched), scan forward from this address 
> to find the RTS, and check to see if the return address on the stack 

I don't think this would work, for several reasons.  First, I don't think 
you can do a simple scan.  I doubt that patches are written in a nice 
linear format.  

Second, your idea tries to determine if a call to Apple's patch (which 
checks the return address) came from the currently installed patch.  The 
problem is that a trap can be patched several times.  Your idea only 
checks the most recent patch.

Also, the whole idea of Apple's patches checking the return address is to 
determine where the *original* call came from.  The patch is intended to 
be activate only in one particular case, when it knows the state of the 
world and can fix the problem.

Suppose there is a bug in the ROM.  The System S/W people find a trap call 
in the ROM that occurs before the bug manifests itself.  They install a 
patch that watches for this particular call and fixes up the state of the 
machine to correct the problem.  This might involve changing a register or 
changing some value on the stack.  (I've never tried fixing bugs in the 
ROM, so I'm guessing at the exact process.)

The trap that's patches bears no relationship to the trap that contains 
the bug.  In fact, patches are likely to appear in frequently called 
routines (eg, Memory Manager routines, BlockMove, etc.), since they tend 
to be called in a lot of different places.

The only way to avoid patches that look at the return address would be to 
replace entire pieces of the ROM.  This would make bug fixes take up more 
RAM space that they do now.


Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

jeremyr@cs.qmc.ac.uk (Jeremy Roussak) (11/10/89)

>As for "sometimes you just gotta," all I can say is: don't do whatever it 
>is you're doing that's "just gotta."  Find a "more inventive" way.

Since I initiated this thread, perhaps I could explain what I was doing, 
and ask if anyone can suggest an alternative way of doing it.

I was challenged to write a patch which would play a sound, preferably
whenever the Finder emptied the wastebasket (doesn't appear to be possible)
or at least when "Empty Wastebasket" was chosen from the menu.  The
reason for this curious request was that the person concerned had changed
the wastebasket icon to look like a toilet and wanted it to flush!

The obvious thing to do, (and we all do obvious things, don't we...)
was to do a tail patch on MenuSelect, look for a return of 0x00050002,
check that CurApName is the same as FinderName and to play the sound
if it is.  I did it.  It worked.  It's not subtle, or particularly
clever, I confess.

How should I have done this, without using a tail patch?

Jeremy Roussak

parent@apple.com (Sean Parent) (11/10/89)

I have written lots of patches of all kinds in the past and I can tell you 
that they are not simple. If you are writting an application then there is 
no good reason to patch a trap that I have been able to determine... so 
don't. If you are writting an INIT, or some funky piece of sudo-system 
software then you are walking a fine compatibility line to begin with and 
you should try to avoid patches.

Take a close look at your code to see if there is some way around the 
problem. For example: If you are writting an INIT and you wish to display 
an alert after the system has started up then don't patch SystemTask or 
GetNextEvent but use the notification manager. Or, if you just need some 
time then install a driver and get idle time that way.

If you deside you must patch a trap then try to avoid tail patches for the 
reasons mentioned previously. Patches to ROM routines do depend on return 
address (I know, I wrote one that does). With any kind of patch the rule 
is "take only picture, leave only footprints." Live by it. Restore 
EVERYTHING you can that you disturb. When chaining to the next routine 
restore ALL registers to their previous values, this can be done by 
reserving space on the stack at the start of your routine and moving the 
address that you will continue to into this space. At the end of your 
patch then restore all registers and do an RTS. The reason for this is that
there are patches that upon checking the return address make assumptions 
about what is in the registers at that particular moment.

Be aware that:
Multifinder keeps seperate trap tables for each application.
On 64K ROM machines the patch must be in the first 64K of RAM.
If you remove your patch someone may have patched it after you so don't 
remove their patch also.
Some traps dispatch to the same routine. For example _write async, and 
_write sync, dispatch to the same routine with the trap number in register 
D1 so you can determine which call was being made.
Your patch may NEVER get called if something in the system (like 
Multifinder) replaces the routine entirely.

If you do write patches be prepared for your software to break even if you 
write it very carefully. Warn your employer and understand that you need a 
good update service in place to fix problems that may arise with the next 
realese of system software. Build a maintenace clause into your contract 
if you are working as a contractor.

And before you write the patch, send DTS a link. They are pretty good at 
talking people off the roof. Give them a chance.

Sean Parent
"Quality unattainable in a reasonable amount of time."

parent@apple.com (Sean Parent) (11/11/89)

In article <1467@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy 
Roussak) writes:
> I was challenged to write a patch which would play a sound, preferably
> whenever the Finder emptied the wastebasket (doesn't appear to be 
possible)
> or at least when "Empty Wastebasket" was chosen from the menu.  The
> reason for this curious request was that the person concerned had changed
> the wastebasket icon to look like a toilet and wanted it to flush!

I would say that this falls into the catagory of one time, skanky, 
useless hacks :-). There is no way that you could ever do this cleanly 
unless the Mac had an empty trash trap which it doesn't. You can not be 
sure that the menu items will not change in the future (in fact, I'm sure 
they will). You could patch the FileManager so that the flush is sounded 
every time a file is deleted but that may be over kill since lots of 
applications create temporary files.

I hope you would never put such a hack into a commercial piece of software.

Sean Parent
"Quality unattainable in a reasonable amount of time."

dwb@sticks.apple.com (David W. Berry) (11/11/89)

In article <5133@internal.Apple.COM> parent@apple.com (Sean Parent) writes:
>In article <1467@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy 
>Roussak) writes:
>> I was challenged to write a patch which would play a sound, preferably
>> whenever the Finder emptied the wastebasket (doesn't appear to be 
>possible)
>> or at least when "Empty Wastebasket" was chosen from the menu.  The
>> reason for this curious request was that the person concerned had changed
>> the wastebasket icon to look like a toilet and wanted it to flush!
>
>I would say that this falls into the catagory of one time, skanky, 
>useless hacks :-). There is no way that you could ever do this cleanly 
>unless the Mac had an empty trash trap which it doesn't. You can not be 
>sure that the menu items will not change in the future (in fact, I'm sure 
>they will). You could patch the FileManager so that the flush is sounded 
>every time a file is deleted but that may be over kill since lots of 
>applications create temporary files.
	How about patching the FileManager to make rude noises whenever
a file with both the desktop and trash bits set is deleted.  It's fairly
clean, straight forward, and can be done with a head patch instead of
a tail patch.
Opinions:  MINE, ALL MINE! (greedy evil chuckle)

David W. Berry		(A/UX Toolbox Engineer)
dwb@apple.com		973-5168@408.MaBell		AppleLink: berry1

cyosta@taux01.UUCP ( Yossie Silverman) (11/11/89)

In article <1467@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy Roussak) writes:
.>As for "sometimes you just gotta," all I can say is: don't do whatever it 
.>is you're doing that's "just gotta."  Find a "more inventive" way.
.
.Since I initiated this thread, perhaps I could explain what I was doing, 
.and ask if anyone can suggest an alternative way of doing it.
.
.I was challenged to write a patch which would play a sound, preferably
.whenever the Finder emptied the wastebasket (doesn't appear to be possible)
.or at least when "Empty Wastebasket" was chosen from the menu.  The
.reason for this curious request was that the person concerned had changed
.the wastebasket icon to look like a toilet and wanted it to flush!
.
.The obvious thing to do, (and we all do obvious things, don't we...)
.was to do a tail patch on MenuSelect, look for a return of 0x00050002,
.check that CurApName is the same as FinderName and to play the sound
.if it is.  I did it.  It worked.  It's not subtle, or particularly
.clever, I confess.
.
.How should I have done this, without using a tail patch?
.
.Jeremy Roussak

I have a neat idea, check for a transition from the 'empty trash' icon
to the 'full trash' icon, and back.  In you case you can produce an
obscene noise (toilet seat going slam) when trash fills, and a flush
sound when it empties.  This would be done by patching copybits and
doing some compares on the bitmap's when the appname = finder.  Whatcha
think?  It would only fail if some other application had the same icon
and it was being displayed in a finder window.  It would fail when someone
changed the 'trash can' icons on you.  This seems to be a legal patch,
after all ColorFinder is doing it as well as ColorQD32 (and who knows
who else).  In fact, the same mechanism could probably be used for other
interesting effects!  You could make noises whenever an icon of your
choice appeared on the screen.  Of course this would fail if ColorFinder
was replacing the B/W icon (which you recognize) with a color one (which
you don't).  Ah well, enough talk.  Go for it!   - Yossie

-- 
Yossie Silverman                                   What did the Caspian sea?
National Semiconductor Ltd. (Israel)
cyosta%taux01@nsc.nsc.COM         or        RPR1YOS@TECHNION.BITNET
NSA LSD FBI KGB PCP CIA MOSAD NUCLEAR MI5 SPY ASSASSINATE SDI -- OOLCAY ITAY

jmunkki@kampi.hut.fi (Juri Munkki) (11/11/89)

Tail patching seems to be one of those subjects that pop up now and then.
Most people seem to agree that Apple is doing a stupid thing with the come
from patch method. In addition to making tail patching impossible, they make
the system software much more fragile.

About six months ago the net was fighting with Apple asking them to change
the way they install patches. I even came up with a method that in my humble
opinion would solve the whole problem from the point of view of developers
who want to tail patch.

The idea is to use a shadow dispatch table for those traps that are used
for come from patching. Calling GetTrapAddress gives that address from the
shadow table and calling SetTrapAddress changes the shadow dispatch table.
The addresses in the old dispatch table always point to routines that use
the come from method. The come from patch does it's processing and then
directly jumps into the shadow dispatch table.

The best thing would of course be to change the way apple patches those
long routines, but since they have started doing something stupid, it is
very unlikely that they will ever stop.

I wonder how much come from patching slows down the system. Most traps
that are used for come from processing are short utility traps. Perhaps
the most annoying examples are FixMul, FixDiv, FixRound and SectRect.
I recommend that you use your own versions of these routines, if you
intend to do any time-critical processing. 

_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^

mystone@caen.engin.umich.edu (Dean Yu) (11/11/89)

In article <1467@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy Roussak) writes:
>>As for "sometimes you just gotta," all I can say is: don't do whatever it 
>>is you're doing that's "just gotta."  Find a "more inventive" way.
>
>Since I initiated this thread, perhaps I could explain what I was doing, 
>and ask if anyone can suggest an alternative way of doing it.
>
>I was challenged to write a patch which would play a sound, preferably
>whenever the Finder emptied the wastebasket (doesn't appear to be possible)
>or at least when "Empty Wastebasket" was chosen from the menu.  The
>reason for this curious request was that the person concerned had changed
>the wastebasket icon to look like a toilet and wanted it to flush!
>
>The obvious thing to do, (and we all do obvious things, don't we...)
>was to do a tail patch on MenuSelect, look for a return of 0x00050002,
>check that CurApName is the same as FinderName and to play the sound
>if it is.  I did it.  It worked.  It's not subtle, or particularly
>clever, I confess.
>
>How should I have done this, without using a tail patch?
>

  Install an event filter in jGNEFilter that looks for mouse ups.  When you
get a mouse up, and CurApName is FinderName, look at MenuDisable.  If it's
$00050002, then flush your toilet.  (How's that for twisted?)
  Or, even better (depending on how you look at it) yet, patch _CopyBits.
When the source and destionation rectangles are 32 by 32, do a bitwise compare
with the stuffed trash can.  (Or whatever your new icon is that signifies 
there's something in the trash.)  If it's changing to the full state, set a
flag in your code.  Next time _CopyBits is called with source and destination
rectangles of 32 by 32, and the bit map is the empty state of the trash
can, play your sound here, then go on to the old _CopyBits.  My, how the mind
goes at 5:15 in the morning...

_______________________________________________________________________________
Dean Yu                            | E-mail: mystone@caen.engin.umich.edu
Self-declared License Czar         | Real-mail: Dean Yu
University of Michigan             |            909 Church St
Computer Aided Engineering Network |            Apt C
     INCLUDE 'Disclaimers.a'       |            Ann Arbor, MI 48104
-------------------------------------------------------------------------------

chewy@apple.com (Paul Snively) (11/12/89)

In article <26596@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:
> The best thing would of course be to change the way apple patches those
> long routines, but since they have started doing something stupid, it is
> very unlikely that they will ever stop.

Momentum isn't the primary reason that we haven't changed the scheme; the 
original rationale is.

Larry Rosenstein has already explained that rationale in this forum quite 
cogently; I suggest that you re-read some of the old messages in this 
thread to find it.

In particular, I can think of some really evil compatibility problems that 
your suggested fix could provoke; that's one reason that we aren't likely 
to use it in the future.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

omullarn@oracle.oracle.com (Oliver Mullarney) (11/12/89)

In article <1467@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy Roussak) writes:
>As for "sometimes you just gotta," all I can say is: don't do whatever it 
>is you're doing that's "just gotta."  Find a "more inventive" way.

Well, we've had a few responses to the toilet flush tail patch issue, so
perhaps someone can tell me how I can avoid the tail patches I said I
"just gotta" do.
I'm trying (so far, successfully) to patch a number of traps in order to
monitor memory usage on the Mac. I need to create log files listing everything
I can find out about memory allocation, reallocation and freeing. Sizes,
stack traces and, most importantly (in this discussion) the value of the
returned Handle or Pointer.
Hence - tail patch NewHandle and NewPtr so that I can examine A0 for the
result. I can't think of any other way (apart from sticking a JSR at the the
end of the NewHandle and NewPtr glue, which I don't think I can modify. I
may also end up patching NewRgn, NewWindow etc. and don't know what the
story is on glue routines for these calls).

Any alternatives in this case?
(Not that it's crucial - these patches will never make it out into the real 
world - They're for development purposes only.)


| Oliver Mullarney     |  "I have knowledge of Digital Watches,  and soon I   |
| Oracle Corporation   |   shall have knowledge of Video Cassette Recorders"  |
| omullarn@oracle.com  |                                      Time Bandits    |
 --------------- "Universally acknowledged to work just fine" ----------------

oster@dewey.soe.berkeley.edu (David Phillip Oster) (11/12/89)

It is possible to patch the finder's Empty Trashcan without using a tail
patch by using a head patch on MDEF 0, or by installing a MenuHook. Both
are well documented.

jmunkki@kampi.hut.fi (Juri Munkki) (11/15/89)

In article <5148@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>In article <26596@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:
>> The best thing would of course be to change the way apple patches those
>> long routines, but since they have started doing something stupid, it is
>> very unlikely that they will ever stop.
>
>Momentum isn't the primary reason that we haven't changed the scheme; the 
>original rationale is.
>
>Larry Rosenstein has already explained that rationale in this forum quite 
>cogently; I suggest that you re-read some of the old messages in this 
>thread to find it.

Ok, so I re-read some of the old messages and found the article that
you seem refer to.

Larry Rosenstein wrote:
<Also, the whole idea of Apple's patches checking the return address is to
<determine where the *original* call came from.  The patch is intended to
<be activate only in one particular case, when it knows the state of the
<world and can fix the problem.
<
<Suppose there is a bug in the ROM.  The System S/W people find a trap call
<in the ROM that occurs before the bug manifests itself.  They install a
<patch that watches for this particular call and fixes up the state of the
<machine to correct the problem.  This might involve changing a register or
<changing some value on the stack.  (I've never tried fixing bugs in the
<ROM, so I'm guessing at the exact process.)
<
<The trap that's patches bears no relationship to the trap that contains
<the bug.  In fact, patches are likely to appear in frequently called
<routines (eg, Memory Manager routines, BlockMove, etc.), since they tend
<to be called in a lot of different places.
<
<The only way to avoid patches that look at the return address would be to
<replace entire pieces of the ROM.  This would make bug fixes take up more
<RAM space that they do now.

Paul Snively continues:
>In particular, I can think of some really evil compatibility problems that 
>your suggested fix could provoke; that's one reason that we aren't likely 
>to use it in the future.

Please tell us what the problems are so that we can work them out. I find
it very interesting that you find that you can just say "it can't be done"
without explaining yourself. Just because you work at Apple doesn't mean
that you are right just because you say so. Just because I say I'm right
doesn't mean I'm right, but you have to prove me wrong first!

The discussion on tail patching and come-from patching has always been
theoretical. I've never really believed that Apple would ever fix anything
that they have decided to break... So, let's say that everything I write
is just theoretical. That way no one will get offended, right?

If you want to get totally rid of come-from patching, you might consider
the following possibilities.

1) Suggestion:	Throw away the ROM. Just keep everything you patch in RAM.
   Pros:	RAM is cheap and you are already using a lot of it...
		Since there are no patches, you OS will run somewhat faster.
   Cons:	A lot of people will disagree and say that they can't afford it.
		(They'll say they don't have the disk or RAM space)

2) Suggestion:	Write a new set of ROMs so that long traps are split into
		smaller subroutines.
   Pros:	You no longer have to use come-from patching and your patches
		only have to replace short subroutines.
   Cons:	You will have to maintain a separate set of patches for every
		ROM version, but that's what you are already doing...sort of.
		(Take a look at FixMul on a Mac II: the come-from patch points
		to GetFontInfo, but GetFontInfo doesn't even contain a FixMul!)

3)  Suggestion:	Use the MMU to remap certain parts of the ROM to RAM.
    Pros:	You can effectively rewrite ROM!
    Cons:	Only 68020 or 68030 users can do this, which means that you
		can't do this and we shouldn't consider this even theoretically.

4)  Suggestion:	Rewrite the OS so that it doesn't contain bugs...
    Pros:	Great!
    Cons:	Ok, who wants to do it? (Who CAN do it?)

5)  Suggestion:	<<Insert ideas here>>

I'd really like comments on my previous article. The contents of that article
is slightly less theoretical than the above ideas. In that article I presented
a way that in my opinion would allow tail-patches and come-from patches to
co-exist.

_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^

chewy@apple.com (Paul Snively) (11/16/89)

In article <26693@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:
> Paul Snively continues:
> >In particular, I can think of some really evil compatibility problems 
that 
> >your suggested fix could provoke; that's one reason that we aren't 
likely 
> >to use it in the future.
> 
> Please tell us what the problems are so that we can work them out.

The most obvious that come to my mind are: some software, such as 
debuggers, look directly at the trap dispatching tables because they have 
to.  Other software does either for (silly) performance reasons, or to 
avoid being lied to by _GetTrapAddress.  The problem here is that if 
_GetTrapAddress lies to you (as it DOES under certain conditions with 
certain vendors' hardware/software) then you have no other recourse.

And there's no way to "work them out" without completely throwing out the 
current trap<->address schtick and starting over.  Fat chance.

In article <26693@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:
> I find it very interesting that you find that you can just say "it can't 
be done"
> without explaining yourself. Just because you work at Apple doesn't mean
> that you are right just because you say so. Just because I say I'm right
> doesn't mean I'm right, but you have to prove me wrong first!

Spare me, please.  I had only hoped to save some time/bandwidth by not 
rehashing something that Macintosh Developer Technical Support (and 
others) have said time and time again: don't tail patch; you'll break 
things in ways that are far too subtle and bizarre to fully explain.  The 
fact that I work at Apple may not confer 100% accuracy, but it IS my job 
to say things like "don't do that because it won't work," and it IS in 
your best interests to listen to me and the others who are in this 
(unfortunate) position, because far more often than not, we know what we 
are talking about.

Incidentally, when you say something is true, I am certainly under no 
obligation to prove you wrong; the burden of proof lies on the person 
making the statement, if indeed anything is to be proven (as opposed to 
being accepted as a statement of personal opinion).

In article <26693@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:
> The discussion on tail patching and come-from patching has always been
> theoretical. I've never really believed that Apple would ever fix 
anything
> that they have decided to break... So, let's say that everything I write
> is just theoretical. That way no one will get offended, right?

Perhaps no one will become offended, but will the writing then have any 
semantic value whatsoever?  I fully expect to offend some people, but if 
the other side-effect is to have more robust Macintosh software that 
follows more of the rules, then that's a price I'll pay in spades.

And I'd be interested in any examples of "something that we have decided to break," let alone something that we have decided to break and then not fix.

The discussion about tail-patching and come-from code is most certainly 
NOT theoretical; many people tail-patching have said that they are doing 
this, and many of us here at Apple have said that we're not saying "this 
is a bad idea in theory."  It is the WRONG thing to do and it DOES break 
software, period, no ifs, ands, or buts, read my lips, for the last time: 
TAIL-PATCHING BREAKS MACINTOSH SOFTWARE, SO DON'T DO IT.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

russotto@eng.umd.edu (Matthew T. Russotto) (11/16/89)

In article <5212@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>
>And I'd be interested in any examples of "something that we have decided to
> break," let alone something that we have decided to break and then not fix.
Resource Header Application Bytes.  Resource References.  The 'abort event'.
'Launch'  (well, you haven't broken it yet, but you keep promising to do so).
'Chain'.  JMP 10(ROMBASE) to restart....
(and, of course, tail patching-- it did used to work)
>
>__________________________________________________________________________
>Just because I work for Apple Computer, Inc. doesn't mean that they 
>believe what I believe or vice-versa.
>__________________________________________________________________________
>C++ -- The language in which only friends can access your private members.
>__________________________________________________________________________


--
Matthew T. Russotto	russotto@eng.umd.edu	russotto@wam.umd.edu
rrn: newsgroup "junk" full --- rerouting to news.groups

francis@mirror.UUCP (Joe Francis) (11/17/89)

In article <5212@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>Spare me, please.  I had only hoped to save some time/bandwidth by not 
>rehashing something that Macintosh Developer Technical Support (and 
>others) have said time and time again: don't tail patch; you'll break 
>things in ways that are far too subtle and bizarre to fully explain.  The 
>fact that I work at Apple may not confer 100% accuracy, but it IS my job 

<LARGE quantities of weird stuff about "burden of proof" deleted>

In the incredible ammount of space you used, you could have hinted at
some of these subtleties and truly done this newsgroup a service.  It
has been my experience that knowledge makes us all better programmers,
even if it is "forbidden" knowledge.

Go ahead Eve, feed us the APPLE.

chewy@apple.com (Paul Snively) (11/18/89)

In article <32982@mirror.UUCP> francis@mirror.UUCP (Joe Francis) writes:
> In the incredible ammount of space you used, you could have hinted at
> some of these subtleties and truly done this newsgroup a service.

You quoted one of my paragraphs, but in a preceding paragraph, the "hints 
at some of the subtleties" that you request were given.  Please go back 
and reread what I wrote.

I have no problems with explaining why not to do certain things; that's 
(unfortunately) a large part of my job.  I DO have problems with 
explaining why not to do certain things and having people ignore me or 
argue with me about it.  It'd also be one thing if it were just me, a lone 
voice crying in the wilderness (:-)), but it's not: it's everyone here in 
DTS as well as in other departments here at Apple.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

chewy@apple.com (Paul Snively) (11/18/89)

In article <1989Nov16.043300.8959@eng.umd.edu> russotto@eng.umd.edu 
(Matthew T. Russotto) writes:
> In article <5212@internal.Apple.COM> chewy@apple.com (Paul Snively) 
writes:
> >
> >And I'd be interested in any examples of "something that we have 
decided to
> > break," let alone something that we have decided to break and then not 
fix.
> Resource Header Application Bytes.  Resource References.  The 'abort 
event'.
> 'Launch'  (well, you haven't broken it yet, but you keep promising to do 
so).
> 'Chain'.  JMP 10(ROMBASE) to restart....
> (and, of course, tail patching-- it did used to work)

* Resource Header Application Bytes
   What on earth are those?

* Resource References
   Macintosh Developers were asked whether this would affect them adversely;
   to the best of my knowledge, no one ever used them, so they were disposed
   of (actually, the trap numbers were assigned to new routines).  How many 
   Macintosh applications broke as a result?

* The "Abort Event."
   Again, what on earth is this?  It's nowhere in Inside Macintosh or the Tech 
   Notes.

* Launch and Chain
   The semantics of Launch will indeed change, but for the better (right now 
   there's no prima facie way to know whether the _Launch trap will return or 
   not; it depends upon whether you're running under MultiFinder or not).  In 
   this case, I'd say we broke it when we released MultiFinder, and now we're 
   fixing it.

* JMP 10(ROMBASE) to restart
   That was never supported; it just happened to work.  Now, of course, we 
   have a Shutdown Manager that actually does the right things.

* Tail Patching (it used to work)
   Wrong.  There was NEVER a time in Macintosh history when tail patching did 
   not break the software.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

lsr@Apple.COM (Larry Rosenstein) (11/18/89)

In article <1989Nov16.043300.8959@eng.umd.edu> russotto@eng.umd.edu (Matthew T. Russotto) writes:
> The 'abort event'.

Abort events were never broken by DTS.  They were mentioned in the phonebook
edition of Inside Mac, but never made it into the released system.

-- 
		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 77-A  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr

tim@hoptoad.uucp (Tim Maroney) (11/18/89)

I think a key point is being missed in the tail patching discussion.
The amount of extra RAM that would be required for Apple to do its ROM
patches without breaking tail patches is not all that large; perhaps
64K above the amount of patches in place now.  We're about to enter a
year when 2M will be the standard amount of RAM on a Mac, and 64K is
sustainable with that much RAM.  This would be a boon to both
developers and users, as it would make a new class of reliable products
available.

It would also be nice if Apple would make new ROMs widely available.
That would be a complete solution to the problem.  ROMs are easier
to change than SIMMs, after all.

And by the way -- I wrote a silly INIT called Backdrop some three years
ago, before I knew about tail patching being a bad idea.  In all that
time, I have yet to see any problem with the software that results from
its tail patching of the Fill routines.  So remember -- tail patching
is a risk, but depending on what you're doing, it may be an acceptable
risk.

(And no, don't ask me for a new version of Backdrop.  I don't use it,
and I don't work on it, and I consider it obsoleted by MultiFinder.)
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"A book is the product of a contract with the Devil that inverts the Faustian
 contract, he'd told Allie.  Dr Faustus sacrificed eternity in return for two
 dozen years of power; the writer agrees to the ruination of his life, and
 gains (but only if he's lucky) maybe not eternity, but posterity, at least.
 Either way (this was Jumpy's point) it's the Devil who wins."
	-- Salman Rushdie, THE SATANIC VERSES

lsr@Apple.COM (Larry Rosenstein) (11/18/89)

In article <26693@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:

> 2) Suggestion:  Write a new set of ROMs so that long traps are split into
>                 smaller subroutines.

The problem is that you need a way to patch these routines.  Trap numbers 
are in short supply, so the alternative is a RAM vector. This takes up 
more RAM and slows things down.

>                 (Take a look at FixMul on a Mac II: the come-from patch 
points
>                 to GetFontInfo, but GetFontInfo doesn't even contain a 
FixMul!)

It sure does!  The come-from patch for FixMul checks return address 
$819B3A which is in fact right after a call to FixMul from GetFontInfo.  
On 68020/030 machines, the ROM sometimes doesn't make A-line traps.  It 
dispatches directly through the trap table.

Inevitably, there are going to be ROM bugs.  The most efficient way to fix 
some of these bugs is via come-from patches.

> I'd really like comments on my previous article. 

OK.  First, let me restate your idea (in a slightly different form) to 
make sure I understand it.

Suppose trap X needs a come-from patch to fix a bug.  You propose that 
when you make a call to X, the trap dispatcher branch directly to the 
come-from patch.  The patch can do its thing, and then branch to the 
address defined in the trap table.  This allows the come-from trap to get 
control first, when there's no possibility of the stack being messed up.

One problem with this idea is that some come-from patches are not this 
simple.  For example, look at the patch to GetHandleSize on the Mac 
II/IIx.  If the return addresses matches the value it looks for (some 
place in the Print Manager, it looks like), it doesn't call the ROM 
implementation of GetHandleSize at all.  

Essentially, your proposal would require that all come-from patches be 
head patches, so that they would have to end by branching to the address 
in the trap table.  Based on my limited knowledge of how ROM bugs are 
fixed, this is not a reasonable restriction.

Your proposal also means that the address you get from GetTrapAddress 
might not be the same as the target address when you call the trap.  Any 
code that tries to bypass the trap dispatcher by calling GetTrapAddress 
and JSR'ing to the result would bypass the come-from patches.  This seems 
like the kind of change that is likely to break applications.

What we are talking about here is a conflict between Apple producing the 
"best" implementation of the system software vs. programmers who might 
like to do tail patches.  Given that a lot of Mac users suffer from too 
many patches already, I think it is unwise to make the tradeoff in favor 
of easier tail patching.

All patching is risky, because there are many unclean applications out 
there.  (I've run across several -- presumably written in C -- that pass 
an address to MenuSelect rather than the point.)  

As people have mentioned many times, you can patch all the traps you want 
on your own machine.  But when you intend to distribute an INIT to others, 
then you have an obligation to produce something that is reliable.  Tail 
patches are simply not reliable given the way Apple fixes ROM bugs.


Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

lsr@Apple.COM (Larry Rosenstein) (11/18/89)

In article <9010@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:

> The amount of extra RAM that would be required for Apple to do its ROM
> patches without breaking tail patches is not all that large; perhaps
> 64K above the amount of patches in place now.  We're about to enter a
> year when 2M will be the standard amount of RAM on a Mac, and 64K is

64K sounds like a reasonable guess, given that the typical ROM has 256K 
total.  It is not clear to me that an extra 64K of RAM patches and disk 
space is acceptable.  People are already concerned that System 7 will 
require 2Mb.

Also, there probably will be users who do not choose to use System 7 
because it requires 2Mb.  Those users will continue to have come-from 
patches, which mean tail patches won't be guaranteed to work on those 
machines.  

I think the key point is not how much memory is required, but whether 
allowing tail patches is reall a boon to the Macintosh user.  

> It would also be nice if Apple would make new ROMs widely available.
> That would be a complete solution to the problem.  ROMs are easier
> to change than SIMMs, after all.

In practice, it is expensive for Apple to offer a ROM upgrade.  Plus, it 
only changes the problem; there are always going to be ROM bugs, and RAM 
patches for those bugs.  Plus it just gives developer several more 
hardware configurations to worry about.

> time, I have yet to see any problem with the software that results from
> its tail patching of the Fill routines.  So remember -- tail patching
> is a risk, but depending on what you're doing, it may be an acceptable
> risk.

Correct.


Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

ts@cup.portal.com (Tim W Smith) (11/18/89)

Suppose you have a NuBus SCSI card, and wish it to work with the
SCSI Manager.  How would you do this without tail patching
_SCSIDispatch?  ( I am assuming that a patch that never calls the
original trap can be considered an extreme case of tail patching,
for the sake of terminology ).

What is a developer to do in a case like this?

						Tim Smith

amanda@mermaid.intercon.com (Amanda Walker) (11/19/89)

In article <9010@hoptoad.uucp>, tim@hoptoad.uucp (Tim Maroney) writes:
> It would also be nice if Apple would make new ROMs widely available.
> That would be a complete solution to the problem.  ROMs are easier
> to change than SIMMs, after all.

I only sort of agree.  For example, I'd rather not get a new set of ROMs
with every system release, and I'd especially rather not pay for a set
each time.  Some things, like the IIci ROMs, or other major upgrades, sure.
But not for things like minor patches to the Sound Manager or TextEdit.
This would also make it much harder to walk into your local Apple dealership
and update your version of the System...

On the other hand, I've always thought that using EEPROMs instead of ROMs
would be a nifty idea, as long as there was a physical switch of some sort
to allow writing to them.

Amanda Walker <amanda@intercon.com>
--

erics@eleazar.dartmouth.edu (Eric Schlegel) (11/19/89)

In article <5249@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>In article <1989Nov16.043300.8959@eng.umd.edu> russotto@eng.umd.edu 
>(Matthew T. Russotto) writes:
>> In article <5212@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>> >
>> >And I'd be interested in any examples of "something that we have 
>> >decided to break," let alone something that we have decided to break 
>> >and then not fix.
>> Resource Header Application Bytes.  Resource References.  The 'abort event'.
>> 'Launch'  (well, you haven't broken it yet, but you keep promising to do 
>> so). 'Chain'.  JMP 10(ROMBASE) to restart....
>> (and, of course, tail patching-- it did used to work)
>
>* Resource Header Application Bytes
>   What on earth are those?
>
>* JMP 10(ROMBASE) to restart
>   That was never supported; it just happened to work.  Now, of course, we 
>   have a Shutdown Manager that actually does the right things.



Resource Header Application Bytes were 128 bytes of data at the beginning
of a resource file that supposedly were available for application use.
This is documented on pp. 128-9 of IM, volume 1. Tech Note 62, from Jan. 1986,
states that applications should no longer use these bytes as they're 
reserved for future use by the Resource Manager.

On pp. 385-6 of IM, volume 2, is documented the Restart procedure. It's 
marked Not in ROM; assembly-language programmers are advised that "you can
give the following instructions to restart the system:"
     MOVE   ROMBase,A0
     JMP    $0A(A0)

Sorry, Paul. The examples are few, far between, and obscure, but they
do exist.

eric
eric.schlegel@dartmouth.edu

jmunkki@kampi.hut.fi (Juri Munkki) (11/19/89)

(comments on my scheme to make comefroms and tailpatches co-exist:)
In article <5250@internal.Apple.COM> lsr@Apple.COM (Larry Rosenstein) writes:
>Suppose trap X needs a come-from patch to fix a bug.  You propose that 
>when you make a call to X, the trap dispatcher branch directly to the 
>come-from patch.  The patch can do its thing, and then branch to the 
>address defined in the trap table.  This allows the come-from trap to get 
>control first, when there's no possibility of the stack being messed up.

Right. The trap dispatcher is not changed. The only new things are
a patched SetTrapAddress/GetTrapAddress (and the N-versions of those)
and a new secondary dispatch table.

>One problem with this idea is that some come-from patches are not this 
>simple.  For example, look at the patch to GetHandleSize on the Mac 
>II/IIx.  If the return addresses matches the value it looks for (some 
>place in the Print Manager, it looks like), it doesn't call the ROM 
>implementation of GetHandleSize at all.  

So what, if it doesn't call GetHandleSize at all? The correct version
of the calling code shouldn't call GetHandleSize either so the trap
wouldn't be called anyway.

>Essentially, your proposal would require that all come-from patches be 
>head patches, so that they would have to end by branching to the address 
>in the trap table.  Based on my limited knowledge of how ROM bugs are 
>fixed, this is not a reasonable restriction.

Why would they have to be head patches? All you need to do is to stash
the address somewhere and then do whatever you want. As I explained above,
the come-from code is still allowed to do anything it needs to do.

>Your proposal also means that the address you get from GetTrapAddress 
>might not be the same as the target address when you call the trap.  Any 
>code that tries to bypass the trap dispatcher by calling GetTrapAddress 
>and JSR'ing to the result would bypass the come-from patches.  This seems 
>like the kind of change that is likely to break applications.

Any code that bypasses the trap dispatcher isn't patched with a
come-from patch.  Come-from patches have zero effect on applications
trap calls.

Come-from patches patch _only_ ROM routines. If ROM routines rely on
GetTrapAddress to get addresses for routines, you might have to
come-from patch GetTrapAddress to return these routines something
totally different from the trap dispatch table.

>What we are talking about here is a conflict between Apple producing the 
>"best" implementation of the system software vs. programmers who might 
>like to do tail patches.  Given that a lot of Mac users suffer from too 
>many patches already, I think it is unwise to make the tradeoff in favor 
>of easier tail patching.
>
>All patching is risky, because there are many unclean applications out 
>there.  (I've run across several -- presumably written in C -- that pass 
>an address to MenuSelect rather than the point.)  

Right. So you think that you are making the situation better by creating
yet another pitfall for inexperienced programmers? Do you think that just
saying that tail patching is wrong will stop programmers from writing
inits that change system behavior?

>As people have mentioned many times, you can patch all the traps you want 
>on your own machine.  But when you intend to distribute an INIT to others, 
>then you have an obligation to produce something that is reliable.  Tail 
>patches are simply not reliable given the way Apple fixes ROM bugs.

We all know this, but unfortunately a lot of software is written by people
who are reading IM while they are writing the application/init/whatever.
I'm just offering you a way to remove an unnecessary pitfall.

An another benefit from this discussion is that at least usenet readers
will know how to write a good patch and maybe even understand a part of
what they are doing.

Ages ago, I posted sample init source code and I'm still getting
requests to help people write whatever they want to do.  Most of these
people have absolutely no idea why my init works and theirs doesn't.
Still they insist on writing their own inits.

P.S.
     Does anyone need/want an init that renames a file in the system folder
     if a certain key is held down while shutdown? I use it to temporarily
     disable 32-bit quickdraw, but you might use it to temporarily enable
     or disable MacsBug...It doesn't make patches.

PS/2									      :)
     Let me remind you that everyone knows that Apple will never fix
     something that was broken from day 1, so we all know that this
     discussion is purely theoretical.

_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^

pete@cavevax.ucsb.edu (GurgleKat) (11/19/89)

I've been watching this thread live on and on for weeks now, or at least
it seems like weeks. And I haven't actually read it, but now that it's lived
for so long, I'm wondering if there wasn't something interesting in it.
(The first article was basically "What's a tail patch," right? That I know.)
Out nntp feed apparently expires articles rather quickly. So if anyone would
care to summarize the thread, in mail or here if it seems warranted, I'd be
much obliged.
--
Pete Gontier   : pete@cavevax.ucsb.edu; outgoing .UUCP cause me grief
Editor, Macker : Online Macintosh Programming Journal; mail for subscription
Hire this kid  : Mac, DOS, C, Pascal, asm, excellent communication skills

"This was it. This was what he was, who he was, his being. He forgot to eat.
 Sometimes he'd resent having to leave the deck to use the toilet..."
                                              -- William Gibson, _Neuromancer_

earleh@eleazar.dartmouth.edu (Earle R. Horton) (11/19/89)

In article <5212@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>
>And I'd be interested in any examples of "something that we have 
>decided to break," let alone something that we have decided to break 
>and then not fix.

"Assembly-language note:  Changing the value of the block's master
pointer lock bit with a BSET instruction is faster than HLock.
However, HLock may eventually perform additional tasks."

immed		EQU $200	 ; execute immediately, bypass I/O queue

;The following twelve OS traps have been redundantly defined as
;Tool traps as well. They should be
;accessed as OS traps, but their slots in the Tool trap table
;will be reserved forever.
;	$1A GetZone
;	...

"Assembly-language note:  To get a pointer to the end of RAM from
assembly language, use the global variable MemTop."
     
Network Events.

Calling PopupMenuSelect under System 6.0 with Color QuickDraw caused
the menuWidth and menuHeight both to be set to -1!  I was told that
this was done deliberately to allow for the possibility of a loaded
menu being used on different monitors.  Result: CalcMenuSize is broken
under System 6.0 because its effect is not what IM says it is.

Tags.

Mac Plus keyboard shifted arrow keys return identical codes to numeric
keypad keys.  This hardware was shipped in a broken state, and no fix
was ever supplied.  Weak-ass excuse supplied by Apple was that this
was done for compatibility with original separate numeric keypad.


  "We broke it because it was a bad idea in the first place, anyway."

  "Fine, but remember, it was YOUR idea."


Earle R. Horton

bob@accuvax.nwu.edu (Bob Hablutzel) (11/19/89)

In article <26788@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:
>(comments on my scheme to make comefroms and tailpatches co-exist:)
>In article <5250@internal.Apple.COM> lsr@Apple.COM (Larry Rosenstein) writes:
>>Suppose trap X needs a come-from patch to fix a bug.  You propose that 
>>when you make a call to X, the trap dispatcher branch directly to the 
>>come-from patch.  The patch can do its thing, and then branch to the 
>>address defined in the trap table.  This allows the come-from trap to get 
>>control first, when there's no possibility of the stack being messed up.
>
>Right. The trap dispatcher is not changed. The only new things are
>a patched SetTrapAddress/GetTrapAddress (and the N-versions of those)
>and a new secondary dispatch table.
>

An INIT I wrote, FreshStart, does do come-from patches, and impliments exactly
this notion. Any patch to the 8 or so traps that I'm worried about don't
actually change the trap dispatch table, but rather the internal variable I
keep for the "original" trap address. (It's initialized when I put in my patch
in the first place). It seems to work OK for INITs (FreshStart is an INIT
manager, and so it running the INITs. I know if a patch is for an INIT or not).
I still have problems with applications that tail-patch. MPW, for example.

Notice, though, that my code has to have some notion of my patches; this is
not a general purpose fix, and I'd be happier if I didn't have to do it. (It
added two patches I had to make JUST FOR COMPATABILITY!) I agree with Apple
(and I agreed with Apple _BEFORE_ I took a job there): tail patching is a
pain in the ass.

Bob Hablutzel	(Wildwood Software, RIP)	BOB@NUACC.ACNS.NWU.EDU
Disclaimer:	As of tomorrow, I work for Apple. I speak for myself.
If you care:	I'll still work on FreshStart.

tim@hoptoad.uucp (Tim Maroney) (11/20/89)

In article <5248@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>I have no problems with explaining why not to do certain things; that's 
>(unfortunately) a large part of my job.  I DO have problems with 
>explaining why not to do certain things and having people ignore me or 
>argue with me about it.

Yeah, can you believe the gall of some of these people?  I mean, actually
daring to disagree with you!  Who do they think they are?
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Mere opinion without supporting argument is no more than the American
 Bandstand school of literary evaluation."  -- Tom Maddox

chewy@apple.com (Paul Snively) (11/21/89)

In article <17090@dartvax.Dartmouth.EDU> erics@eleazar.dartmouth.edu (Eric 
Schlegel) writes:
> Resource Header Application Bytes were 128 bytes of data at the beginning
> of a resource file that supposedly were available for application use.
> This is documented on pp. 128-9 of IM, volume 1. Tech Note 62, from Jan. 
1986,
> states that applications should no longer use these bytes as they're 
> reserved for future use by the Resource Manager.

Great, but did this actually break anything?

In article <17090@dartvax.Dartmouth.EDU> erics@eleazar.dartmouth.edu (Eric 
Schlegel) writes:
> On pp. 385-6 of IM, volume 2, is documented the Restart procedure. It's 
> marked Not in ROM; assembly-language programmers are advised that "you 
can
> give the following instructions to restart the system:"
>      MOVE   ROMBase,A0
>      JMP    $0A(A0)

This raises an interesting point: Inside Macintosh actually does 
programmers a disservice by saying things like "assembly-language 
programmers can..." and then giving code that relies on specific ROM 
addresses (or even specific ROM offsets, like above).  The CORRECT way to 
get that same effect, given that there's a routine called RESTART that is 
marked NOT IN ROM is to Link in the appropriate library (usually Runtime.o 
for MPW users) from your development system, and make the call to the 
library routine.  That's what libraries are for.

In article <17090@dartvax.Dartmouth.EDU> erics@eleazar.dartmouth.edu (Eric 
Schlegel) writes:
> Sorry, Paul. The examples are few, far between, and obscure, but they
> do exist.

Indeed they do, but a) how much stuff breaks as a result of our System 
Software and hardware architectures evolving, and b) is it the software 
that's broken, the documentation, the hardware, or is it all a matter of 
interpretation?

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

chewy@apple.com (Paul Snively) (11/21/89)

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
> "Assembly-language note:  Changing the value of the block's master
> pointer lock bit with a BSET instruction is faster than HLock.
> However, HLock may eventually perform additional tasks."

The last sentence says it all.  We've ALWAYS recommended AGAINST direct 
manipulation of data structures.

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
> immed           EQU $200         ; execute immediately, bypass I/O queue

It's redundant; all I/O calls execute synchronously unless they are 
specified async.

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
> ;The following twelve OS traps have been redundantly defined as
> ;Tool traps as well. They should be
> ;accessed as OS traps, but their slots in the Tool trap table
> ;will be reserved forever.
> ;       $1A GetZone
> ;       ...

What broke here?

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
> "Assembly-language note:  To get a pointer to the end of RAM from
> assembly language, use the global variable MemTop."

For virtually all purposes, this is still true, although it really 
shouldn't be necessary to ask where the end of physical RAM is in the 
first place, and there'd better be a better way than a low-RAM global to 
get what you want (for example, we now are facing virtual memory, etc.  We 
are providing ways to get various kinds of memory information in a cleaner 
way).

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
> Network Events.

Ah, a good one.  There WAS a fair amount of code that died due to this.  I 
think this one falls into the category in your last two sentences: it was 
a bad idea in the first place, but it was OUR idea.

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
> Calling PopupMenuSelect under System 6.0 with Color QuickDraw caused
> the menuWidth and menuHeight both to be set to -1!  I was told that
> this was done deliberately to allow for the possibility of a loaded
> menu being used on different monitors.  Result: CalcMenuSize is broken
> under System 6.0 because its effect is not what IM says it is.

This sounds pretty brain-dead to me too; I'm completely unaware of this.  
I'll ask other DTSers about the whys and wherefores.

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
> Tags.

This may have affected some disk utility types, but it actually made life 
easier for hard disk folks, since we no longer had such screwy sector 
sizes.

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
> Mac Plus keyboard shifted arrow keys return identical codes to numeric
> keypad keys.  This hardware was shipped in a broken state, and no fix
> was ever supplied.  Weak-ass excuse supplied by Apple was that this
> was done for compatibility with original separate numeric keypad.

Just because YOU THINK it's a weak-ass excuse doesn't mean that it IS one; 
being incompatible with our (very popular) separate numeric keypad would 
have been unacceptable to our users and our developers.

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu 
(Earle R. Horton) writes:
>   "We broke it because it was a bad idea in the first place, anyway."
> 
>   "Fine, but remember, it was YOUR idea."

This is probably the most common case, and in many of THOSE cases, I'd say 
it's the documentation that is broken and not the software or hardware.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

chewy@apple.com (Paul Snively) (11/21/89)

In article <26788@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:
>      Let me remind you that everyone knows that Apple will never fix
>      something that was broken from day 1, so we all know that this
>      discussion is purely theoretical.

Let me remind you that this is complete and utter nonsense, otherwise 
Apple would never release new ROMs or new version of the System.  A 
correct interpretation of the above statement would read: "Let me remind 
you that Apple hasn't done what I insisted that they do, so we all know 
that Apple doesn't jump every time someone says 'jump.'"

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

chewy@apple.com (Paul Snively) (11/21/89)

In article <9012@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> In article <5248@internal.Apple.COM> chewy@apple.com (Paul Snively) 
writes:
> >I have no problems with explaining why not to do certain things; that's 
> >(unfortunately) a large part of my job.  I DO have problems with 
> >explaining why not to do certain things and having people ignore me or 
> >argue with me about it.
> 
> Yeah, can you believe the gall of some of these people?  I mean, actually
> daring to disagree with you!  Who do they think they are?

Let me try to be clearer: what I have a problem with is having explained, 
in some detail, with support from others here at Apple, why doing 
something is not merely a bad idea, but just plain wrong, and having 
people who aren't as experienced or as well-informed about how the 
Macintosh works tell me that it's NOT wrong.

The function of my department is to help people create good, reliable 
Macintosh software.  That function is subverted every time someone does 
something that we tell them not to do, or when they don't do what we DO 
tell them to do.

Perhaps I'm like an army drill sargeant or something: I'm harsh, I'm 
stern, I'm a pain in the ass, but it's all to benefit the person being 
disciplined.  When Macintosh software follows the rules, Apple benefits, 
the developer benefits, and most importantly, the user benefits.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

russotto@eng.umd.edu (Matthew T. Russotto) (11/21/89)

In article <5292@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>In article <17090@dartvax.Dartmouth.EDU> erics@eleazar.dartmouth.edu (Eric 
>Schlegel) writes:
>> On pp. 385-6 of IM, volume 2, is documented the Restart procedure. It's 
>> marked Not in ROM; assembly-language programmers are advised that "you 
>can
>> give the following instructions to restart the system:"
>>      MOVE   ROMBase,A0
>>      JMP    $0A(A0)
>
>This raises an interesting point: Inside Macintosh actually does 
>programmers a disservice by saying things like "assembly-language 
>programmers can..." and then giving code that relies on specific ROM 
>addresses (or even specific ROM offsets, like above).  The CORRECT way to 
>get that same effect, given that there's a routine called RESTART that is 
>marked NOT IN ROM is to Link in the appropriate library (usually Runtime.o 
>for MPW users) from your development system, and make the call to the 
>library routine.  That's what libraries are for.
So?  Your application still breaks.  Unless you have a dynamic linker,
of course... (was it REALLY that hard for apple to keep a JMP to the right
spot in 0A(RomBase)? )
>
>In article <17090@dartvax.Dartmouth.EDU> erics@eleazar.dartmouth.edu (Eric 
>Schlegel) writes:
>> Sorry, Paul. The examples are few, far between, and obscure, but they
>> do exist.
>
>Indeed they do, but a) how much stuff breaks as a result of our System 
>Software and hardware architectures evolving, and b) is it the software 
>that's broken, the documentation, the hardware, or is it all a matter of 
>interpretation?
It isn't the hardware, but whether it is the software or the documentation
depends on your answer to the following:
If a program does not conform to specifications, is it the fault of the
program or the specification.
>
>__________________________________________________________________________
>Just because I work for Apple Computer, Inc. doesn't mean that they 
>believe what I believe or vice-versa.
>__________________________________________________________________________
>C++ -- The language in which only friends can access your private members.
>__________________________________________________________________________


--
Matthew T. Russotto	russotto@eng.umd.edu	russotto@wam.umd.edu
][, ][+, ///, ///+, //e, //c, IIGS, //c+ --- Any questions?
You know you are in trouble when you need a kill file for 'junk'!

tim@hoptoad.uucp (Tim Maroney) (11/21/89)

In article <1467@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy Roussak)
writes:
>I was challenged to write a patch which would play a sound, preferably
>whenever the Finder emptied the wastebasket
>
>The obvious thing to do, (and we all do obvious things, don't we...)
>was to do a tail patch on MenuSelect, look for a return of 0x00050002,
>check that CurApName is the same as FinderName and to play the sound
>if it is.

This is probably one of those cases where a tail patch is an acceptable
risk.  MenuSelect is called in one context, when an application wants
to track the menu bar.  It's unlikely to be called from any other trap,
only directly from the application, and so is very unlikely to acquire
any come-from patches in the course of Apple bug fixes or extensions.
Furthermore, if it *does* cause problems, it doesn't do anything vital,
and the user can just throw it away.

In article <46c51bee.129dc@blue.engin.umich.edu> mystone@caen.engin.umich.edu
writes:
>  Install an event filter in jGNEFilter that looks for mouse ups.  When you
>get a mouse up, and CurApName is FinderName, look at MenuDisable.  If it's
>$00050002, then flush your toilet.  (How's that for twisted?)

Should work.  Of course, using jGNEFilter goes against some other, more
pressing compatibility guidelines, such as not writing to low-memory
globals, since they'll go away in the future.

>  Or, even better (depending on how you look at it) yet, patch _CopyBits.
>When the source and destionation rectangles are 32 by 32, do a bitwise compare
>with the stuffed trash can.  (Or whatever your new icon is that signifies 
>there's something in the trash.)  If it's changing to the full state, set a
>flag in your code.  Next time _CopyBits is called with source and destination
>rectangles of 32 by 32, and the bit map is the empty state of the trash
>can, play your sound here, then go on to the old _CopyBits.  My, how the mind
>goes at 5:15 in the morning...

Amusing, but remember how often the Finder draws icons.  This kind of thing
is not worth a performance hit of this magnitude.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"I have recently been examining all the known superstitions of the world,
 and do not find in our particular superstition (Christianity) one redeeming
 feature.  They are all alike founded on fables and mythology."
    -- Thomas Jefferson

chewy@apple.com (Paul Snively) (11/21/89)

In article <1989Nov20.182741.2658@eng.umd.edu> russotto@eng.umd.edu 
(Matthew T. Russotto) writes:
> In article <5292@internal.Apple.COM> chewy@apple.com (Paul Snively) 
writes:
> >In article <17090@dartvax.Dartmouth.EDU> erics@eleazar.dartmouth.edu 
(Eric 
> >Schlegel) writes:
> >> On pp. 385-6 of IM, volume 2, is documented the Restart procedure. 
It's 
> >> marked Not in ROM; assembly-language programmers are advised that 
"you 
> >can
> >> give the following instructions to restart the system:"
> >>      MOVE   ROMBase,A0
> >>      JMP    $0A(A0)
> >
> >This raises an interesting point: Inside Macintosh actually does 
> >programmers a disservice by saying things like "assembly-language 
> >programmers can..." and then giving code that relies on specific ROM 
> >addresses (or even specific ROM offsets, like above).  The CORRECT way 
to 
> >get that same effect, given that there's a routine called RESTART that 
is 
> >marked NOT IN ROM is to Link in the appropriate library (usually 
Runtime.o 
> >for MPW users) from your development system, and make the call to the 
> >library routine.  That's what libraries are for.
> So?  Your application still breaks.  Unless you have a dynamic linker,
> of course... (was it REALLY that hard for apple to keep a JMP to the 
right
> spot in 0A(RomBase)? )

Your application won't break as long as you link with up-to-date library 
code!  As for "was it hard to keep the jump," I'm not a ROM engineer, so I 
don't really know.  There were some pretty hairy changes in going from the 
old Macs to the II-family Macs.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

lsr@Apple.COM (Larry Rosenstein) (11/21/89)

In article <26788@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:

> Right. The trap dispatcher is not changed. The only new things are
> a patched SetTrapAddress/GetTrapAddress (and the N-versions of those)
> and a new secondary dispatch table.

And you need a table per ROM that you new Get/SetTrapAddress uses to know 
which traps have come-from patches.

> So what, if it doesn't call GetHandleSize at all? The correct version
> of the calling code shouldn't call GetHandleSize either so the trap
> wouldn't be called anyway.

Your suggestion was that a come-from patch do its thing, then look in a 
private table to find out where to branch to next.  (The private table is 
updated by SetTrapAddress.)

If the come-from patch doesn't call the original GetHandleSize in certain 
cases, then any patches to GetHandleSize installed with SetTrapAddress 
won't be called in those cases either.

> Why would they have to be head patches? All you need to do is to stash
> the address somewhere and then do whatever you want. As I explained 
above,
> the come-from code is still allowed to do anything it needs to do.

See above.  Some come-from patches branch back into a ROM at a different 
place than the original trap address (the address before the patch was 
installed).  

> Any code that bypasses the trap dispatcher isn't patched with a
> come-from patch.  Come-from patches have zero effect on applications
> trap calls.

There are ROM calls on 68020/030 machines that bypass the trap dispatcher. 
 (They branch indirectly through the trap table to the code.)  

> Right. So you think that you are making the situation better by creating
> yet another pitfall for inexperienced programmers? Do you think that just
> saying that tail patching is wrong will stop programmers from writing
> inits that change system behavior?

Writing reliable INITs is very difficult.  It is not something that an 
inexperienced programmer should do, and expect to have a reliable piece of 
code.

Any time you patch a trap or install a hook, you are making certain 
assumptions about how the system works. When those assumptions don't hold, 
then the INIT breaks.  In the case of a tail patch, you are assuming that 
the trap won't be come-from patched in the future.  Depending on the trap 
involved, that might be a safe assumption.  At least with a tail patch, 
the assumption is fairly well-known; this is not true of other patches.

Staying away from tail patches doesn't mean you can't customize the 
system.  That's a silly statement.  History has shown that programmers 
will patch any trap they want to get some hack done.  That's fine with me. 

Just look at the number of INIT managers, and problem reports having to do 
with INITs.  It shows that writing an INIT is a black art, and not 
something that should be taken lightly.


Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

russotto@eng.umd.edu (Matthew T. Russotto) (11/21/89)

In article <5320@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>Your application won't break as long as you link with up-to-date library 
>code!  As for "was it hard to keep the jump," I'm not a ROM engineer, so I 
>don't really know.  There were some pretty hairy changes in going from the 
>old Macs to the II-family Macs.
And just how (in 1984) was I supposed to link with up-to-date library code
released in 1987?
>
>__________________________________________________________________________
>Just because I work for Apple Computer, Inc. doesn't mean that they 
>believe what I believe or vice-versa.
>__________________________________________________________________________
>C++ -- The language in which only friends can access your private members.
>__________________________________________________________________________


--
Matthew T. Russotto	russotto@eng.umd.edu	russotto@wam.umd.edu
][, ][+, ///, ///+, //e, //c, IIGS, //c+ --- Any questions?
You know you are in trouble when you need a kill file for 'junk'!

ejd@iris.brown.edu (Ed Devinney) (11/21/89)

In article <1989Nov21.040138.344@eng.umd.edu> russotto@eng.umd.edu 
(Matthew T. Russotto) writes:
> In article <5320@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>>Your application won't break as long as you link with up-to-date library 
>>code! [...] 
> And just how (in 1984) was I supposed to link with up-to-date library code
> released in 1987?
   
You might try something called a "product update" or "new release".  
This is a very nice thing that programmers occasionally do as time goes 
by.  Fix a few bugs, change the about-box or something important like 
that, and maybe even relink with new libraries while you're at it.  You 
can even change the version number and charge more for your application.  
Welcome to the wonderful world of real-life software development
   Jeeeezzzuss, guys...when did Apple (aside from Steve Jobs maybe) claim that 
the Mac family would be upward-compatible forever?  And if they did, when
were you gullible enough to believe them?

ed

++++++
ed devinney...IRIS/Brown University, Providence, RI...ejd@iris.brown.edu
-- "...she treated me like a brother - a ubiquitous feature that I have 
discovered in 97% of the women who drive me crazy..." Satch Carlson--

d88-jwa@nada.kth.se (Jon Watte) (11/21/89)

[ Patch _CopyBits to look for the trash can icon ]

>Amusing, but remember how often the Finder draws icons.  This kind of thing
>is not worth a performance hit of this magnitude.

Is it really a performance loss ? Let's see:
Check CurApName. If it isn't the finder, it's obvious after One (1)
longword check, or AT MOST two. That is just a few instructions of the
anyway slow _CopyBits for non-finder applications.

Second, two subtractions and two checks to see if it's 32x32. This COULD
be skipped. (Fat chance any other bitmap's gonna look like our trash can
anyway)

If it's not our trash can bitmap, that's mostly obvious after the first
eight bytes or so, i.e. ~30 more instructions.

To me, it looks likeany program but the finder loses <10 instructions,
the finder loses a bit more ( <100 though, in the typical case.)

This should be compared to the unimagianbly slow 1->8 bit expansion :-)

>Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

Haven't I seen that name before ? Hmmm... 8)

		The sun always shines in my mac

								h+
-- 
This .signature is longer than 4 lines. If you'd like to see it in whole,
please send a note to me. I'm h+@nada.kth.se and also h+@proxxi.se    8')

russotto@eng.umd.edu (Matthew T. Russotto) (11/21/89)

In article <21353@brunix.UUCP> ejd@iris.brown.edu (Ed Devinney) writes:
>   Jeeeezzzuss, guys...when did Apple (aside from Steve Jobs maybe) claim that 
>the Mac family would be upward-compatible forever?  And if they did, when
>were you gullible enough to believe them?
That is the whole argument.  Apple claimed, and continues to claim, that
any program that follows their guidelines will work on all future platforms.
This simply isn't so.
>++++++
>ed devinney...IRIS/Brown University, Providence, RI...ejd@iris.brown.edu
>-- "...she treated me like a brother - a ubiquitous feature that I have 
>discovered in 97% of the women who drive me crazy..." Satch Carlson--
--
Matthew T. Russotto	russotto@eng.umd.edu	russotto@wam.umd.edu
][, ][+, ///, ///+, //e, //c, IIGS, //c+ --- Any questions?
You know you are in trouble when you need a kill file for 'junk'!

chewy@apple.com (Paul Snively) (11/22/89)

In article <1989Nov21.040138.344@eng.umd.edu> russotto@eng.umd.edu 
(Matthew T. Russotto) writes:
> In article <5320@internal.Apple.COM> chewy@apple.com (Paul Snively) 
writes:
> >Your application won't break as long as you link with up-to-date 
library 
> >code!  As for "was it hard to keep the jump," I'm not a ROM engineer, 
so I 
> >don't really know.  There were some pretty hairy changes in going from 
the 
> >old Macs to the II-family Macs.
> And just how (in 1984) was I supposed to link with up-to-date library 
code
> released in 1987?

You weren't, in 1984; you were supposed to rebuild your code every time a 
new development system was released, like everyone else who distributes 
what they write in any way.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

chewy@apple.com (Paul Snively) (11/22/89)

In article <1989Nov21.153508.1872@eng.umd.edu> russotto@eng.umd.edu 
(Matthew T. Russotto) writes:
> In article <21353@brunix.UUCP> ejd@iris.brown.edu (Ed Devinney) writes:
> >   Jeeeezzzuss, guys...when did Apple (aside from Steve Jobs maybe) 
claim that 
> >the Mac family would be upward-compatible forever?  And if they did, 
when
> >were you gullible enough to believe them?
> That is the whole argument.  Apple claimed, and continues to claim, that
> any program that follows their guidelines will work on all future 
platforms.
> This simply isn't so.

Actually, we never claimed that software written to our guidelines will 
work on all future platforms.  We did, and do, claim that you stand a 
significantly better chance if you do than if you don't.

Unfortunately, we didn't even provide a procedural interface to all of the 
low-RAM globals on the original Macintosh models, and we didn't get around 
to stuff like _HGetState and _HSetState until the 128K ROMs.

We are trying valiantly (and no, our name's not "Eddie") to move the 
Macintosh in a direction that won't force our developers to rely on things 
that are likely to change from one machine/System Software revision to the 
next, but that's simply not entirely possible.  Our systems are not going 
to go into statis anytime soon; they'll continue to evolve, and sometimes 
in ways that are mildly or even fundamentally incompatible with previous 
systems--but hopefully always in ways that are better (although even that 
isn't guaranteed by any means).

That's one of the reasons that stuff like tail patching isn't 
supported--we know today, here and now, that it breaks things.  Other 
things that are good or bad ideas we may either know today, or we may find 
out tomorrow--sometimes the hard way.  That's why we have things like Tech 
Notes, which are a combination of lots of things (Inside Mac fixes and/or 
clarifications, documentation for new system features, caveats about what 
to do and/or not do), and Sample Code (which hopefully shows the RIGHT way 
to do certain things).

So do please follow the guidelines, at least so that you don't break in 
six months, and if you break in two years, well, two years is a helluva 
long time in microcomputer terms.  And remember--the people we're really 
trying to protect here are the users, not Apple Computer, Inc. and not 
you, the developers.  That's a harsh reality, but it IS reality.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

tim@hoptoad.uucp (Tim Maroney) (11/22/89)

In article <5248@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>I have no problems with explaining why not to do certain things; that's 
>(unfortunately) a large part of my job.  I DO have problems with 
>explaining why not to do certain things and having people ignore me or 
>argue with me about it.
 
In article <9012@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> Yeah, can you believe the gall of some of these people?  I mean, actually
> daring to disagree with you!  Who do they think they are?

In article <5296@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>Let me try to be clearer: what I have a problem with is having explained, 
>in some detail, with support from others here at Apple, why doing 
>something is not merely a bad idea, but just plain wrong, and having 
>people who aren't as experienced or as well-informed about how the 
>Macintosh works tell me that it's NOT wrong.

But Paul, you are missing the point.  Every case I've seen here where
people argue with you is because you have *not* raised any compelling
argument.  It seems you want us all to put "DTS said it, that settles
it, and I believe it" bumper stickers on our cars.  I am referring only
to you; most other Apple employees here have much better network
manners.  You, however, specialize in responses which are inane and
peremptory; for example, your messages on tail patches that nowhere
included a technical explanation of the problem with them, or your
message on file ids that completely ignored every point I raised (as
some other posters noted at the time).

Another good example would be the current discussion of things that
Apple has broken.  At first, your position was one of shocked outrage
that anyone would suggest such a thing had ever happened.  Now that
people have provided a number of irrefutable examples, you have not
apologized for earlier questioning their competence or veracity;
instead, we are supposed to believe that your position all along has
been what you just changed it to, that Apple does break things
sometimes but it has good reasons to do so.  And then you've tossed in
some more inane arguments just to confirm that no one should treat you
seriously, such as saying that developers should not pay attention to
explicit instructions in Inside Macintosh.

You seem to have forgotten that a job in Developer Relations is a job
in Public Relations; it is not the pulpit of Jonathan Edwards.  As a
result, you are breeding ill-will towards Apple, and people are coming
to ignore your conclusions even in the very rare cases where you
sincerely try to prove them correct.

>The function of my department is to help people create good, reliable
>Macintosh software.

And to maintain good relations with the developer comunity, which by
nature involves taking seriously objections raised by those
developers.  Instead, you contemptuously dismiss the complaints without
dealing honestly with their substance, and you dismiss the complainers
themselves as "people who aren't as experienced or as well-informed
about how the Macintosh works".  This is highly obnoxious behavior.

>Perhaps I'm like an army drill sargeant or something: I'm harsh, I'm
>stern, I'm a pain in the ass, but it's all to benefit the person being
>disciplined.

Gee, Daddy, thanks a lot.

>When Macintosh software follows the rules, Apple benefits,
>the developer benefits, and most importantly, the user benefits.

And when "the rules" are handed down as infallible and inarguable fiats
from on high, Apple's image suffers, the developers ignore the rules,
and the user suffers.  If you imagine that your behavior here is in
any way likely to increase the probability of anyone following the
rules, you are deluding yourself.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"In science it often happens that scientists say, 'You know that's a
 really good argument; my position is mistaken,' and then they actually
 change their minds and you never hear that old view from them again.
 They really do it.  It doesn't happen as often as it should, because
 scientists are human and change is sometimes painful.  But it happens
 every day.  I cannot recall the last time something like that happened
 in politics or religion." -- Carl Sagan, 1987 CSICOP keynote address

chewy@apple.com (Paul Snively) (11/22/89)

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> You, however, specialize in responses which are inane and
> peremptory; for example, your messages on tail patches that nowhere
> included a technical explanation of the problem with them,

The technical problem with them--that various system patches use come-from 
code to make sure that they work at the right time--has been spelled out 
on several occassions both by Larry Rosenstein and myself, among others.  
My "inane and peremptory" [sic] responses came when people didn't seem to see 
the reasons, or perhaps rather to care that they exist.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> or your
> message on file ids that completely ignored every point I raised (as
> some other posters noted at the time).

I addressed all of your points, as did other people here (Andrew Shebanow 
comes immediately to mind).  I'd be more than happy to continue the 
discussion, although I believe it will be much easier when System 7 final 
ships, since at that point the details of the Alias Manager, et al. will 
be much clearler.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> Another good example would be the current discussion of things that
> Apple has broken.  At first, your position was one of shocked outrage
> that anyone would suggest such a thing had ever happened.  Now that
> people have provided a number of irrefutable examples, you have not
> apologized for earlier questioning their competence or veracity;

I never questioned anyone's competence or veracity; I do often question 
whether some of the changes that we've made constitute breakage, and in 
some cases where they do, whether it's the hardware or software that's 
broken or the documentation.  The problem seems to be that often an individual sees something as broken when in fact the change fixes a problem for a much broader base of people.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> instead, we are supposed to believe that your position all along has
> been what you just changed it to, that Apple does break things
> sometimes but it has good reasons to do so.

This isn't a change; it's a different semantic interpretation of "break."  
If we change something and it makes life overall better than it was 
instead of worse, I don't call it "breaking something," although for the 
small handful of people (relatively speaking) for whom it causes a 
problem, sure, it seems like a breakage.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> And then you've tossed in
> some more inane arguments just to confirm that no one should treat you
> seriously, such as saying that developers should not pay attention to
> explicit instructions in Inside Macintosh.

You have a bad habit of overgeneralizing, Tim.  What I said was that using 
assembly language to directly manipulate something when there is a library 
routine to do so is a bad idea, and that for Inside Macintosh to recommend 
it is also bad.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> You seem to have forgotten that a job in Developer Relations is a job
> in Public Relations; it is not the pulpit of Jonathan Edwards.

I'm not in Developer Relations.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> As a
> result, you are breeding ill-will towards Apple,

I doubt it.  By your own admission, your problem is with me.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> and people are coming
> to ignore your conclusions even in the very rare cases where you
> sincerely try to prove them correct.

For whom exactly are you speaking?  So far, you're the only one making 
these claims.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> >The function of my department is to help people create good, reliable
> >Macintosh software.
> 
> And to maintain good relations with the developer comunity, which by
> nature involves taking seriously objections raised by those
> developers.  Instead, you contemptuously dismiss the complaints without
> dealing honestly with their substance, and you dismiss the complainers
> themselves as "people who aren't as experienced or as well-informed
> about how the Macintosh works".  This is highly obnoxious behavior.

Good point, and I'll take this opportunity to apologize for a comment made 
in frustration.  I do take problem reports seriously, but I do have 
difficulty taking issues like the tail-patching one seriously when it's 
been covered here and in Tech Notes so completely and by so many people.  
I'd also like to point out that professional courtesy is a two-way street; 
a developer statement that "Apple will never fix something that has been 
broken since day one" is a combination of arrogant, ignorant, and rude 
(that's the STATEMENT, folks, not necessarily the person), and certainly 
does nothing to motivate me to lend an ear to what that person has to say.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> >Perhaps I'm like an army drill sargeant or something: I'm harsh, I'm
> >stern, I'm a pain in the ass, but it's all to benefit the person being
> >disciplined.
> 
> Gee, Daddy, thanks a lot.

Gee, Tim, what a substantive rebuttal.  You know as well as I do that what 
makes the Macintosh what it is is precisely the set of standards and 
guidelines that I attempt to promulgate here.

In article <9041@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
> And when "the rules" are handed down as infallible and inarguable fiats
> from on high, Apple's image suffers, the developers ignore the rules,
> and the user suffers.

Tim, the reasons behind the rules, guidelines, whatever, have been stated 
time and time again.  You know them.  I know them.  Obviously they change, 
as our hardware and system software changes, but it's just not possible to 
do everything that everyone wants.  In fact, it's not even desirable.

I'm sorry if tons of comp.sys.mac.programmer readers are getting upset 
because I advance our position here so forcefully.  I'll try to tone it 
down.  But Tim, your accusations that I have given no technical reasons 
for what I've said simply don't hold water.  Please go back and look again.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

tim@hoptoad.uucp (Tim Maroney) (11/22/89)

In article <21353@brunix.UUCP> ejd@iris.brown.edu (Ed Devinney) writes:
>   Jeeeezzzuss, guys...when did Apple (aside from Steve Jobs maybe) claim that 
>the Mac family would be upward-compatible forever?  And if they did, when
>were you gullible enough to believe them?

When Apple instituted compatibility guidelines which were supposed to
insure binary upward compatibility, that's when.  Applications on the
Mac are *not* supposed to require periodic recompilation.  Perhaps you
have MacOS confused with minicomputer operating systems like UNIX and
VMS.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Americans will buy anything, as long as it doesn't cross the thin line
 between cute and demonic." -- Ian Shoales

casseres@apple.com (David Casseres) (11/23/89)

Only three posts on tail patches today, and two of them are maroneys.  
Whatsamatta with you guys?  Get with it!

David Casseres

Exclaimer:  Hey!

lins@Apple.COM (Chuck Lins) (11/23/89)

In article <5361@internal.Apple.COM> casseres@apple.com (David Casseres) writes:
>Only three posts on tail patches today, and two of them are maroneys.  
>Whatsamatta with you guys?  Get with it!
>
>David Casseres
>
>
Exclaimer:  Hey!

In the beginning the was Clarus the Dogcow. To make a very long story very
short, Clarus created the ROM Gods (a.k.a. Apple's system software engineers).
In time, a new priesthood arose to worship the new gods and interpret the
words of divine wisdom for the humble masses. (The priesthood is called DTS).
One day, the gods summoned their priesthood unto them to proclaim some of their
wisdom. They spoke in unison "Thou shalt not tail patch. Knowest that it will
break your software artifacts in ways that are unexpected and unpredictable."
The priests took the words of the gods unto the masses. Most believed. But a
few heretic non-believers refused the wisdom of the gods and tail patched
anyway.

Then one day, the gods summoned their priesthood, servants, and the masses
together announcing the wonderful new magic of System 7.0. And the people
rejoiced. And the gods were pleased. And everybody lived happily ever after.

Except for those who tail patched, for their software broke, and their users
were unhappy. For their favorite INITs no longer worked. And so the users
smote the unbelievers and drove them from the land and refused to buy their
products. Thus, the non-believers were left out in the cold, hungry, and
unhappy. So they plotted revenge on the new gods and the people... But that's
another story.

:-)


-- 
Chuck Lins               | "Exit left to funway."
Apple Computer, Inc.     | Internet: lins@apple.com
20525 Mariani Avenue     | AppleLink: LINS
Mail Stop 41-K           | 
Cupertino, CA 95014      | "Self-proclaimed Object Oberon Evangelist"
The intersection of Apple's ideas and my ideas yields the empty set.

peltz@cerl.uiuc.edu (Steve Peltz) (11/23/89)

Hmph, just started reading this group, and I see the subject of "tail patches"
has wandered all over the place, but I'd just like to say that the first
application I ever wrote for the Mac (written using a Lisa, Workshop Pascal,
and MacWorks) still works on every Mac and System I've ever had a chance
to test it on (MacPAD 0.4). I've updated it since, but it still works on a
Mac 512, and if I had a MacXL or 128 I'm 99% confident it would work there.
I do one thing outside the standards: I look directly at keycodes instead
of ASCII; however, I have a lookup table as a resource to make it easy to
change (I realize there are ways to specify a custom translation, but I'd
have to maintain my specific table one way or another, and it was much too
much hassle to do it that way).

There are some things I just decided I wouldn't bother working around: closing
the serial port (on earlier Macs, disabled the mouse!), ignoring some error
codes from serial drivers (in some versions of MacWorks, the serial driver
returned spurious error codes), flashing cursor on the screen when an offscreen
bitmap happened to correspond to the same coordinates, not having a fully
backed window (too slow to plot to off-screen AND on-screen, and display
could be of unlimited length so can't store as a PICT or save incoming
serial data stream for playback, even if those were fast enough)("solution"
is that I don't refresh my window), the STUPID keycodes for Mac+ cursor keys
(even if the numeric keypad was stupid, there were better ways to do the Mac+
keys that wouldn't have broken existing applications, and anyway wasn't the
argument just given that it WAS ok to require updates to programs from time
to time?).

Anyway, the point is that I wrote it following the guidlines and it never
broke. I find that reasonably impressive when compared to MS-DOS or anything
else. Admittedly, my program doesn't change the behavior of the system, it is
a mere application, but *I* think the guidelines are useful, appropriate, and
not excessively restrictive. I just wish the system wasn't becoming so damn
complex!
--
Steve Peltz (almost) CFI-G
"Monticello traffic, Glider 949 landing 18, full stop"

dricejb@drilex.UUCP (Craig Jackson drilex1) (11/25/89)

In article <5320@internal.Apple.COM> chewy@Apple.com (Paul Snively) writes:
>In article <1989Nov20.182741.2658@eng.umd.edu> russotto@eng.umd.edu 
>(Matthew T. Russotto) writes:
>> In article <5292@internal.Apple.COM> chewy@apple.com (Paul Snively) 
>writes:
>> >In article <17090@dartvax.Dartmouth.EDU> erics@eleazar.dartmouth.edu 
>(Eric 
>> >Schlegel) writes:
>> >get that same effect, given that there's a routine called RESTART that 
>is 
>> >marked NOT IN ROM is to Link in the appropriate library (usually 
>Runtime.o 
>> >for MPW users) from your development system, and make the call to the 
>> >library routine.  That's what libraries are for.

This raises the issue for third-party applications tool developers.  Either
one waits for Think, TML, to decode those libraries, or one does it them-
selves.

>> So?  Your application still breaks.  Unless you have a dynamic linker,
>> of course... (was it REALLY that hard for apple to keep a JMP to the 
>right
>> spot in 0A(RomBase)? )
>
>Your application won't break as long as you link with up-to-date library 
>code!  As for "was it hard to keep the jump," I'm not a ROM engineer, so I 
>don't really know.  There were some pretty hairy changes in going from the 
>old Macs to the II-family Macs.

So, you're supposed to ship MPW, with some sort of updates subscription,
to everyone who wants to automate their dental practice?  Here, I believe
you're way off base, and Apple appears to have screwed up.  (This stuff
hasn't really affected me; I've never managed to complete a real Mac
application.  Just too much investment in doc & time...)

For better or worse, Documented is Documented, whether it's an assembly-
language note or a library description.  Major computer manufacturers
come to learn (and hate) this.

Apple comes out on the lower end of the "how many applications break on
each release" scale.  I think Berkeley CSRG is actually lower, but most
commercial vendors are forced to do much better.  MVS will still run
binaries from OS/360, compiled 20 years ago.  Unisys/Burroughs finally
got tired of offering such compatibility: they now only support a binary
for four releases of the operating system: one forward, the current one,
and two back.  *If the application is too old, it isn't run*.  This is
much better than have one function break on odd Tuesdays--it keeps
everything up front.
-- 
Craig Jackson
dricejb@drilex.dri.mgh.com
{bbn,ll-xn,axiom,redsox,atexnet,ka3ovk}!drilex!{dricej,dricejb}

ieee@smu.uucp (IEEE group account) (11/25/89)

In article <9028@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>In article <46c51bee.129dc@blue.engin.umich.edu> mystone@caen.engin.umich.edu
>writes:
>>When the source and destionation rectangles are 32 by 32, do a bitwise compare
>>with the stuffed trash can.  (Or whatever your new icon is that signifies 
>>there's something in the trash.)  If it's changing to the full state, set a
>>flag in your code.  Next time _CopyBits is called with source and destination
>>rectangles of 32 by 32, and the bit map is the empty state of the trash
>>can, play your sound here, then go on to the old _CopyBits.  My, how the mind
>>goes at 5:15 in the morning...
>
>Amusing, but remember how often the Finder draws icons.  This kind of thing
>is not worth a performance hit of this magnitude.

I'm sure no one would ever implement such a scheme just to play a sound
or to, let's say, change a black&white icon to a color icon :)



-Fred

_______________________________________________________________________________
-  Fred Hollander              |  AppleLink: F.Hollander                      -
-  President                   |  CIS:       72077,3544                       -
-  Software Innovations, Inc.  |  Internet:  f.hollander@applelink.apple.com  -
-                                                                             -
-  SMU is not responsible for the content of this posting.                    -
_______________________________________________________________________________

chewy@apple.com (Paul Snively) (11/28/89)

In article <6353@drilex.UUCP> dricejb@drilex.UUCP (Craig Jackson drilex1) 
writes:

[Stuff about Restart removed]

> This raises the issue for third-party applications tool developers.  
Either
> one waits for Think, TML, to decode those libraries, or one does it them-
> selves.

Well, that really means that we need to get new library code to folks like 
Symantec and TML Systems faster, which I'll certainly agree with.

In article <6353@drilex.UUCP> dricejb@drilex.UUCP (Craig Jackson drilex1) 
writes:
> So, you're supposed to ship MPW, with some sort of updates subscription,
> to everyone who wants to automate their dental practice?  Here, I believe
> you're way off base, and Apple appears to have screwed up.  (This stuff
> hasn't really affected me; I've never managed to complete a real Mac
> application.  Just too much investment in doc & time...)

The answer to the first part is clearly "no; it's not necessary in the 
vast majority of the cases."  If the "dental practice" is using THINK or 
TML, they should get updates from them.  On the other hand, if this dental 
practice IS doing Macintosh programming, they do have to concern 
themselves with keeping up to one extent or another.  That's just the way 
the real world is.

In article <6353@drilex.UUCP> dricejb@drilex.UUCP (Craig Jackson drilex1) 
writes:
> For better or worse, Documented is Documented, whether it's an assembly-
> language note or a library description.  Major computer manufacturers
> come to learn (and hate) this.

I'm not disagreeing with this; I'm saying that precisely because it's 
being committed to print, Inside Macintosh could stand to try to be a 
little more careful about saying things like "jump into ROM here."

In article <6353@drilex.UUCP> dricejb@drilex.UUCP (Craig Jackson drilex1) 
writes:
> Apple comes out on the lower end of the "how many applications break on
> each release" scale.  I think Berkeley CSRG is actually lower, but most
> commercial vendors are forced to do much better.  MVS will still run
> binaries from OS/360, compiled 20 years ago.  Unisys/Burroughs finally
> got tired of offering such compatibility: they now only support a binary
> for four releases of the operating system: one forward, the current one,
> and two back.  *If the application is too old, it isn't run*.  This is
> much better than have one function break on odd Tuesdays--it keeps
> everything up front.

I think you mean to say the HIGHER end of the scale.  Actually, if you go 
around trying most commercial Mac applications on most of our machines and 
OS releases, they mostly tend to work across everything from the Mac Plus 
running System 4.1 on up.  The things that break the most are a) 
non-commercial efforts that don't spend so much time paying attention to 
the guidelines, b) INITs and the like, which tend to be hacks by 
definition.

It's not quite fair to compare the microcomputer industry's compatibility 
efforts to the mainframe industry's; the micro industry has to move much 
faster and make larger steps to differentiate its companies from each 
other.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

time@oxtrap.oxtrap.UUCP (Tim Endres) (11/28/89)

In article <5323@internal.Apple.COM> lsr@Apple.COM (Larry Rosenstein) writes:

   From: lsr@Apple.COM (Larry Rosenstein)
   In article <26788@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:

   [ ... tons of discussion on patching religion ... ]

   Staying away from tail patches doesn't mean you can't customize the 
   system.  That's a silly statement.  History has shown that programmers 
   will patch any trap they want to get some hack done.  That's fine with me. 

   Just look at the number of INIT managers, and problem reports having to do 
   with INITs.  It shows that writing an INIT is a black art, and not 
   something that should be taken lightly.

Has Apple looked into some OS mechanism that provides ROM patching?
Like, bless and condone patching in a "supported" manner. Just curious.

time@oxtrap.oxtrap.UUCP (Tim Endres) (11/28/89)

In article <1989Nov21.153508.1872@eng.umd.edu> russotto@eng.umd.edu (Matthew T. Russotto) writes:

   In article <21353@brunix.UUCP> ejd@iris.brown.edu (Ed Devinney) writes:
   >   Jeeeezzzuss, guys...when did Apple (aside from Steve Jobs maybe) claim that 
   >the Mac family would be upward-compatible forever?  And if they did, when
   >were you gullible enough to believe them?

   That is the whole argument.  Apple claimed, and continues to claim, that
   any program that follows their guidelines will work on all future platforms.
   This simply isn't so.

   >++++++
   >ed devinney...IRIS/Brown University, Providence, RI...ejd@iris.brown.edu
   --
   Matthew T. Russotto	russotto@eng.umd.edu	russotto@wam.umd.edu

You must remember that the above claim is absurd. At best it is a "goal".
In fact, depending on what is declared to be "the" quidelines,
the claim *is* true.

I have a new company. Blue Sky Inc.
We intend to produce a computer that runs all operating systems and is
binary compatible with every machine in existence. And they all run
simultaneously in seperate windows!

You are smart enough to see through that one.
Why let a little colored Apple confuse you?

chewy@apple.com (Paul Snively) (11/28/89)

In article <TIME.89Nov27160228@oxtrap.oxtrap.UUCP> time@oxtrap.oxtrap.UUCP 
(Tim Endres) writes:
> Has Apple looked into some OS mechanism that provides ROM patching?
> Like, bless and condone patching in a "supported" manner. Just curious.

Yes, various groups within Apple have looked at doing this.  There are a 
variety of problems.  One problem is the one that's been under discussion, 
which, for the sake of completeness, goes like this:

1) A bug is discovered in some ROM routine.  The routine may be fairly 
   large.
2) Rather than replace the entire largeish routine in RAM, Apple fixes the 
   bug by patching the code for some trap that the broken routine calls.
3) The patch for the trap, when called, looks at some offset on the stack 
   for a return address to the broken routine so as to ensure that, within the 
   context of this invocation, it was indeed called from the broken routine.
4) If the address comparison comes out equal, some code that fixes the 
   problem is executed.  Otherwise the trap goes about its normal business.

Tail patching (that is, replacing a trap definition in such a way that the 
original code is effectively JSRed to rather than JMPed to) is bad because 
effectively JSRing to the original code screws up the stack offsets and 
therefore screws up the return-address comparison, so the fix code never 
gets executed at all.  Oops.

Anyway, another potential problem with even a sanctioned way to patch 
traps is that the patch may not completely obey the letter of the law (for 
example, a trap may be callable at interrupt time, but the patched version 
may not.  Or a trap may be guaranteed not to move memory, but the patched 
version may allow for a heap scramble).  Unfortunately, there's no a 
priori way to know what a patch is going to do.  As a friend of mine who 
writes Macintosh applications puts it, "not only am I programming my 
users' Macintoshes, but everyone whose INITs and cdevs that my users are 
using is programming my users' Macintoshes."

Hope this helps.

__________________________________________________________________________
Just because I work for Apple Computer, Inc. doesn't mean that they 
believe what I believe or vice-versa.
__________________________________________________________________________
C++ -- The language in which only friends can access your private members.
__________________________________________________________________________

pem@cadnetix.COM (Paul Meyer) (11/29/89)

In article <9041@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>But Paul, you are missing the point.  Every case I've seen here where
>people argue with you is because you have *not* raised any compelling
>argument.  It seems you want us all to put "DTS said it, that settles
>it, and I believe it" bumper stickers on our cars.  I am referring only
>to you; most other Apple employees here have much better network
>manners.  You, however, specialize in responses which are inane and
>peremptory; for example, your messages on tail patches that nowhere
>included a technical explanation of the problem with them, or your
>message on file ids that completely ignored every point I raised (as
>some other posters noted at the time).

	I'm sorry, Tim, but I just can't let this go by.  It's true that
when you, or somebody who I know is competent to talk about it, take DTS
or Apple to task about something, I pay attention.  The fact is, this
whole flamefest started with somebody asking what a tail patch is and
whining that he "ought" to be able to do it.  DTS is a bunch of people
whose *job* is to track the pitfalls of programming Macs (Apples), and
I can't stand to see everybody taking pot-shots at them because they say
that we *shouldn't* do something because it is likely to break.  Your
job also requires you to keep up with things, and you are qualified to
take pot-shots.  Most of the people who whine about things *don't* have
the perspective on what Mac development looks like that you or the DTS
people do.
	Additionally, if I ask you, "Tim, why shouldn't I go out in
the snow naked", I would be very surprised indeed if you gave me a nice
60-line explanation of body temperature, wind chill, biochemistry, and
the phase of the moon.  You would answer, with precisely the information
that I seek, "because you would get sick or die."  I'd rather see DTS
answering simple questions simply so they can get to the meaty questions
and spend the time on *them*.  A simple answer can always receive a
request for more information if it really is needed.

Paul Meyer                      pem@cadnetix.COM
Daisy/Cadnetix Inc. (DAZIX)	{uunet,boulder}!cadnetix!pem
5775 Flatirons Pkwy.            GEnie P.MEYER   CI$ 73627,1274
Boulder, CO 80301               (303)444-8075x277

tecot@Apple.COM (Ed Tecot) (11/30/89)

In article <17090@dartvax.Dartmouth.EDU> erics@eleazar.dartmouth.edu (Eric Schlegel) writes:
>In article <5249@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>>In article <1989Nov16.043300.8959@eng.umd.edu> russotto@eng.umd.edu 
>>(Matthew T. Russotto) writes:
>>> In article <5212@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>>> >
>>> >And I'd be interested in any examples of "something that we have 
>>> >decided to break," let alone something that we have decided to break 
>>> >and then not fix.

Okay boys and girls, call off the wolves.  Keep in mind that he's relatively
new to the net.  Please treat him a little nicer lest he run with his tail
between his legs and never return.  I'm sure none of us want to see that
happen.  Perhaps a few of us can even identify with it (right, Byron?)
What Paul was trying to point out was that we don't intentionally break
things.  When changes need to be made, we attempt to do make it as painless
as possible.  See Tech note 227 "Toolbox Karma" for even more handwaving.

>Resource Header Application Bytes were 128 bytes of data at the beginning
>of a resource file that supposedly were available for application use.
>This is documented on pp. 128-9 of IM, volume 1. Tech Note 62, from Jan. 1986,
>states that applications should no longer use these bytes as they're 
>reserved for future use by the Resource Manager.

No one seemed to be using them anyway.  We decided to reserve them so that
we might be able to make improvements to the Resource Manager in the future.
Applications are still free to use the data fork or create their own resource.

						_emt

tecot@Apple.COM (Ed Tecot) (11/30/89)

In article <17105@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu (Earle R. Horton) writes:
>In article <5212@internal.Apple.COM> chewy@apple.com (Paul Snively) writes:
>>And I'd be interested in any examples of "something that we have 
>>decided to break," let alone something that we have decided to break 
>>and then not fix.

I'm not going to claim that we never do this, but I will claim that we never
do it without reason.  We're not spiteful, and we don't make arbitrary
decisions.

>"Assembly-language note:  Changing the value of the block's master
>pointer lock bit with a BSET instruction is faster than HLock.
>However, HLock may eventually perform additional tasks."

Well, it still works in 24-bit systems.  This one we really had no choice in.
In order to increase the amount of memory available (which developers clamor
for), we will eventually have to break this.  I'd say that in this case, it
was a poor documentation choice.

>;The following twelve OS traps have been redundantly defined as
>;Tool traps as well. They should be
>;accessed as OS traps, but their slots in the Tool trap table
>;will be reserved forever.
>;	$1A GetZone
>;	...

Actually, I personally sweated bullets over this one.  We were running out
of traps, and I discovered that no one appeared to be using these redundant
traps anymore.  In fact, DTS went to the trouble to verify this, and found
that it was true.  DTS also found out that a thirteenth, undocumented
redundant trap WAS being used.  The application was fixed about a year and
a half ago.  In this case, we broke no one.

>Network Events.

Actually, we never broke these.  Network events were always implemented by
the libraries linked with the application.  Applications which used them
will continue to work, since the code which creates the events is in the
application.  Of course, there's no longer a guarantee that the events will
be delivered to the application that created them...

>Calling PopupMenuSelect under System 6.0 with Color QuickDraw caused
>the menuWidth and menuHeight both to be set to -1!  I was told that
>this was done deliberately to allow for the possibility of a loaded
>menu being used on different monitors.  Result: CalcMenuSize is broken
>under System 6.0 because its effect is not what IM says it is.

But this was fixed in System 6.0.2.  This was a bona fide bug.  I'd say
that this falls in the class of things that we fixed.

>Mac Plus keyboard shifted arrow keys return identical codes to numeric
>keypad keys.  This hardware was shipped in a broken state, and no fix
>was ever supplied.  Weak-ass excuse supplied by Apple was that this
>was done for compatibility with original separate numeric keypad.

Oh, so now you're complaining because of something we didn't break?
Bad example.  (Excuse my sarcasm, but I can't express it any other way)

>  "We broke it because it was a bad idea in the first place, anyway."
>
>  "Fine, but remember, it was YOUR idea."

What's wrong with admitting your mistakes and correcting them?

						_emt

jeremyr@cs.qmc.ac.uk (Jeremy Roussak) (11/30/89)

In article <10385@cadnetix.COM> pem@cadnetix.COM (Paul Meyer) writes:
>I really can't let this go by...
> ... The fact is, this
>whole flamefest started with somebody asking what a tail patch is and
>whining that he "ought" to be able to do it.

I can't let this go by either.  I started this "flamefest" with a perfectly
reasonable request for information.  As I recall, it went,

1. What are tail patches?
2. If they are what I think they are, why are they bad?

I think that's a simple request with no element of whine present and
certainly no feeling that I "ought" to be able to do anything.

Jeremy Roussak