/* */#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>/* * Mac specific includes */#include <NameRegistry.h>#include <Pci.h>#include <Gestalt.h>#include <Timer.h>#include <DriverServices.h>/* * macraigor systems PCI card registers */typedef struct pciRegs {	unsigned char  cmdStat;			/* Command / Status Register */	unsigned char  ___0;	unsigned char  gpOut;			/* GP Output Register */	unsigned char  ___1;	unsigned char  IOLow;			/* Holding Register 0-7, input shift register */	unsigned short TMSReg;			/* TMS Register */	unsigned short ___2;	unsigned short ___3;	unsigned short ___4;	unsigned char  IOHi;			/* Holding Register 8-15 */} pciRegs;void findPCICard(char *name);void Jtag_OSDelay(int waitTime);	/* miliseconds */void usDelay(int waitTime);unsigned long swapEndian(unsigned long val);void readConfigEE(unsigned long adr);volatile pciRegs *regPtr = 0;int jtagError = 0;char *failedRoutineName;unsigned long		aaplAdrs[8];RegPropertyValueSize	adrSize = sizeof(aaplAdrs);char					slotName[32];RegPropertyValueSize	nameSize = sizeof(slotName);unsigned long		assignedAdrs[8][5];RegPropertyValueSize	assignedAdrsSize = sizeof(assignedAdrs);unsigned long		regAdrs[8][5];RegPropertyValueSize	regAdrsSize = sizeof(regAdrs);char	*CardNames[]  = {   "pci1c1c,1",		/* winbond (really broken IDE)*/							"pci907f,2015", 	/* ATronics 2015 (sort of broken IDE)*/							"pci10ad,105",		/* Cujo (bus master IDE) */							"pci10b5,9050",		/* PLX Eval board */							"pci131f,1034",		/* SIIG 2S 1P */							"pci121f,1020",		/* SIIG 1P (plx9052) */							"pcid84d,6811",		/* Dolphin 1P */							"pcifde5,7", 		/* Frontier Designs (PLX9050if) */							"pci152c,1",		/* Macgraigor PCI JTAG card */							"pci10b5,1",		/* MCT-P1P-E */							""						};unsigned char stateChg[12] = {	0b0000, 0b1000, 0b0000, 0b0100, 0b0000, 0b0000,								0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b1000 };volatile unsigned char * LPT0Adr;#define LPD	LPT0Adr#define LPS LPT0Adr+1#define LPC LPT0Adr+2/* LPS */#define PSYN	0x01#define PD0		0x2/* LPC */#define AD3		0x80#define AD2		0x40#define AD1		0x20#define AD0		0x10#define ASYN	0x08#define ADMASK	0xf0#define ADSHIFT	4#define NBLOCK (1+2+8+256)short block[NBLOCK];void outport(volatile unsigned char *adr, unsigned char data);unsigned char inport(volatile unsigned char *adr);void getblock();void getinsync();int getword();void main(void){	 int i;	 int bno;		 unsigned long configAdr;	 	 unsigned clkCnt = 0;	 unsigned char clkShadow = 0;	 FILE *fp;	 	for(i=0; CardNames[i][0] != '\0'; i++){	 findPCICard(CardNames[i]);	 if(!jtagError) goto foundOne;	}	printf("didn't find a known card\n");	exit(1);	foundOne:	 printf("%s = %s\n",slotName, CardNames[i]);	 	 printf("Slot %s, adrs %x %x %x %x %x %x\n", slotName, aaplAdrs[0], aaplAdrs[1], aaplAdrs[2], aaplAdrs[3], aaplAdrs[4], aaplAdrs[5]);	for(i=0; i<8; i++)		 printf("reg %d  %08x,%08x,%08x,%08x,%08x\n", i, regAdrs[i][0],regAdrs[i][1],regAdrs[i][2],regAdrs[i][3],regAdrs[i][4]);	for(i=0; i<8; i++)		 printf("assigned adrs %d %08x,%08x,%08x,%08x,%08x\n", i, assignedAdrs[i][0],assignedAdrs[i][1],assignedAdrs[i][2],assignedAdrs[i][3],assignedAdrs[i][4]);/*	for(j=0; j<8; j++){		printf("Adr space %d: 0x%08x\n",j ,aaplAdrs[j]);		for(i=0, p = (unsigned char *)aaplAdrs[0]; i<16; i++)		 printf("%02x ", *p++);		printf("\n");	}*/	/*	 * find memory mapped config space	 */	 configAdr  = 0;	 for(i=0; i<8; i++){	  if((assignedAdrs[i][0] & 0xff0000ff) == 0x82000010){	   configAdr = aaplAdrs[i];	   break;	  }	 }	 printf("Config Adr = %08x\n", configAdr);	 	 if(configAdr){		readConfigEE(configAdr);	 }	 LPT0Adr = 0;	 for(i=0; i<8; i++){	  if((assignedAdrs[i][0] & 0xff0000ff) == 0x81000020){	/* IO Mapped Parallel Port */	   LPT0Adr = (volatile unsigned char *)aaplAdrs[i];	   break;	  }	 }	 printf("LPT0 Adr = %08x\n", LPT0Adr);	 	 if(!LPT0Adr) exit(1);	fp = fopen("alto.dsk", "wb");	if (fp == 0) { printf("Can't open alto.dsk\n"); exit(1); }	printf("Calling getinsync()\n"); fflush(stdout);		getinsync();	for (bno = 0; bno < 4872; ++bno) {		printf("Block %d ...\n", bno); fflush(stdout);		getblock();		if (block[0] != bno) {			printf("Wrong block, gto %d\n", bno);			exit(1);		}		if (fwrite((char *)block, sizeof(short), NBLOCK, fp) != NBLOCK) {			printf("Write error\n");			exit(1);		}	}	fclose(fp);	}void outport(volatile unsigned char *adr, unsigned char data){	*adr = data;}unsigned char inport(volatile unsigned char *adr){	return(*adr);}void getblock(){	int	s;	int	d;	int	i;	d = getword();	if (d != 20000) {		printf("Bad seal, got %04x %d\n", d, d);		exit(1);	}	s = d;	for (i=0; i<NBLOCK; ++i) {		d = getword();		block[i] = d;		s += d;	}	s &= 0xffff;		d = getword();	if (d != s) {		printf("Bad checksum, %04x %04x\n", s, d);		exit(1);	}}void getinsync(){	outport(LPD, 0xFF);	outport(LPC, 0x00);	while ((inport(LPS)&ASYN) != 0)		;}int getword(){	int	i;	int	d;	int	a;	int	p;	unsigned char invalue;	a = ASYN;	p = PSYN;	d = 0;	for (i=0; i<16; i+=4) {		while ((inport(LPS)&ASYN) != a)			;		while ((inport(LPS)&ASYN) != a)			;		while ((inport(LPS)&ASYN) != a)			;		while ((inport(LPS)&ASYN) != a)			;		while ((inport(LPS)&ASYN) != a)			;		a ^= ASYN;				invalue = inport(LPS);				d |= ((invalue & ADMASK) >>ADSHIFT) << i;				outport(LPC, p);				p ^= PSYN;	}	return (d);}unsigned short eeBuffer[256];#define D0 0x4#define CS 0x2#define CK 0x1unsigned char	readCmd[] = {		CS, 		CS, 	D0|CS,		D0|CS|CK,	D0|CS,	D0|CS, 		CS|CK, 		CS,		CS,		CS|CK, 		CS,		CS,		CS|CK, 		CS,		CS,		CS|CK, 		CS,		CS,		CS|CK, 		CS,		CS,		CS|CK, 		CS,		CS,		CS|CK, 		CS,		CS,		CS|CK, 		CS,		CS,		CS|CK,		CS,		CS,		CS|CK, 		CS,		CS};void readConfigEE(unsigned long adr){	volatile char *p = (volatile char *)(adr + 0x53);			/* point to ee access reg */	int i, j;	unsigned short inp = 0;	for(i=0; i<33; i++){	 asm(eieio);	 *p = readCmd[i];	}	 	for(i=0; i<64; i++){		for(j=0; j<16; j++){			*p = CS;										/* lower ck */			asm(eieio);			inp = (inp << 1) | ((*p & 0x8) >> 3);			/* read a bit */			asm(eieio);			*p = CS|CK;										/* raise ck */			asm(eieio);			*p = CS|CK;										/* raise ck */			asm(eieio);			*p = CS;										/* lower ck */			asm(eieio);			*p = CS;										/* two ticks */			asm(eieio);		}		printf("%04x ", inp);		if(((i+1) % 16) == 0) printf("\n"); 		eeBuffer[i] = inp;	}	*p = 0x20;												/* negate CS and clock */}unsigned long swapEndian(unsigned long val){	return __lwbrx( &val, 0 );}/* * try to find the PCI JTAG card, and return the register base * adr */void findPCICard(char *name){	OSErr					err;	long 					result;	RegEntryID				entry;	RegEntryIter			iter;	Boolean 				done = false;	RegEntryIterationOp		iterOp = kRegIterDescendants;	int						i,j;	unsigned long			val, sav;	/*	 * Check that this is a PCI Mac	 */	if(Gestalt( gestaltNameRegistryVersion, &result) != noErr) goto fail;	RegistryEntryIDInit(&entry);	if(RegistryEntryIterateCreate( &iter ) != noErr) goto fail;	/*	 * search the name registry for a PCI card with the correct vendor ID	 */	err = RegistryEntrySearch(&iter, iterOp, &entry, &done, "name", name, strlen(name)+1);		if(err != noErr) goto fail;	RegistryEntryIterateDispose(&iter);	err = RegistryPropertyGet(&entry, "assigned-addresses", (void *)&assignedAdrs, &assignedAdrsSize);	if(err != noErr) goto fail;	err = RegistryPropertyGet(&entry, "reg", (void *)&regAdrs, &regAdrsSize);	if(err != noErr) goto fail;	err = RegistryPropertyGet(&entry, "AAPL,address", (void *)&aaplAdrs, &adrSize);	if(err != noErr) goto fail;	err = RegistryPropertyGet(&entry, "AAPL,slot-name", (void *)&slotName, &nameSize);	if(err != noErr) goto fail;	/*	 * card was found, enable I/O and memory space access in PCI config reg at offset 4	 */	err = ExpMgrConfigReadLong(&entry, (LogicalAddress)4, &val);	val |= 3;	err = ExpMgrConfigWriteWord(&entry, (LogicalAddress)4, val);	if(err != noErr) goto fail;	printf("Config Space\n");	for(j=0; j<128; j+=4){	 		err = ExpMgrConfigReadLong(&entry, (void *)j, &val);			if((j % 16) == 0) printf("\n");	 		printf("%08x ", val); fflush(stdout);	}	printf("\n\n");printf("--\n");	 for(i=0; i<6; i++){	  err = ExpMgrConfigReadLong(&entry, (void *)((i*4)+0x10), &sav);	  err = ExpMgrConfigWriteLong(&entry, (void *)((i*4)+0x10), 0xffffffff);	  err = ExpMgrConfigReadLong(&entry, (void *)((i*4)+0x10), &val);	  err = ExpMgrConfigWriteLong(&entry, (void *)((i*4)+0x10), sav);	  printf("%08x = %08x\n",((i*4)+0x10), val); fflush(stdout);	 }	  err = ExpMgrConfigReadLong(&entry, (void *)(0x30), &sav);	  err = ExpMgrConfigWriteLong(&entry, (void *)(0x30), 0xffffffff);	  err = ExpMgrConfigReadLong(&entry, (void *)(0x30), &val);	  err = ExpMgrConfigWriteLong(&entry, (void *)(0x30), sav);	  printf("%08x = %08x (config)\n",0x30, val);printf("--\n");		jtagError = 0;	return;fail:	jtagError = 1;	return;}static long longprimeTimeoutTime(int timeout){	UnsignedWide currentTime;	long long theTime;	Microseconds(&currentTime);	theTime = ((currentTime.hi  << 32) | currentTime.lo) + timeout;	return theTime;}static long longcurrentTime(void){	UnsignedWide currentTime;	Microseconds(&currentTime);	return((currentTime.hi << 32) | currentTime.lo);}static voidcsrTimeout(char *rtn){	failedRoutineName = rtn;	jtagError = 1;}/* * Macintosh specific delay() routine */ void Jtag_OSDelay( int waitTime ) {	AbsoluteTime	startTime, currentDelta;	Duration		delta;		/* get the start time */	startTime = UpTime();		do {		/* get the delta absolute time from the start time */		currentDelta = SubAbsoluteFromAbsolute( UpTime(), startTime );				/* convert the delta into micro/milli seconds */		delta = AbsoluteToDuration( currentDelta );				/* if we got microseconds, convert to milliseconds */		if ( delta < 0 )			delta /= -1000;					} while( delta < waitTime );}void usDelay( int waitTime ){	AbsoluteTime	startTime, currentDelta;	Duration		delta;		/* get the start time */	startTime = UpTime();		do {		/* get the delta absolute time from the start time */		currentDelta = SubAbsoluteFromAbsolute( UpTime(), startTime );				/* convert the delta into micro/milli seconds */		delta = AbsoluteToDuration( currentDelta );				/* at this rate we shouldnt get microseconds, but we'll check for them anyways */		if ( delta > 0 )			delta *= 1000;		else			delta = -delta;					} while( delta < waitTime );}