Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


Apple IIgs
#69:    The Ins and Outs of Slot Arbitration

Revised by:    Matt Deatherage                                       May 1990
Written by:    Matt Deatherage                                 September 1989

This Technical Note discusses the concept of a 14-slot Apple IIgs system 
through dynamic software slot arbitration.  It presents concepts of which all 
IIgs programmers should be aware for full compatibility.
Changes since September 1989:  Removed the section which stated that this Note 
showed how to switch slots in a way that does not interfere with slot 
arbitration and replaced it with the proper description, which is how to 
search a 14-slot system for peripherals and their identification bytes.
_____________________________________________________________________________


History

The Apple II has always had seven slots.  In some cases (e.g., IIe), one of 
the slots was handled specially by the hardware, or (e.g., IIc) there was no 
hardware present for peripheral cards at all.  But there have always been 
seven "slots" with firmware at location $Cn00 (where n is the slot number).  
If there was no firmware, there was no peripheral connected.

With the introduction of the Apple IIgs, the Apple II family saw its first 14-
slot system.  Seven hardware slots are provided for peripheral cards (like on 
the IIe), and seven internal "ports" with connectors on the back panel are 
provided by the system (like on the IIc).  Since $C800 and above cannot be 
used for additional slots (that space is shared between all interface cards), 
each of the seven internal ports is matched with one of the slots, and either 
the port or the slot is enabled at any given time.  The IIgs hardware allows 
switching between the two, so all fourteen slots could be used more or less 
simultaneously.

This situation posed a problem--the Apple II had only a disk operating system, 
not an overall operating system.  Access to non-disk devices (i.e., character 
devices, like a serial card) was not arbitrated by the system in any way.  The 
world was used to seven, and only seven, slots.  Attempting to use more in a 
shared system such as the IIgs resulted in somebody jumping to slot firmware 
that somebody else had switched out.  This tended to crash the system.

Then came GS/OS.  With its centralized mechanism for dispatching to all 
devices connected to a system, GS/OS provides hope (for the first time) that a 
central routing mechanism can dynamically arbitrate between slots and ports, 
allowing the use of all 14 at one time.  This is called dynamic slot 
arbitration, and is handled by a portion of GS/OS referred to as the Slot 
Arbiter.

Although the Slot Arbiter does not function in System Software 5.0 or earlier, 
it may function in the future.  A skeleton is present in version 5.0 and later 
that accepts Slot Arbiter calls, but the skeleton does not actually switch any 
slots.  This Note details the Slot Arbiter functionality and shows how to 
search a 14-slot system for peripherals and their identification bytes.

Note:  The Slot Arbiter must not be used unless GS/OS is the current 
       operating system.

The Slot Arbiter

The Slot Arbiter is accessed through the GS/OS system service call vector 
DYN_SLOT_ARBITER ($01FCBC).  On ROM 03 and later, the vector is duplicated at 
$E10208.  Entry to the Slot Arbiter is via a JSL instruction, and exit is via 
RTL.  The parameters are as follows:

Entry:
    A = Slot to be selected (defined below)
    X = Undefined (or Bit Encoded Slot Configuration)
    Y = Undefined
    B = Undefined
    D = Undefined
    P = N V M X D I Z C  E
        x x 0 0 0 x x x  0

Exit:
    A = Error Code
    X = Bit Encoded Slot Configuration
    Y = Undefined
    B = Unchanged
    D = Undefined
    P = N V M X D I Z C  E
        x x 0 0 0 x x 0  0        If A = $0000 (no error)
        x x 0 0 0 x x 1  0        If A = $0010 (slot not available)

The slot number in the A register tells the Slot Arbiter what you are 
requesting.  Bits 0-2 are the slot number in the range 0 through 7.  Bit 3 is 
set if you are requesting an external slot and clear if you are requesting an 
internal port.  Taken together, bits 0-3 give slot numbers of $0-$7 for 
internal ports and $9-$F for external slots.  This is the same way that slot 
numbers are returned by the GS/OS DInfo command.

Bits 8 and 9 of the slot number indicate the action you wish the Slot Arbiter 
to take.  A value in these two bits of 00 asks the Slot Arbiter to switch in 
the slot identified in bits 0 through 3.  If both bits are set to 11, the Slot 
Arbiter restores all the slots to match the Bit Encoded Slot Configuration 
present in the X register.  Bit Encoded Slot Configurations are discussed in 
the next section of this Note.  Values other than 00 or 11 in bits 8 and 9 are 
reserved and must not be used by applications.

Bit 15 of the slot number is set if the slot selection has no slot 
dependencies.  When the Slot Arbiter is asked to switch in a slot with no slot 
dependencies, it does no actual switching, although it returns a Bit Encoded 
Slot Configuration in the X register.  The slot number and the definitions of 
the individual bits are illustrated in Figure 1.

     ___________________|___________
    |F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0|
    |_|_________|___|_______|_|_____|
     |     |      |     |    |   |___ Slot
     |     |      |     |    |_______ 0 = Internal; 1 = External
     |     |      |     |____________ Zero
     |     |      |__________________ Call Type Identifier
     |     |                            00 = Slot Request
     |     |                            11 = Select by Bit Encoded
     |     |                                 Slot Configuration
     |     |_________________________ Zero
     |_______________________________ Slot Dependent or Slot Independent

                  Figure 1-Slot Number and Bit Definitions

