home *** CD-ROM | disk | FTP | other *** search
- // Sample AppleTalk adev resource
- // (C) 1994-1996 Stuart Cheshire <cheshire@cs.stanford.edu>
- //
- // You need to contact Apple to get an adev id assigned.
- // This file must be compiled into a code resource of type 'adev' with your id.
- // This resource file is then merged into the final adev file built by the
- // atlk project (See atlk.c)
- //
- // The main routine in assembly code here calls the three C routines below:
- // 1. doGetAdev indicates the available AppleTalk connection icons to display in
- // the Network Control Panel There is just one for the 'None' connection, but
- // other adevs may offer multiple connections -- eg. multiple serial ports --
- // in which case they are distinguished by an index in the low byte of d2
- // 2. doSelAdev is called when the user selects our icon
- // 3. doReSelAdev is called when the user double-clicks on our icon
- // Some of the parameters to the C routines are declared volatile to provide
- // call-by-value-return semantics, to allow the C code to easily return values
- // in registers without having to use even more nasty inline assembly code.
- // If your compiler doesn't honour volatile parameters you'll have to write
- // inline assembly code.
- //
- // You should also read the "Macintosh AppleTalkĀ® Connections Programmer's Guide"
- // available from Apple.
-
- #include <AppleTalk.h>
- #include "LAPEqu.h"
-
- #include "StuTypes.h"
- #include "adev.h"
-
- // *********************************************************************************
-
- local char doGetAdev(u_long const pram, u_long volatile d2, u_char *volatile name);
- local void doSelAdev(u_long volatile pram, u_long const d2);
- local void doReSelAdev(u_long volatile pram, u_long const d2);
-
- export void main(void)
- {
- asm {
- @0 move.l a4, -(sp) ; save A4
- lea @0, a4 ; set up global register
-
- cmpi.l #GetADEV, D0 ; Is this a GetADEV call?
- bne.s @1 ; If not, try the next one
-
- move.l a0, -(sp) ; If yes,
- move.l d2, -(sp) ; Push parameters on the stack
- move.l d1, -(sp)
- bsr doGetAdev ; and make the call
- move.l (sp)+, d1
- move.l (sp)+, d2
- move.l (sp)+, a0
- bra.s @exit
-
- @1 cmpi.l #SelectADEV, D0 ; Is this a SelectADEV call?
- bne.s @2 ; If not, try the next one
-
- move.l d2, -(sp) ; If yes,
- move.l d1, -(sp) ; Push parameters on the stack
- bsr doSelAdev ; and make the call
- move.l (sp)+, d1
- move.l (sp)+, d2
- bra.s @exit
-
- @2 cmpi.l #ReSelADEV, D0 ; Is this a ReSelADEV call?
- bne.s @exit ; If not, give up
-
- move.l d2, -(sp) ; If yes,
- move.l d1, -(sp) ; Push parameters on the stack
- bsr doReSelAdev ; and make the call
- move.l (sp)+, d1
- move.l (sp)+, d2
-
- @exit move.l (sp)+, a4 ; restore A4
- }
- }
-
- // *********************************************************************************
-
- local short GetMyResID(void)
- {
- short rID;
- ResType rType;
- Str255 rName;
- GetResInfo(RecoverHandle((Ptr)&main), &rID, &rType, rName);
- return(rID);
- }
-
- // *********************************************************************************
-
- enum { InterfaceActive = -1, InterfaceInactive = 0, NoMoreInterfaces = 1 };
-
- local u_short num_ports;
-
- local char doGetAdev(u_long const pram, u_long volatile d2, u_char *volatile name)
- {
- // If d2 is zero, then this is the first adev call, and we should do any
- // necessary initialization. As part of that initialization I set the high
- // order bit of d2, so that on the next call I'll know that I've already done
- // the initialization.
- // The low byte (byte 0) of d2 contains a zero-based index to identify a
- // particular port for adevs that support multiple ports (e.g. Printer Port
- // and Modem Port) -- so we return index zero the first time and increment
- // it on subsequent calls.
-
- if (d2) d2++; // If not first call, increment
- else // else do any necessary one-time initialization
- {
- d2 = 0x80000000; // Set the top bit
- // Do initialization here,
- // eg. count how many ports are available
- num_ports = 1;
- }
-
- // See if we have finished.
- if ((d2 & 0xFF) >= num_ports) return(NoMoreInterfaces);
-
- // Now do any necessary per-port setup
-
- // Give the name of the port identified by index (d2 & 0xFF)
- name = "\pNone";
-
- // Tell the control panel if this port is our currently selected one
- if (((pram >> 8) & 0xFF) == (d2 & 0xFF)) return(InterfaceActive);
- else return(InterfaceInactive);
- }
-
- // *********************************************************************************
-
- // The system uses the least significant byte of the PRAM to store the ID of the adev
- // in use and the top three bytes are nominally free for us to use, although in practice
- // Duos seem to revert to LocalTalk on wake-up if the top word is not set to FFFF.
-
- local void doSelAdev(u_long volatile pram, u_long const d2)
- {
- // User has clicked on one of our icons, identified by d2. Stash this code
- // in the AppleTalk PRAM so we'll know which port to open in the atlk resource.
- pram = 0xFFFF0000 | (d2 << 8) | GetMyResID();
- }
-
- // *********************************************************************************
-
- local void doReSelAdev(u_long volatile pram, u_long const d2)
- {
- // User has clicked again on our already selected icon
- // Can display dialog for options or configuration display here.
- pram = 0xFFFF0000 | (d2 << 8) | GetMyResID();
- }
-