To avoid collisions, you moved physical jumpers on cards that might conflict, to select among a small range of addresses, I/O ports and/or select IRQs.<p>For example if you had two identical network cards, or SCSI disk controllers, you would need to physically reconfigure one of them away from its defaults.<p>There were only a small number of configurations available on each type of device, and some weren't configurable at all, so you could still get irreconcilable conflicts.<p>The Linux kernel of the time was full of hard-coded "probe" addresses and I/O ports, probe sequences to see if there was a device there, and IRQ auto-detection routines that triggered an interrupt to find out which IRQ line was asserted. Some of the probes had to be run in a particular order, so that probes for one type of device wouldn't break another type.<p>Later came ISAPnP, meaning Plug'n'Play for ISA, which allowed the operating system to use a clever protocol to talk simultaneously over ISA with all devices on the bus that support it, identify and select them individually, query what they required and and configure their addresses, I/O ports and IRQs to avoid overlap, or permit overlap where it was ok for IRQs. After the operating system was done configuring them, they operated as if they were configured physically like the older ISA cards. If necessary this could be implemented cheaply by adding an ISAPnP module to an existing ISA card design.<p>Eventually ISA was superceded by PCI which had better, well-defined enumeration and configuration methods from the start which all devices had to implement. PCI also allowed MMIO and IO base addresses to be set anywhere in (32-bit), not just a small number or single option as ISA cards usually had, so there were no more address conflicts. The operating system still had to find the PCI configuration registers itself, but after that, probing was simpler and more reliable than with ISA.<p>USB also arrived around the same time, and also had well-defined enumeration and configuration methods. Many simpler ISA devices were replaced by equivalent USB devices. Although USB was (and is) complex to implement at a low level, the complexity was handled very well be low-cost, generic USB modules on the device side, so it was easy for device manufacturers to use.