Bit Encoded Slot Configurations

Every call to the Slot Arbiter returns (on exit) a miniature picture of the 
slot configuration in the X register (as it was on entry).  This picture has 
one bit set for each of the 14 slots; if the bit is set, then the 
corresponding slot is switched in.  Bits 0 and 8 are reserved and are always 
clear.  This picture is called a Bit Encoded Slot Configuration.

Since each external slot has the same number as an internal port (with bit 3 
set), and since such pairs share the same address space, it follows that both 
of them may not be enabled at the same time.  For example, port 5 and slot 5 
($D) both may not be enabled.  This makes the high byte of the Bit Encoded 
Slot Configuration the eXclusive-OR of the low byte (excluding bits 0 and 8, 
which are always clear).  Figure 2 illustrates the Bit Encoded Slot 
Configuration.

             _______________________________
            |F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0|
             |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_ 0
             | | | | | | | | | | | | | | |___ 1 = slot 1 active
             | | | | | | | | | | | | | |_____ 1 = slot 2 active
             | | | | | | | | | | | | |_______ 1 = slot 3 active
             | | | | | | | | | | | |_________ 1 = slot 4 active
             | | | | | | | | | | |___________ 1 = slot 5 active
             | | | | | | | | | |_____________ 1 = slot 6 active
             | | | | | | | | |_______________ 1 = slot 7 active
             | | | | | | | |_________________ 0
             | | | | | | |___________________ 1 = slot 9 active
             | | | | | |_____________________ 1 = slot 10 active
             | | | | |_______________________ 1 = slot 11 active
             | | | |_________________________ 1 = slot 12 active
             | | |___________________________ 1 = slot 13 active
             | |_____________________________ 1 = slot 14 active
             |_______________________________ 1 = slot 15 active

                  Figure 2-Bit Encoded Slot Configuration

By fully using the slot number parameter, the Slot Arbiter returns any aspect 
of the current slot configuration.  Following are a few examples:

            Slot number    Action Taken by Slot Arbiter
            _________________________________________________________
            $8000          Returns current Bit Encoded Slot 
                           Configuration in the X register.  This 
                           number asks the Slot Arbiter to switch in 
                           with no slot dependencies (no switching), 
                           so it just returns the Bit Encoded Slot 
                           Configuration.
            $0300          Restore from Bit Encoded Slot 
                           Configuration.  This command, when paired 
                           with the one above, can be used to save 
                           and restore a slot environment.
            $0005          Asks the Slot Arbiter for internal port 5.
            _________________________________________________________


The Impact on Applications and Drivers

Applications which correctly do all input and output through GS/OS are 
affected by slot arbitration, except that they find more devices available.  
GS/OS uses the slot number parameter in the Device Information Block to call 
the Slot Arbiter, making sure the slot is available for the device before it 
gets control.  However, there are some applications (such as peripheral card 
configuration programs) which go directly to firmware or hardware, not using 
GS/OS.  Perhaps the card has no ROM, so there is no generated driver, or 
perhaps there is no loaded driver and the generated driver does not control 
certain aspects of the hardware.  In any case, such applications are directly 
impacted by slot arbitration.

Slot Searching

The first problem is finding the hardware.  In a 14-slot system, it's not 
suitable to just look for ID bytes between $C100 and $C700--two peripherals may 
be sharing each of those pages of slot ROM space.  Drivers must examine all 14 
slots, with the aid of the Slot Arbiter.  The following sample code 
demonstrates this technique:

find_slot          lda    #$8000           ; request current Bit Encoded Slot 
Configuration
                   jsl    slot_arbiter
                   phx                     ; save it on the stack

                   lda    #$000F           ; start with slot 15
                   sta    slot_number      ; be sure of the data bank when
                                           ; doing this!

slot_search        lda    slot_number      ; get the slot number to examine
                   jsl    slot_arbiter     ; and ask for it
                   bcs    continue_search  ; if an error, then don't look here
                   jsr    check_for_hw     ; this routine looks for your 
hardware
                   bcc    found_my_hw      ; if found it, we're done searching
continue_search    dec    slot_number      ; try the next lower slot
                   bpl    slot_search      ; (if there are any left, of course)

found_my_hw        plx                     ; get Bit Encoded Slot Configuration
                                           ; from stack
                   lda    #$0300           ; and tell the Slot Arbiter to 
                                           ; restore from it
                   jsl    slot_arbiter

; We're done.  Our slot number is in the location slot_number.

Note:  You must restore the previous slot configuration when 
       searching for a slot.  This is vital to device drivers during the 
       Drvr_Startup call, and failure to do so at other times may break 
       older, seven-slot applications.

