[comp.sys.mac.programmer] "TN.248.DAs in Need of Time" in need of proofreader.

earleh@eleazar.dartmouth.edu (Earle R. Horton) (09/08/89)

The topic is setting flags in the high-order byte of a desk
accessory's Device Control Entry.  The quoted text is from Technote
248, August 1989 version.

>The _BitClr and _BitSet Toolbox utilities are a mite on the
>brain-damaged side...
>
>(I think whoever wrote these routines did this just to see if anyone
>was paying attention.)
>
>Pascal
>
>BitClr(@dce^.dCtlFlags, 31 - dNeedTime);{ clear bit 5/dNeedTime bit. IM I-471 }
>BitSet(@dce^.dCtlFlags, 31 - dNeedTime);{ set bit 5/dNeedTime bit.  IM I-471 }
>
>C
>
>dce->dCtlFlags ^= dNeedTime;		/* clear bit 5/dNeedTime bit */
>dce->dCtlFlags |= dNeedTime;		/* set bit 5/dNeedTime bit */
>

The Pascal code is incorrect.  Substitute 7 for 31.  Look who's paying
attention now!

The C code is grossly incorrect.  The correct code is

dce->dCtlFlags &= ~(1 << (dNeedTime + 8) ); /* Clear. */
dce->dCtlFlags |= (1 << (dNeedTime + 8));   /* Set.   */

Furthermore, "dNeedTime" is not defined in the MPW C header files.
This leads me to believe that the C code, and possibly the Pascal
code, has never been tested or even typed in anywhere, except for the
Technote.

Tip 1:	Test code before distribution.
Tip 2:	Know your operators.

Earle R. Horton

pvh@Apple.COM (Pete Helme) (09/08/89)

Ahem.   

"Oops."

The BitSet, BitClr stuff is definitely wrong.  I originally had 7 - dNeedTime
in there.  Someone else thought it should be changed in the tech note 
review (yes, there is a 'proofreading'. In this case it did everything but
help, which is rare).  Stick with your your first draft on occasion I guess.

Unfortunately for me, I used THINK C (not MPW C) to test the statement:

 dce->dCtlFlags ^= dNeedTime;
 dce->dCtlFlags |= dNeedTime;

which THINK C compiles to:

 BCHG    #5,4(A0)          
 BSET    #5,4(A0)          

BSET #5,4(A0) is OK for what we want since it's the high byte we're changing, 
but it's not correctly compiled as far as the operators are concerned.  
THINK C actually included stuff like dce->dCtlFlags |= dNeedTime in 
their old samples I believe.  That's why I probably left it that way.
BCHG 5,4(A0) is just plain wrong.  A pox on me and my 4 slice toaster.


FYI, THINK C compiled the following lines:

 dce->dCtlFlags &= ~(1 << (dNeedTime + 8)); 
 dce->dCtlFlags |= (1 << (dNeedTime + 8));  

to:

 BCLR    #0,4(A0)          
 BSET    #0,4(A0)          

Huh?

where as MPW C compiles to:

 ANDI    #$DFFF,4(A0)
 ORI     #$2000,4(A0)
  
Which is correct.

Anyone from Symantec care to comment?


As for dNeedTime not being included in the MPW interfaces, it's true, 
but it is defined in the THINK interfaces.  Why it isn't in MPW I 
don't know, but I'll see if I can get it (and the rest of device constants) 
put in for the next MPW release.  I guess I just assumed that people could 
type in constants themselves.  Guess I jumped to conclusions....  ;-)

The tech note will be fixed for the October batch.

All my C testing will be in MPW from now on that's for sure.

Thanks for your comments.  Always appreciated.

Pete Helme
"Whose every opinion was previously owned"
MacDTS
Apple Computer, Inc.

lim@iris.ucdavis.edu (Lloyd Lim) (09/08/89)

In article <34579@apple.Apple.COM> pvh@Apple.COM (Pete Helme) writes:
>
>Unfortunately for me, I used THINK C (not MPW C) to test the statement:
>
> dce->dCtlFlags ^= dNeedTime;
> dce->dCtlFlags |= dNeedTime;
>
>which THINK C compiles to:
>
> BCHG    #5,4(A0)          
> BSET    #5,4(A0)          
>
>BSET #5,4(A0) is OK for what we want since it's the high byte we're changing, 
>but it's not correctly compiled as far as the operators are concerned.  
>THINK C actually included stuff like dce->dCtlFlags |= dNeedTime in 
>their old samples I believe.  That's why I probably left it that way.
>BCHG 5,4(A0) is just plain wrong.  A pox on me and my 4 slice toaster.
>
>
>FYI, THINK C compiled the following lines:
>
> dce->dCtlFlags &= ~(1 << (dNeedTime + 8)); 
> dce->dCtlFlags |= (1 << (dNeedTime + 8));  
>
>to:
>
> BCLR    #0,4(A0)          
> BSET    #0,4(A0)          
>
>Huh?

If you look through the THINK C header files, you'll see what's going on.
Inside Mac says dNeedTime is 5 while THINK C has #define dNeedTime 0x2000.
Earle's code is correct for the Inside Mac values.

The correct code for THINK C is:

dce->dCtlFlags &= ~dNeedTime;
dce->dCtlFlags |= dNeedTime;

The output of the THINK C compiler (the resulting bit instructions) can be
explained by something I heard on the net sometime somewhere (probably in a
dream.  I remember the statement that the THINK C compiler optimizes bit
operations with single bit masks to bit instructions.  Is this true, Rich?

BTW, I was stuck for an hour today with code that essentially looked like
this once you evaluated all the #defines and stuff:

switch (x) {
0:
  /* */
  break;
1:
  /* */
  break;
default:
  Debugger();
  break;
}

For the life of me, I couldn't see what was wrong.  Then I noticed the missing
cases.  Arrrggghhh!  Sometimes I wonder why these things compile.  TMON wasn't
too enlightening since the code for the fake cases was in there and it looked
okay.

+++
Lloyd Lim     Internet: lim@iris.ucdavis.edu (128.120.57.20)
              Compuserve: 72647,660
              US Mail: 146 Lysle Leach Hall, U.C. Davis, Davis, CA 95616

pvh@Apple.COM (Pete Helme) (09/10/89)

That explains it.  Since THINK C has already defined dNeedTime to be 0x2000
and neither MPW C or Pascal have bothered to define it as anything, I think 
we'll just leave the technote the way it is and use 0x2000 for dNeedTime.  
(SysEqu.a using '5' is OK of course)

So we'll use:

	#define dNeedTime 0x2000	/* bit 5 of high byte of word */

	dce->dCtlFlags &= ~dNeedTime; 	/* clear */
	dce->dCtlFlags |= dNeedTime;	/* & set */

and try to have the MPW device manager interfaces modified accordingly.  
Sound OK?

Pete Helme
MacDDS
Apple Computers & Orthodontia