#include #include #include #include #include #include #include "univiflib.h" #define CONSOLE int uiflib_debug=0; char uif_error[1024]={'\0'}; int GIVEIO=0; #ifndef __CWD__ #define __CWD__ "D:\\home\\kumagai\\VC\\univif" #endif static char *TTFSearchPath=";"__CWD__"\\ttf\\"; // 情報格納 UNIV_IF_BaseAddress baseAddress[UNIV_IF_MaxID]; // ====================================================================== // コンフィグレーションアクセス関数 int TargetBaseAddress=0x0; const byte CONF_DONE=0x01; const byte nSTATUS =0x02; const byte INIT_DONE=0x04; const byte LOOPBACK =0x08; const byte nCONFIG =0x01; const byte DCLK =0x02; const byte DATA =0x04; const byte LOOPBACKV2 =0x08; const byte LOOPBACKV3 =0x10; static byte cur=0xff; inline void H(byte mask) { cur |= mask; outb(cur,TargetBaseAddress+0xfe); } inline void L(byte mask) { cur &= ~mask; outb(cur,TargetBaseAddress+0xfe); } inline int ISH(byte mask) { return inb(TargetBaseAddress+0xfe)&mask; } inline int ISL(byte mask) { return !ISH(mask); } static int CheckLoopBackV2(void) { H(LOOPBACKV2); if(!ISH(LOOPBACK)) return 1; L(LOOPBACKV2); if(!ISL(LOOPBACK)) return 2; return 0; } static int CheckLoopBackV3(void) { H(LOOPBACKV3); if(!ISH(LOOPBACK)) return 1; L(LOOPBACKV3); if(!ISL(LOOPBACK)) return 2; return 0; } static int CheckLoopBack(void) { if((CheckLoopBackV2()==0)|| (CheckLoopBackV3()==0)) return 0; return -1; } inline int GetUIFVersion(void) { int v=0; if(CheckLoopBackV2()==0) v=2; if(CheckLoopBackV3()==0) v=3; return v; } inline int GetBSN(void) { int vofs=0; if(GetUIFVersion()==3) vofs=16; return ((inb(TargetBaseAddress+0xfe) >> 4)&0xf)+vofs; } // ====================================================================== // ボード検索 static int InitializeIO(int disp=1) { static int Init_IO=10; if(Init_IO<10) return Init_IO; _fmode=_O_BINARY; // ファイルは原則バイナリモードで int status=getdllstatus(); if(status!=DLLSTATUS_NOERROR) { sprintf(uif_error,"Cannot use DLL for PCI access (%d)",status); #ifdef CONSOLE fprintf(stderr,"%s\n",uif_error); #endif Init_IO=-1; return Init_IO; } HANDLE hgiveio; hgiveio = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hgiveio == INVALID_HANDLE_VALUE) { #ifdef CONSOLE if(uiflib_debug) printf("Cannot use GiveIO.sys. I'll use PDB functions(will be slow)\n"); #endif } else { GIVEIO=1; CloseHandle(hgiveio); } Init_IO=0; return Init_IO; } static int CheckUNIVIFOperation(void) { int i; int baseaddr,ctrladdr,bsn; static int have_checked=0; if(have_checked) return 0; if(InitializeIO()) { return 1; } for(i=0;i> 8) & 0xff; int dev=(busdevfn >> 3) & 0x1f; int fn= (busdevfn >> 0) & 0x07; #ifdef CONSOLE if(uiflib_debug) printf("found Universal IF at %d:%d:%d ",bus,dev,fn); #endif base0=(_pciConfigReadLong(busdevfn, 0x10))&(~3); // BASE0 base1=(_pciConfigReadLong(busdevfn, 0x14))&(~3); // BASE1 / IO base2=(_pciConfigReadLong(busdevfn, 0x18))&(~0xf); // BASE2 / MEM ctrladdr=base0; baseaddr=base1; #ifdef CONSOLE if(uiflib_debug) printf("BASE:%04X ",base1); #endif // ループバックチェック TargetBaseAddress=baseaddr; if(CheckLoopBack()) { sprintf(uif_error," Loopback check failed(%d)",CheckLoopBack()); #ifdef CONSOLE fprintf(stderr,"%s\n",uif_error); #endif continue; } bsn=GetBSN(); #ifdef CONSOLE if(uiflib_debug) printf(" BSN: % 2X\n",bsn); #endif baseAddress[bsn].ctladdr=ctrladdr; baseAddress[bsn].ioaddr=baseaddr; baseAddress[bsn].busdevfn=(word)busdevfn; baseAddress[bsn].version=GetUIFVersion(); baseAddress[bsn].device=UnivIFReadEEPROM(bsn,0x30); } return 0; } // ====================================================================== // FLEX コンフィグレーション関数 static int StartConfiguration(void) { int i; H(nCONFIG); L(DCLK); L(DATA); L(nCONFIG); for(i=0;i<1000;i++) if((ISL(nSTATUS))&&(ISL(CONF_DONE))) break; #ifdef CONSOLE if(uiflib_debug) printf(">> device start-up-time %d\n",i); #endif //CONSOLE if(i==1000) { strcpy(uif_error,"Start Condition Error(1)"); #ifdef CONSOLE fprintf(stderr,"%s\n",uif_error); #endif //CONSOLE return 1; } H(nCONFIG); for(i=0;i<1000;i++) if(ISH(nSTATUS)) break; #ifdef CONSOLE if(uiflib_debug) printf(">> device boot-up-time %d\n",i); #endif if(i==1000) { strcpy(uif_error,"Start Condition Error(2)"); #ifdef CONSOLE fprintf(stderr,"%s\n",uif_error); #endif //CONSOLE return 1; } return 0; } inline void SendBit(int bit) { if(bit) H(DATA); else L(DATA); H(DCLK); L(DCLK); } static int SendByte(byte b) { int i; for(i=0;i<8;i++) { SendBit(b&1); b=b>>1; if(ISL(nSTATUS)) return -1-i; } return 0; } static int SendData(byte *data,int length) { int i,r,ost=-1; for(i=0;i> device status changed %02X at %d\n",ost,i); #endif //CONSOLE } } for(i=0;i<1000;i++) if(ISH(CONF_DONE)) break; #ifdef CONSOLE if(uiflib_debug) printf(">> device configuration-finish-time %d\n",i); #endif //CONSOLE if(i==1000) { strcpy(uif_error,"Configuration Error(1)"); #ifdef CONSOLE fprintf(stderr,"%s\n",uif_error); #endif //CONSOLE return 1; } return 0; } static byte *LoadTTF(const char *filename,int &length) { struct stat st; if(stat(filename,&st)<0) { sprintf(uif_error,"LoadTTF: stat error '%s.500'",filename); #ifdef CONSOLE fprintf(stderr,"%s\n",uif_error); #endif //CONSOLE return NULL; } int size=st.st_size; byte *r=new byte[size]; length=0; FILE *fp; fp=fopen(filename,"r"); if(fp==NULL) { sprintf(uif_error,"LoadTTF: cannot open %.500s",filename); #ifdef CONSOLE fprintf(stderr,"%s\n",uif_error); #endif //CONSOLE return NULL; } char buff[1024]; while(fgets(buff,1024,fp)) { while(strlen(buff)>0) if(strchr("\r\n",buff[strlen(buff)-1])) buff[strlen(buff)-1]='\0'; else break; char *it; for(it=buff ; *it ; it+=4) { if(it[3]=='\0') { it[3]=','; it[4]='\0'; } // 最終数値 if((strchr(" 0123456789",it[0])==NULL) || (strchr(" 0123456789",it[1])==NULL) || (strchr("0123456789",it[2])==NULL) || (it[3]!=',')) { sprintf(uif_error,"LoadTTF: Illegal Line in %.500s\n>>%s",filename,buff); #ifdef CONSOLE fprintf(stderr,"%s\n",uif_error); #endif //CONSOLE delete r; return NULL; } r[length]=atoi(it); //printf("%3d,",r[length]); // debug length++; } //printf("\r\n"); // debug } fclose(fp); return r; } static int SetBSN(int bsn) { CheckUNIVIFOperation(); if((bsn>=0)&&(baseAddress[bsn].ioaddr==0)) { sprintf(uif_error,"Error: There is no device BSN:0x%X",bsn); #ifdef CONSOLE fprintf(stderr,"%s\n\n",uif_error); #endif //CONSOLE return -1; } else TargetBaseAddress=baseAddress[bsn].ioaddr; #ifdef CONSOLE if(uiflib_debug) printf("Target Base Address:%04X\n", TargetBaseAddress); #endif //CONSOLE return bsn; } /*static char *SearchFile(const char *filename, int device=6024) { char *work=new char[strlen(TTFSearchPath)+strlen(filename)]; char *p,*q; struct stat st; p=TTFSearchPath; while(*p) { strcpy(work,p); if((q=strchr(work,';'))!=NULL) { *q='\0'; } if((q=strchr(p,';'))!=NULL) { p=q+1; } else { p=p+strlen(p); } strcat(work,filename); if(stat(work,&st)==0) return work; } return NULL; }*/ static char *SearchFile(const char *filename,int device=6024) { char *dir=new char[strlen(TTFSearchPath)+2]; char *work=new char[strlen(TTFSearchPath)+strlen(filename)+20]; char *p,*q; struct stat st; p=TTFSearchPath; while(*p) { strcpy(dir,p); if((q=strchr(dir,';'))!=NULL) { *q='\0'; } if((q=strchr(p,';'))!=NULL) { p=q+1; } else { p=p+strlen(p); } sprintf(work,"%s%d\\%s",dir,device,filename); #ifdef CONSOLE if(uiflib_debug) printf("Try %s\n",work); #endif if(stat(work,&st)==0) { delete[] dir; return work; } sprintf(work,"%s%s",dir,filename); #ifdef CONSOLE if(uiflib_debug) printf("Try %s\n",work); #endif if(stat(work,&st)==0) { delete[] dir; return work; } } delete[] dir; delete[] work; return NULL; } #ifdef CONSOLE void DumpDeviceList(void) { CheckUNIVIFOperation(); int i; printf("UNIV-IF device list\n"); for(i=0;i> 8, (baseAddress[i].busdevfn >> 3) & 0x1f, baseAddress[i].busdevfn & 0x7, baseAddress[i].ioaddr); } puts(""); } #else void DumpDeviceList(void) { // nothing can do with this function without console } #endif int ConfigureUNIVIF(int bsn,const char *ttfile) { if(SetBSN(bsn)<0) return 9; // あとでまじめに int device; if(baseAddress[bsn].device!=65535) device=baseAddress[bsn].device; else { if((bsn&0xf0)==0x00) device=6024; // Ver2 if((bsn&0xf0)==0x10) device=10030; // Ver3 } char *realfile=SearchFile(ttfile,device); if(realfile==NULL) { return 10; } byte *data; int length; data=LoadTTF(realfile,length); if(data==NULL) return 10; #ifdef CONSOLE if(uiflib_debug) printf("loaded %d bytes from '%s'\nStart configuration to BSN:0x%X\n\n", length,realfile,bsn); #endif // CONSOLE if(StartConfiguration()) return 11; if(SendData(data,length)) L(nCONFIG); // デバイスdisable #ifdef CONSOLE if(uiflib_debug) printf("\n Configuration is successfully done to UNIV-IF(BSN 0x%X)\n\n",bsn); #endif //CONSOLE return 0; } int DisableUNIVIF(int bsn) { if(SetBSN(bsn)<0) return 9; if(StartConfiguration()) return 11; L(nCONFIG); // デバイスdisable return 0; } int GetUNIVIFBaseAddress(int bsn) { CheckUNIVIFOperation(); if((bsn>=0)&&(baseAddress[bsn].ioaddr==0)) { return -1; } else return baseAddress[bsn].ioaddr; } // =================================================================== // UnivIF EEPROM アクセス static unsigned short CtlAddr=0; void WriteVirtualb(int addr,unsigned char b) { outl(addr & ~3,CtlAddr+8); outb(b,CtlAddr+12+(addr&3)); } unsigned char ReadVirtualb(int addr) { outl(addr & ~3,CtlAddr+8); return inb(CtlAddr+12+(addr&3)); } inline void EECSH(void) { WriteVirtualb(0, (ReadVirtualb(0)&0x5)|2); } inline void EECSL(void) { WriteVirtualb(0, (ReadVirtualb(0)&0x5)|0); } inline void EECLKH(void) { WriteVirtualb(0, (ReadVirtualb(0)&0x6)|1); } inline void EECLKL(void) { WriteVirtualb(0, (ReadVirtualb(0)&0x6)|0); } inline void EEDIH(void) { WriteVirtualb(0, (ReadVirtualb(0)&0x3)|4); } inline void EEDIL(void) { WriteVirtualb(0, (ReadVirtualb(0)&0x3)|0); } inline int EEDO(void) { return ReadVirtualb(0)&0x8; } static void EESendCommand(int command) { int i; EECSL(); EECLKL(); EEDIL(); // スタート EECSH(); EEDIH(); EECLKH(); EECLKL(); // 1 // コマンド送信 for(i=0;i<8;i++) { if(command & 0x80) EEDIH(); else EEDIL(); command <<= 1; EECLKH(); EECLKL(); } EECSL(); EEDIL(); } static void EEWaitBusy(void) { EECSH(); EECSH(); EECSH(); while(!EEDO()) ; EECSL(); } inline void EEWriteEnable(void) { EESendCommand(0x30); } inline void EEWriteDisable(void) { EESendCommand(0x00); } void UnivIFWriteEEPROM(int bsn, word addr,word val) { CheckUNIVIFOperation(); if((bsn>=0)&&(baseAddress[bsn].ctladdr==0)) { fprintf(stderr,"Error: There is no device BSN:0x%X\n\n",bsn); return ; } else CtlAddr=baseAddress[bsn].ctladdr; EEWriteEnable(); int i; EECSL(); EECLKL(); EEDIL(); // スタート EECSH(); EEDIH(); EECLKH(); EECLKL(); // 1 addr=(addr&0x3f)|0x40; // コマンド送信 for(i=0;i<8;i++) { if(addr & 0x80) EEDIH(); else EEDIL(); addr <<= 1; EECLKH(); EECLKL(); } for(i=0;i<16;i++) { if(val & 0x8000) EEDIH(); else EEDIL(); val <<= 1; EECLKH(); EECLKL(); } EECSL(); EEDIL(); EEWaitBusy(); EEWriteDisable(); } int UnivIFReadEEPROM(int bsn, word addr) { CheckUNIVIFOperation(); if((bsn>=0)&&(baseAddress[bsn].ctladdr==0)) { fprintf(stderr,"Error: There is no device BSN:0x%X\n\n",bsn); return -1; } else CtlAddr=baseAddress[bsn].ctladdr; unsigned short d=0; int i; EECSL(); EECLKL(); EEDIL(); // スタート EECSH(); EEDIH(); EECLKH(); EECLKL(); // 1 addr=addr&0x3f | 0x80; // READ Opecode // アドレス送信 for(i=0;i<8;i++) { if(addr & 0x80) EEDIH(); else EEDIL(); addr <<= 1; EECLKH(); EECLKL(); } EECLKH(); for(i=0;i<16;i++) { d <<= 1; EECLKL(); if(EEDO()) d|=1; EECLKH(); } EECSL(); EECLKL(); EEDIL(); return d; }