public class PCI {	
	static int   ECD	= 0x80000000;					// Enable Config. Data
	static int   CFGADR	= 1;							// Typ in CFA
	static short CFA	= 0xCF8;						// Config. Address
	static short CFD	= 0xCFC;						// Config. Data


	public static void scanBus() {
		int b,d,f;										// counters: bus, device, function
		int result,func;
		int classID,deviceID,vendorID;					// info
		int intLine;									// info

		for(b=0; b<256; b++) {							// bus number 
			for(d=0; d<32; d++) {						// devices on bus
				// Bit-7 of Header-Type: 0=single function; 1=multiple function
				// (restl. Bits definieren weiteres Format: 00=Skript & 01=PCI-to-PCI Bridge)
				if ((ReadConfig(b,d,0,0xC)&0x800000)!=0)// read dword at 0xC
					func=8;								// max. 8 funcs.
				else									 
					func=1;								// min. 1 func.
					
				for (f=0; f<func; f++) {				// Fkt. bei Multifunktionsgeräten
					result = ReadConfig(b,d,f,0);		// read dword at 0
					if (result!=0 && result!=-1) {
						vendorID = result&0xFFFF;
						deviceID = (result>>16)&0xFFFF;

						result   = ReadConfig(b,d,f,8);	// read dword at 8
						classID  = (result>>24)&0xFF;	

						intLine	 = ReadConfig(b,d,f,0x3C);// read dword at 0x3C 
						intLine  &= 0xFF;				// first 8-Bit INT nr.

						printInfo(vendorID,classID,deviceID,intLine);
					}
				}
			}
		}			  		
		  		
	}
	
	private static void printInfo(int vendorID, int classID, int deviceID, int intLine) {
		StaticDisplay.print("vendorID: ");   StaticDisplay.printHex(vendorID); 
		StaticDisplay.print(", classID:  "); StaticDisplay.printHex(classID);  
		StaticDisplay.print(", deviceID: "); StaticDisplay.printHex(deviceID); 
		StaticDisplay.print(", intLine:  "); StaticDisplay.printHex(intLine);  StaticDisplay.println();		
	}

	public static int ReadConfig(int bus,int device,int function, int register) {
		int addr, orig, value;

		addr = ECD |((bus&0xFF)<<16) |((device&0x1F)<<11) |((function&7)<<8) |(register&0xFC) | CFGADR ;

		orig = MAGIC.In32((short)CFA);			// read & save CFA
 		MAGIC.Out32((short)CFA,addr) ;			// set CFA
 		value= MAGIC.In32((short)CFD);			// read CFD
 		MAGIC.Out32((short)CFA,orig) ;			// restore CFA
		return value;
	}
}
