Looking over the Apple II expansion card pinout, it seems it's largely just the pins of the 6502 plus some +12V supplies and such.
Yes, and no. The unique point about the Apple II bus is that basic address decoding is done externally to the card. This saves quite some circuitry.
Generally speaking, though, is there any reason any other 6502 machine, like the PET or Atari, couldn't have supported them?
No. it would need some glue logic for address decoding.
I suspect the memory mapped I/o would present a problem if it overlapped with other items in the machine's own libraries,
In fact, Woz' strategy to put decoding external removes the hardware side of that issue, as the needed external decoder logic would have to be made to cover this.
but that seems like something that could be corrected in the driver ROM, which one would expect would be different anyway.
Sure, driver/ROM code has to be replaced. Not just because of the address issues, but also for integration in the new environment. Each machine's BIOS and OS has it's own ways of integration for drivers, so usually it might best to drop ROM support and go with loadable drivers.
Am I missing anything special about the hardware that might make Apple II cards difficult to use on other platforms?
It may only go tricky when a card going for real deep integrated function like taking over the bus like with a CPU card. Or for example cards snooping the bus to capture things like screen data or certain system setup (softswitches). But then again, adapting such special cards between systems are always tricky.
For instance, did the motherboard have specific interfacing hardware like latching or such that would have to be implemented to make it work? Or it is, as it appears, just a bunch of pins and a driver?
It's a bunch of pins and drivers - plus address decoding. Apple II cards expect
- A 16 byte address window accessed with
/DEVICE-SELECT
and A0..A3, used for I/O registers.
- A 256 byte address window accessed with
/IO-SELECT
and A0..A7, usually holding the promary driver and all entry points. Some cards use it as well for RAM or registers. This is usually called 'PROM' space.
- A 2048 byte address window accessed with
/IO-STROBE
and A0..A10, usually this holds the main driver ROM. But it has as well be used for RAM windows.
While the first two are reserved for each card at fixed addresses, the last one is shared between cards. The protocol is rather simple and all hardware needed is on the card and handled by drivers (*1).
So after adding address decoding, according to whatever system you have, a good number of Apple cards should work right away - sans driver that is.
The next level would be to check if RDY handling for DMA is possible. On the Apple II pulling RDY from the card during PHI1 will put the CPU on hold (like with any 6502 system) but as well decouple it from the bus, allowing the Card to put out a memory address of it's own. Ofc, this will be hard to archive on machines that are unable free up the bus.
Everything after that will be rather extreme Apple II specific and more about the inner workings of the II series, not really worth to be supported.
*1 - All cards have to disable their ROM as soon as an access to the top address in ROM space is detected. That's /IO-STROBE
plus A0..A10 all high ($CFFF when decoded like in an Apple II). Some cards only decode that partitialy, ignoring the lower value addresses. That's fine, as long as the top most address is included.
Hardware wise ROM enable/disable is usually done (on card) by a simple flipflop. /IO-SELECT
is simple wired up to set it, while /IO-STROBE
+ A3..A10 will reset it. As a result, every time code is executed within PROM space the ROM is paged in. Now a single BIT (or alike) instruction is all that's needed to disable all, as the next instruction will again enable the own ROM. I always liked the elegance. No lengthy loading of values and port handling to swap between ROMS. Instant and automatic.