The Slot Arbiter attempts to maintain a static seven-slot system for 
applications as reflected by the user's Control Panel settings.  This system 
allows older applications to continue to work, as something they find in an 
older, seven-slot scan is still present.  Newer applications may wish to 
consider implementing a 14-slot scan, but any slot not present in the static 
seven-slot environment requires a call to the Slot Arbiter before and after 
every access to that device.  The overhead in such instances may be 
intolerable.  Apple recommends that if an application requires hardware that 
cannot be found in a seven-slot scan, it request the user to set the Control 
Panel to make the hardware available and restart the system.

Using Slot-Dependent Hardware

Applications which have slot dependencies must call the Slot Arbiter before 
each use of the slot in question.  Since Slot Arbitration changes the 
environment to which Apple IIgs programs have become accustomed, everyone has 
a better chance of working by sticking to the general Apple IIgs rule of "put 
back what you use when you're done with it."  Ask for the slot, use it, then 
restore the previous Bit Encoded Slot Configuration.  (If you use multiple 
slots, you might wish to get the Bit Encoded Slot Configuration, save a copy, 
modify it to reflect the slots you want, and restore from the modified 
version.)

Note:  Peripherals accessed through GS/OS do not have to call the 
       Slot Arbiter; GS/OS handles this task automatically.

There are certain applications with more specialized needs, such as high-
speed, single character input or output.  In such cases, the Slot Arbiter may 
be a bottleneck.  When a slot is not switched, the Slot Arbiter returns 
quickly, but when a slot must be switched, it takes a significant amount of 
time.  Doubling that significant time for switching in and restoring gives a 
substantial overhead for each hardware access, which may be too much for some 
applications.

Note:  It is far better to write a GS/OS driver to deal with hardware 
       than to write a slot-dependent application to control it.  A slot-
       dependent application must deal with the Slot Arbiter, and the user must 
       quit the current application to run your application just to change some 
       aspect of the hardware.  Writing a GS/OS driver lets any application, 
       desk accessory, or CDev control your hardware with regular GS/OS calls.


Problems with Slot-Dependent Tools

Code designed before the Slot Arbiter may have slot-dependencies that cause 
unexpected problems when dynamic slot arbitration is fully implemented.  This 
list includes some of the Apple IIgs System Software.  Specifically, the Text 
Tools and the FWEntry call in the Miscellaneous Tools present problems with 
dynamic slot arbitration.

Text Tools

When using the Text Tools to specify a device for input, output, or error, the 
value specified (a four-byte parameter) is assumed to be a slot number if it 
is in the range 0-7.  The Text Tools were not designed to use Slot Arbiter-
style slot numbers, and this causes a compatibility problem.

The Text Tools were modified in System Software 5.0 to recognize Slot Arbiter-
style slot numbers where possible.  The trick is that it's not possible as 
often as we'd like.  External slots are specified by using slot numbers 9 
through 15; if such a slot number is used as input to a Text Tools call, the 
appropriate Slot Arbiter call is made and that external slot is used if it can 
be made available.  However, internal port numbers are in the range 1-7--the 
same range used by the old Text Tools to indicate which of two peripherals was 
switched in for a particular slot.  The Text Tools cannot assume that you are 
requesting an internal slot when using a slot number between one and seven.

For example, your old application might do a seven-slot search and find a 
parallel printer card in slot 1 (where the Control Panel setting for that slot 
is "Your Card").  If the Text Tools assumed all slot numbers in the range one 
through seven meant internal ports, your application would actually access the 
internal port 1 firmware every time it tried to access the parallel card it 
found in slot 1; this problem occurs since old applications don't know and 
don't care about internal or external slots.

The Text Tools may be used to access any external slot (if available), but 
they may only be used to access internal ports that are set to internal in the 
Control Panel.  The Text Tools slot numbers zero through seven always match 
the Control Panel settings.

Apple strongly recommends that the Text Tools not be used.  GS/OS character-
based drivers are preferable for standard character input and output.  The 
Text Tools may be used for specialized purposes; however, you cannot access 
some internal ports and other components of the system that are not well-
behaved.  Doing so could cause your application to trash memory or media.  You 
must assume these risks when using the Text Tools.

FWEntry

The Miscellaneous Tools call FWEntry should not be used to access entry points 
on a peripheral card (entry points in the $Cxxx range).  As discussed, a 
poorly-behaved routine could switch the slot from one you've identified to 
something else between the time you identify the slot and issue the FWEntry 
call.  Furthermore, the space between $C800 through $CFFF cannot be identified 
as belonging to any given slot, and the Slot Arbiter more or less guarantees 
that it won't be what you expect.  Accesses to peripheral card ROM space 
($Cxxx) should only be made by GS/OS drivers.  FWEntry must not be used to 
access $Cxxx addresses.

FWEntry is still safe to use for addresses in the $D000-$FFFF range.


Further Reference
_____________________________________________________________________________
  o  Apple IIGS Toolbox Reference, Volume 2
  o  Apple IIGS Firmware Reference
  o  Apple IIGS Hardware Reference
  o  GS/OS Reference
