
PC-CARDs and the Amiga

 For those of you who might want to write drivers for PC-CARDs, here are
 some things I have found out about them.

 Most cards are designed to be set up to look like an ISA bus card, which is
 what the peecee needs for software compatibility.

 As PCMCIA is quite different from ISA, the peecee has a controller chip
 (PCIC) which can be programmed to translate from one bus to the other.
 Using the PCIC, the PCMCIA memory can be mapped into the I/O and memory
 space expected by an ISA card. Also the INT line is routed to one the ISA
 interrupts. Once this setup has been done, the card would be accessed as if
 it were a standard ISA bus card.

 Since the Amiga does not have a PCIC, we can access the memory and I/O
 space directly. The single IRQ is handled for us by card.resource, we
 merely have to provide a routine to run when the interrupt occurs.

 It may be necessary to access odd I/O register locations at a different
 address range from the even registers. Apparently this allows the card
 to respond to byte accesses. A typical Amiga memory map for PCMCIA looks
 like this:-

 $600000 - $9fffff  RAM (may be a mirror of attribute memory for I/O cards)
 $a00000 - $a1ffff  attribute memory
 $a20000 - $a2ffff  I/O space (16bit and even 8bit registers)
 $a30000 - $a3ffff  I/O space (odd 8bit registers)

 If the PC-Card's registers were at the ISA I/O addresses of $0300 and $0301,
 8bit access would appear in the Amiga at locations $a20300 ($0300) and
 $a30300 ($0301). For 16bit access, both bytes would appear at $a20300/1.
 Note that the Amiga PCMCIA slot has its data bus wires swapped to account
 for INTEL's backward byte order.

 In order to enable I/O access, the card may need to be programmed by first
 writing to the Card Configuration Register in attribute memory. The location
 of this register can be determined by examining the CONFIGMAP tuple. The
 value to write into the CCR is called the ConfigurationID, which can be
 extracted from any CONFIG tuple. Multiple CONFIG tuples may exist, which
 usually relate to different I/O addresses.

 Once you have gathered enough infomation on the card's hardware features,
 you will want to write a program to control it. This will involve use of
 card.resource functions, so it is a good idea to read the docs on this
 (available on the Amiga Developer CD). At a minimum, you will need to call
 the functions OwnCard (to set up the interrupt) and CardMiscControl (to
 enable I/O addressing).


Interrupt Handling

 The Cnet card generates a standard level-sensitive interrupt. However Gayle
 (the custom chip that controls the PCMCIA port) responds to interrupts on
 negative and positive edges only. Since the card.resource resets Gayle's
 interrupt latch after your status interrupt routine finishes, there is a
 small but critical period of time where an interrupt could be missed. The
 result is that the PCMCIA card could be holding its INT line down expecting
 service, but Gayle ignores it because the negative transition occurred
 before her interrupt latch was reset.

 Commodore's recommended workaround for this is to add another PORTS
 interrupt server, whose sole job is to make sure that card interrupts
 are not enabled until after the status change interrupt has completed
 (after card.resource has reset the Gayle interrupt latch). This ensures
 that the next downwards transition on the PCMCIA INT line gets detected.

 For V39 of card.resource a new method was provided, where by setting a flag
 'CARDB_POSTSTATUS' your status interrupt would be called twice, the second
 time would occur after Gayle had been reset. Unfortantely V39 card.resource
 did not make it into the Kickstart 3.0 ROMS, so this is not an option for
 most A1200s and A600s. However 'CARDB_POSTSTATUS' should be used if V39+
 card.resource is available (Kickstart 3.1 has V40 card.resource).
