From: grobbins@Apple.COM (Grobbins)
Newsgroups: comp.sys.mac.programmer
Subject: Re: LED Lights Test [code]
Date: 26 Sep 92 19:57:56 GMT
Organization: Apple Computer Inc., Cupertino, CA

In article <ksand-250992182016@wintermute.apple.com> ksand@apple.com (Kent Sandvik) writes:
>In article <2201.2AC0BB34@fidogate.FIDONET.ORG>,
>Hank.Woods@p0.f222.n125.z1.FIDONET.ORG (Hank Woods) wrote:
>> A couple weeks ago someone posted in this newsgroup some code that would 
>> make the LED lights on the mac keyboard blink on and off 
>Didn't Greg Robbins write something similar? Yep, it's placed on the
>Developer CD, do a find on 'ledApp'.

ledApp should also be in the snippets collection in the dts area of
ftp.apple.com.  Anyway, pasted below is the portion relevant to setting
the LEDs.  Documentation for ADB is in IM V and in the ADB Tech Note
("Space Aliens Ate My Mouse".)

Grobbins               grobbins@apple.com

Usual disclaimers apply.

---

from ledApp.p:

  FUNCTION GetA2: LONGINT;
    INLINE $2E8A; { put A2 on stack }
    
  PROCEDURE CompADBOp;
  { completion routine for ADB talks and listens }
    TYPE
      boolPtr = ^BOOLEAN;
    VAR
      completionFlagPtr: boolPtr;
    BEGIN
      { set flag to indicate completion routine has run; A2 points to the flag }
      completionFlagPtr := boolPtr(GetA2); 
      completionFlagPtr^ := TRUE;
    END;
  
  PROCEDURE DoSetLEDs(ledPat: BYTE);
  { set the leds to the given pattern }
    TYPE
      ADBregBuffType = PACKED ARRAY[0..8] of BYTE;

    VAR
      retCode:  OSErr;
      i: INTEGER;                  { index through ADB devices }
      numADBs: INTEGER;              { total number of ADB devices }
      anADBDB: array[1..16] of ADBDataBlock;    { data block for each device }
      anADBadd: array[1..16] of ADBAddress;    { address of each device }
      regBuff: ADBregBuffType;          { buffer for ADBOp commands }
      oldReg: BYTE;
      completionFlag: BOOLEAN;

    BEGIN
      numADBs := CountADBs;

      FOR i:=1 to numADBs DO
        BEGIN
          { get an address for an ADB device }
          anADBadd[i] := GetIndADB(anADBDB[i], i);
          
          { a keyboard has an original address of 2, but the actual ADB address
            may change if there is a conflict; a U.S. extended keyboard has a
            device type ("handler ID") of 2, but unfortunately some other ADB
            devices also do }
          IF (anADBDB[i].origADBAddr = 2) AND (anADBDB[i].devType = 2) THEN 
             { ext keyboard }
            BEGIN
              regBuff[0] := BYTE(2); { initial data buffer length }

              { talk }
              completionFlag := FALSE;
              retCode := ADBOp(@completionFlag, @CompADBOp, @regBuff,
                 kTalkCommand + kLEDRegister + 16 * anADBadd[i]);
              
              IF retCode <> noErr THEN
                EXIT(DoSetLEDs);
              
              { do nothing until completion routine has run }
              REPEAT
                ;
              UNTIL completionFlag;
              
              { extended keyboard has a word of data, LEDs are low 3 bits }
              oldReg := regBuff[2];
              
              { set the specified bits; note that a clear bit indicates a
                lit LED }
              regBuff[2] := BOR(BAND(oldReg, 255-7), 7 - LedPat);

              { listen }
              completionFlag := FALSE;            
              retCode := ADBOp(@completionFlag, @CompADBOp, @regBuff,

                kListenCommand + kLEDRegister + 16 * anADBadd[i]);

              { do nothing until completion routine has run }
              REPEAT
                ;
              UNTIL (retCode <> noErr) OR (completionFlag);
              
            END; { if }
        END; { for }
    END; { DoSetLEDs }