| 0,0 → 1,1728 |
| //------------------------------------------------------------------------------------------- |
| // pvmon.c - the body of a simple tool to access VME BUS resources |
| // |
| // (c) 1999-2002 ARW Elektronik |
| // |
| // this source code is published under GPL (Open Source). You can use, redistrubute and |
| // modify it unless this header is not modified or deleted. No warranty is given that |
| // this software will work like expected. |
| // This product is not authorized for use as critical component in life support systems |
| // wihout the express written approval of ARW Elektronik Germany. |
| // |
| // Please announce changes and hints to ARW Elektronik |
| // |
| // $Log: pvmon.c,v $ |
| // Revision 1.6 2002/11/14 19:57:56 klaus |
| // improvement, still bugs active |
| // |
| // Revision 1.5 2002/10/20 18:07:48 klaus |
| // mostly working alpha version |
| // |
| // Revision 1.4 2002/10/20 11:49:33 klaus |
| // first parts working |
| // |
| // Revision 1.3 2002/10/19 09:47:30 klaus |
| // first success compiling project |
| // |
| // Revision 1.2 2002/10/19 09:44:38 klaus |
| // first success compiling project |
| // |
| // Revision 1.1.1.1 2002/10/18 22:14:29 klaus |
| // |
| // first parts written and published from |
| // Sven Hannover, Sven Tuecke, Klaus Hitschler, Ralf Dux 1991 |
| // |
| |
| //------------------------------------------------------------------------------------------- |
| // INCLUDES |
| // |
| #include <unistd.h> |
| #include <sys/types.h> |
| #include <sys/ioctl.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| |
| #include <setjmp.h> |
| #include <signal.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <time.h> |
| |
| #include <slang.h> |
| |
| #include <../driver/vme.h> /* constants about VME BUS */ |
| #include <mbuffer.h> /* simple message buffering */ |
| #include <pcilibLx.h> /* device access functions */ |
| |
| //------------------------------------------------------------------------------------------- |
| // DEFINES |
| // |
| #define VERSION "6.0Lx" |
| #define True 1 |
| #define False 0 |
| |
| #if !defined(FALSE) || !defined(TRUE) |
| #define FALSE False |
| #define TRUE True |
| #endif |
| |
| #define DEVPATH " - No input neccessary!" // not used |
| #define DEFDEVICENAME "/dev/vmemm_1" |
| #define DEFAULT_ADDRESS 0x00000000 // default VME window base address |
| #define DEFAULT_MODIFIER Std_NoPriv_Data // default address modifier |
| #define DEFAULT_TYPE sizeof(char) // default data BUS access width |
| #define MAX_TIMEOUT_LOOPS 100000 // maximum loops for waiting reset finished |
| |
| //------------------------------------------------------------------------------------------- |
| // TYPEDEFS |
| // |
| typedef char STRG[BUFFERLENGTH]; /* Allgemeiner Stringtyp */ |
| |
| //------------------------------------------------------------------------------------------- |
| // LOCALS |
| // |
| static char UpCase(char Zchn); |
| static char *ParaStr(int Num); |
| static unsigned long ParaNum(int Num); |
| static void SetModifier(void); |
| static void PrintItem(unsigned long Addr, char Mode, unsigned char *Asc); |
| static char GetZug(char *Zug); |
| static void Dump(void); |
| static char GetStrg(STRG Stg, int Len); |
| static void Examine(void); |
| static void Move(void); |
| static void Fill(void); |
| static void Hilfe(void); |
| static int InitAt(char *szDevicePath, int *nInterfaceHandle); |
| static void CfgName(STRG Stg); |
| static void LoadKonfig(void); |
| static void Konfig(void); |
| static void ReadIrqVect(void); |
| static void JumpToDos(void); |
| static void Raus(void); |
| static void SearchPort(char *Art, |
| int Anz, |
| unsigned short modf, |
| void(*SFunc)(int nHandle, unsigned long Adr,unsigned short AModifier)); |
| static void SearchPorts(void); |
| static unsigned GibNum(char **PSt,char Anz); |
| static int _ReadFile(void); |
| static void SeekPatt(void); |
| static void TestSet(void); |
| static void ResetVme(void); |
| static int OutHex(FILE *OuF, int Siz, unsigned long Adr, int Typ, char Buf[]); |
| static int _WriteFile(void); |
| static void ShowModifier(int Mode); |
| static void ShowRegister(void); |
| static int HauptMenue(STRG Stg); |
| static void MyExit(int); |
| static void SysFail(void); |
| |
| //------------------------------------------------------------------------------------------- |
| // EXTERNALS |
| // |
| |
| //------------------------------------------------------------------------------------------- |
| // GLOBALS |
| // |
| static unsigned short AdrMode = Short_NoPriv; /* Mein initialer Adressmodifier */ |
| static char DefZug = 'B'; /* Default Zugriff */ |
| static char DefVec = 'B'; /* Default Zugriff IrqVecs */ |
| static char **ArgV; /* ArgV aus main() */ |
| static STRG InStg; /* Allgemeiner Eingabestring */ |
| |
| static char *TsT; |
| static char Abbruch = 0; /* verzweig wg. SIGINT */ |
| |
| static int nInterfaceHandle; /* handle of device */ |
| static char *cszDevicePath; /* path of device */ |
| static int WordMode; /* mode of VME path operation */ |
| |
| static char localBuffer[BUFFERLENGTH] = DEFDEVICENAME; |
| |
| //------------------------------------------------------------------------------------------- |
| // FUNCTIONS |
| // |
| //----------------------------------------------------------------------------- |
| // functions to emulate for this platform |
| static int getch(void) |
| { |
| return SLang_getkey(); |
| } |
| |
| |
| static void strlwr(char *str) |
| { |
| int i; |
| char *ptr = str; |
| |
| for (i = 0; ((i < BUFFERLENGTH) && (*ptr)); i++) |
| { |
| *ptr = tolower(*ptr); |
| ptr++; |
| } |
| } |
| |
| static int _gets(char *str) |
| { |
| if (fgets(str, BUFFERLENGTH, (FILE *)stdin) == NULL) |
| return EINVAL; |
| else |
| { |
| // remove '\n' from string |
| int i; |
| char *ptr = str; |
| |
| for (i = 0; i < BUFFERLENGTH; i++, ptr++) |
| { |
| if (*ptr == '\n') |
| { |
| *ptr = 0; |
| break; |
| } |
| } |
| return 0; |
| } |
| } |
| |
| //----------------------------------------------------------------------------- |
| // get out of here |
| static void Raus(void) |
| { |
| DeInit_Interface(nInterfaceHandle); |
| exit(0); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // return the uppercase char |
| static char UpCase(char Zchn) /* Upcase eines Zeichens */ |
| { |
| return((Zchn >= 'a' && Zchn <= 'z') ? Zchn - 0x20 : Zchn); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // get the n-th parameter as string |
| static char *ParaStr(int Num) /* Hole n-ten Parameter */ |
| { /* als String aus InStg */ |
| char *PSt; /* Evt. Ergebnis NULL bei (Num>1) */ |
| |
| PSt=InStg; /* Fange bei InStg[0] an */ |
| if (Num > 1) |
| { /* Folgeparameter: suche Anfang */ |
| if (*PSt!='\0') |
| { /* Leerstring ignorieren */ |
| PSt++; |
| switch (*PSt) |
| { /* Teste evt. Modusparameter */ |
| case 'L': |
| case 'W': |
| case 'B': |
| case 'X': |
| case 'H':PSt++; |
| } |
| |
| if (*PSt==' ') PSt++; /* Evt. Delimiter ueberspringen */ |
| } |
| |
| if (*PSt=='\0') PSt=NULL; /* Kein weiterer Parameter da */ |
| else |
| { |
| while (PSt!=NULL && Num>2) |
| { |
| PSt=strchr(PSt, ' '); /* Suche nach Delimiter */ |
| if (PSt!=NULL) PSt++; /* Delimiter ueberspringen */ |
| Num--; /* Naechster Parameter da */ |
| } /* while */ |
| } /* else */ |
| } /* if */ |
| return(PSt); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // get the n-th parameter as unsigned long |
| static unsigned long ParaNum(int Num) /* Hole n-ten Parameter */ |
| { /* als Zahl aus InStg */ |
| unsigned long Erg; |
| char *PSt; |
| |
| PSt=ParaStr(Num); /* Hole Parameterstring */ |
| Erg=0; /* Hole Word aus String */ |
| if (PSt!=NULL) sscanf(PSt, "%lx", &Erg); |
| return(Erg); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // set the address modifier for following accesses |
| static void SetModifier(void) /* Neuen Adressmodifier setzen */ |
| { |
| int Idx; |
| |
| if (ParaStr(1)[1]=='H') |
| { /* Wenn Hilfsfunktion gewuenscht */ |
| if (ParaStr(2)==NULL) |
| { /* Noch ein Parameter da? */ |
| for (Idx=0; Idx<0x40; Idx++) |
| { /* Nein: Liste ausgeben */ |
| ShowModifier(Idx); |
| if ((Idx == 0x10) || (Idx == 0x20) || (Idx == 0x30)) |
| { |
| printf("\n go on ?\r"); |
| getch(); |
| } |
| } |
| printf("\n"); |
| } |
| else ShowModifier((int)ParaNum(2)); /* Nur gewuenschten Mode anzeigen */ |
| } |
| else |
| { |
| if (ParaStr(2) != NULL) |
| { |
| if (ParaStr(1)[1] == 'M') |
| { |
| AdrMode=(int)ParaNum(3) & 0x3f; |
| } |
| else |
| { |
| AdrMode=(int)ParaNum(2) & 0x3f; /* Adressmodifier merken */ |
| } |
| } |
| ShowModifier(AdrMode); /* Status Adressmodifier zeigen */ |
| } /* else */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // print out an item |
| static void PrintItem(unsigned long Addr, char Mode, unsigned char *Asc) |
| { |
| unsigned long xl; |
| unsigned int xi; |
| unsigned char xc; |
| |
| switch (Mode) |
| { |
| case 'L': xl=ReadLong(nInterfaceHandle, Addr, AdrMode); |
| if (GetError(nInterfaceHandle)) |
| { |
| ClearError(nInterfaceHandle); printf("******** "); |
| } |
| else |
| { |
| printf("%08lx ", xl); |
| if (Asc != NULL) *(unsigned long *)Asc=xl; |
| } |
| break; |
| case 'W': xi=ReadWord(nInterfaceHandle, Addr, AdrMode); |
| if (GetError(nInterfaceHandle)) |
| { |
| ClearError(nInterfaceHandle); printf("**** "); |
| } |
| else |
| { |
| printf("%04hx ", xi); |
| if (Asc != NULL) *(unsigned short *)Asc=xi; |
| } |
| break; |
| case 'B': xc=ReadByte(nInterfaceHandle, Addr, AdrMode); |
| if (GetError(nInterfaceHandle)) |
| { |
| ClearError(nInterfaceHandle); printf("**"); |
| } |
| else |
| { |
| printf("%02hx", xc); |
| if (Asc != NULL) *Asc=xc; |
| } |
| break; |
| }; /* switch */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // test whether byte word or long access |
| static char GetZug(char *Zug) /* Moduszeichen feststellen */ |
| { |
| switch (ParaStr(1)[1]) |
| { /* Moduszchn ist angegeben */ |
| case 'L': |
| case 'W': |
| case 'B':*Zug = ParaStr(1)[1]; /* Neues Moduszchn festlegen */ |
| } |
| return(*Zug); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // get or set SYSFAIL |
| static void SysFail(void) |
| { |
| if (ParaStr(2) != NULL) |
| { |
| if (ParaNum(2) > 0) |
| SetSfail(nInterfaceHandle); |
| else |
| ClrSfail(nInterfaceHandle); |
| } |
| |
| if (PollSfail(nInterfaceHandle)) |
| printf("SYSFAIL deasserted\n"); |
| else |
| printf("SYSFAIL asserted\n"); |
| } |
| |
| |
| //----------------------------------------------------------------------------- |
| // dump a range of memory |
| static void Dump(void) /* Ausgabe eines Bereichs */ |
| { |
| static unsigned long DefVon=0; /* Default Addr fuer Dump */ |
| |
| unsigned long Bis; /* Bis wohin ausgeben */ |
| unsigned int Len; /* Wieviel Bytes/Ausgabe */ |
| unsigned int Idx; /* Index */ |
| char Asc[16]; /* ohne static gehts bei dw nicht */ |
| |
| if (ParaStr(2) != NULL) /* Von-Adresse angegeben? */ |
| DefVon=ParaNum(2); |
| Len=1; |
| |
| switch (GetZug(&DefZug)) |
| { /* Zugriffsmodus festlegen */ |
| case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
| case 'W':Len++; /* Auf Wort-Adresse biegen */ |
| } |
| |
| DefVon&=-(long)Len; /* Adressen geradebiegen */ |
| if (ParaStr(3) != NULL) |
| { /* Bis-Adresse angegeben? */ |
| Bis=ParaNum(3); |
| } |
| else |
| Bis=(DefVon+0x7f) | 0x0f; /* Default fuer Bis errechnen */ |
| |
| printf("%08lx: ", DefVon); |
| for (Idx=0; Idx < (DefVon & 0x0f)/Len*(2*Len+1); Idx++) |
| printf(" "); |
| |
| memset(Asc, ' ', sizeof(Asc)); /* Initialize String to Spaces */ |
| while ((True) && (!Abbruch)) |
| { |
| PrintItem(DefVon, DefZug, /* Gebe eine Speicherstelle aus */ |
| &Asc[DefVon & 0x0f]); /* Merke Zeichen in Asc */ |
| DefVon+=Len; /* Zaehler erhoehen */ |
| |
| if ((DefVon > Bis) || (!(DefVon & 0x0f))) |
| { |
| printf(" "); |
| for (Idx=0; Idx < sizeof(Asc); Idx++) |
| { |
| if (Asc[Idx] < ' ') printf("."); /* Ascii-String ausgeben */ |
| else printf("%c", Asc[Idx]); /* Ctrl-Zeichen als Punkte */ |
| } |
| |
| printf("\n"); |
| if (DefVon <= Bis) |
| { |
| printf("%08lx: ", DefVon); /* Neue Zeile bei 16er-Grenze */ |
| memset(Asc, ' ', sizeof(Asc)); /* Init String */ |
| } |
| else return; /* Ausstieg */ |
| } |
| else |
| { /* Sonst Leerzeichen ausgeben */ |
| printf(((DefVon & 0x0f) == 0x08) ? "|":" "); |
| } |
| } /* while */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // read a string with editing functions |
| static char GetStrg(STRG Stg, int Len) /* Lese String ein bis Spc */ |
| { |
| int Idx; /* Zugriffsindex */ |
| char Zch; /* Eingabezeichen */ |
| |
| Idx=0; /* Vorne anfangen */ |
| do |
| { |
| Zch=(char)getch(); /* Hole ein Zeichen */ |
| if ((unsigned char)Zch >' ' && Zch!='\t') |
| { |
| if (Idx<Len) |
| { |
| printf("%c",Zch); /* Zeichen ok, Ausgeben */ |
| Stg[Idx++]=Zch; /* Zeichen ablegen */ |
| } |
| } |
| else |
| { |
| switch (Zch) |
| { |
| case '\b':if (Idx) |
| { /* Backspace=Delete? */ |
| Idx--; /* Loesche Zeichen aus String */ |
| printf("\b \b"); /* und vom Bildschirm */ |
| } |
| case '\t': |
| case '\r':break; /* Return? Endezeichen 13 */ |
| default:Zch=0; /* Ende mit Endezeichen 0 */ |
| } /* switch */ |
| } /* else */ |
| } while (Zch && Zch!='\r' && Zch!='\n'); |
| |
| Stg[Idx]='\0'; /* Stringende eintragen */ |
| return(Zch); /* Returncode = Abschlusstaste */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // examine a memory location |
| static void Examine(void) /* Speicherbereich aendern */ |
| { |
| unsigned long DefVon; /* Anfangsadresse */ |
| unsigned long Inh; /* Neuer Inhalt */ |
| int Len; /* Item-Laenge */ |
| int Idx; /* Index */ |
| char End; /* Endmodus */ |
| STRG Stg; /* Eingabestring */ |
| |
| if (ParaStr(2)!=NULL) |
| { /* Adresse benoetigt */ |
| Len=1; |
| switch (GetZug(&DefZug)) |
| { /* Zugriffsmodus festlegen */ |
| case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
| case 'W':Len++; /* Auf Wort-Adresse biegen */ |
| } |
| DefVon=ParaNum(2) & -(long)Len; /* Adressen geradebiegen */ |
| if (ParaStr(3)!=NULL) |
| { /* Wert angegeben? */ |
| Inh=ParaNum(3); /* Hole auszugebenden Wert */ |
| switch (DefZug) |
| { |
| case 'L': WriteLong(nInterfaceHandle, DefVon,Inh,AdrMode); |
| break; |
| case 'W': WriteWord(nInterfaceHandle, DefVon,(short)Inh,AdrMode); |
| break; |
| case 'B': WriteByte(nInterfaceHandle, DefVon,(char)Inh,AdrMode); |
| break; |
| }; /* switch */ |
| |
| if (GetError(nInterfaceHandle)) |
| { /* Fehlerpruefung: VME-Transfer ok? */ |
| ClearError(nInterfaceHandle); /* Zuruecksetzen Fehlerflag */ |
| printf("Error\n"); /* Zugriff gescheitert */ |
| } |
| } |
| else |
| { |
| SLang_init_tty(-1, 0, 1); |
| SLtt_get_terminfo(); |
| |
| End='\n'; /* Bei Einstieg drucke Adresse */ |
| do |
| { |
| if (End=='\n' || End=='\177' || !(DefVon % 8)) |
| { |
| if (End!='\n') printf("\n"); /* Bei Einstieg nicht <CRLF> */ |
| printf("%08lx: ", DefVon); /* Adresse ausgeben */ |
| } |
| |
| PrintItem(DefVon,DefZug,NULL); /* Gebe eine Speicherstelle aus */ |
| printf("."); |
| SLtt_flush_output(); |
| |
| End=GetStrg(Stg,Len << 1); /* Hole begrenzte Eingabezeile */ |
| |
| for (Idx=strlen(Stg); Idx<2+(Len << 1); Idx++) |
| printf(" "); |
| if (sscanf(Stg,"%lx",&Inh)>0) |
| { /* Hexzahl rausholen und ausgeben */ |
| switch (DefZug) |
| { |
| case 'L': WriteLong(nInterfaceHandle, DefVon,Inh,AdrMode); |
| break; |
| case 'W': WriteWord(nInterfaceHandle, DefVon,(short)Inh,AdrMode); |
| break; |
| case 'B': WriteByte(nInterfaceHandle, DefVon,(char)Inh,AdrMode); |
| break; |
| }; /* switch */ |
| |
| if (GetError(nInterfaceHandle)) |
| ClearError(nInterfaceHandle);/* Fehlerpruefung: VME-Transfer ok? */ |
| } /* if sscanf */ |
| |
| if (End == '\177') DefVon-=Len;/* Naechste Speicherzelle ansteuern */ |
| else DefVon+=Len; |
| } while (End!='\r'); |
| /* Ende bei <CR> */ |
| printf("\n"); |
| |
| SLang_reset_tty(); |
| } /* else */ |
| } /* if */ |
| else printf("\a"); /* Fehler: zuwenig Parameter */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // fill a range of memory |
| static void Fill(void) /* Fuellt Speicherbereich mit Wert */ |
| { |
| char DefZug; /* Zugriffsart */ |
| int Len; /* Item Laenge */ |
| unsigned long Idx; /* Index */ |
| unsigned long End; /* Endadresse */ |
| unsigned long Patt; /* Fuellmuster */ |
| unsigned char Merk_error = 0; /* Haelt error flag */ |
| |
| DefZug=' '; /* Modus muss angeben werden */ |
| if (GetZug(&DefZug)!=' ' && ParaStr(4)!=NULL) |
| { |
| Len=1; |
| switch (GetZug(&DefZug)) |
| { /* Zugriffsmodus festlegen */ |
| case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
| case 'W':Len++; /* Auf Wort-Adresse biegen */ |
| } |
| Idx=ParaNum(2) & -(long)Len; /* Adressen geradebiegen */ |
| End=ParaNum(3); /* Endadresse festlegen */ |
| Patt=ParaNum(4); /* Pattern merken (geht schneller) */ |
| |
| while ((Idx<=End) && (!Abbruch)) |
| { |
| switch (DefZug) |
| { |
| case 'L':WriteLong(nInterfaceHandle, Idx, Patt, AdrMode); |
| break; |
| case 'W':WriteWord(nInterfaceHandle, Idx, (short)Patt, AdrMode); |
| break; |
| case 'B':WriteByte(nInterfaceHandle, Idx, (char)Patt, AdrMode); |
| break; |
| } /* switch */ |
| |
| if (GetError(nInterfaceHandle)) |
| { |
| ClearError(nInterfaceHandle); /* Fehler abfangen */ |
| Merk_error = 1; |
| } |
| if ((Idx & 0xffl)==0) |
| { /* Ermoegliche Ctrl-C */ |
| printf("\r"); |
| } |
| Idx+=Len; |
| } /* while */ |
| if (Merk_error) printf("--> Memory fill failed\a\n"); |
| } |
| else printf("\a"); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // moves a range of memory |
| static void Move(void) /* Schiebt Speicherbereich */ |
| { |
| char DefZug; /* Zugriffsart */ |
| int Len; /* Item Laenge */ |
| unsigned long Idx; /* Index */ |
| unsigned long End; /* Endadresse */ |
| unsigned long Dest; /* Zieladresse */ |
| unsigned long Wert; /* Kopiewert */ |
| unsigned char Merk_error = 0; /* Haelt error flag */ |
| |
| |
| DefZug=' '; /* Modus muss angeben werden */ |
| if (GetZug(&DefZug)!=' ' && ParaStr(4)!=NULL) |
| { |
| Len=1; |
| switch (GetZug(&DefZug)) |
| { /* Zugriffsmodus festlegen */ |
| case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
| case 'W':Len++; /* Auf Wort-Adresse biegen */ |
| } |
| Idx=ParaNum(2) & -(long)Len; /* Adressen geradebiegen */ |
| End=ParaNum(3); /* Endadresse festlegen */ |
| Dest=ParaNum(4); /* Zieladresse setzen */ |
| |
| while ((Idx<=End) && (!Abbruch)) |
| { |
| switch (DefZug) |
| { |
| case 'L': { |
| Wert = ReadLong(nInterfaceHandle, Idx, AdrMode); |
| WriteLong(nInterfaceHandle, Dest, Wert, AdrMode); |
| } |
| break; |
| case 'W': { |
| Wert = ReadWord(nInterfaceHandle, Idx, AdrMode); |
| WriteWord(nInterfaceHandle, Dest, (short)Wert, AdrMode); |
| } |
| break; |
| case 'B': { |
| Wert = ReadByte(nInterfaceHandle, Idx, AdrMode); |
| WriteByte(nInterfaceHandle, Dest, (char)Wert, AdrMode); |
| } |
| break; |
| } /* switch */ |
| |
| if (GetError(nInterfaceHandle)) |
| { |
| ClearError(nInterfaceHandle); /* Fehler abfangen */ |
| Merk_error = 1; |
| } |
| |
| if ((Idx & 0xffl)==0) |
| { /* Ermoegliche Ctrl-C */ |
| printf("\r"); |
| } |
| |
| Idx+=Len; |
| Dest+=Len; |
| } /* while */ |
| if (Merk_error) printf("--> Memory move failed\a\n"); |
| } |
| else printf("\a"); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // print out help to user |
| static void Hilfe(void) |
| { |
| printf("a[h] [adrmode]\t\t: Change address modifiers, h=help\n"); |
| printf("c\t\t\t: Configure interface\n"); |
| printf("d[m] [start] [end]\t: Dump memory area\n"); |
| printf("e[m] <start> [value]\t: Examine or change memory area\n"); |
| printf("f<m> <start> <end> <x>\t: Fill memory from <start> til <end> with <x>\n"); |
| printf("g<m> <st> <en> [l] [x]\t: Generate random memory test. (loop l, seed x)\n"); |
| printf("h\t\t\t: This help\n"); |
| printf("i\t\t\t: Interface init\n"); |
| printf("l[m]\t\t\t: Get VME interrupt status/ID\n"); |
| printf("m<m> <src> <end> <dest>\t: Move memory area\n"); |
| printf("o\t\t\t: Jump to OS\n"); |
| printf("p[adrmode]\t\t: Port search\n"); |
| printf("q\t\t\t: Quit program\n"); |
| printf("r[x] <f> <start> [end]\t: Read file <f> to VME, x= x or s (HEX)\n"); |
| printf("s[m] <start> <end> <p>\t: Search pattern <p>=different Items\n"); |
| printf("t <start>\t\t: TAS emulation, 'Test and Set' bit 7\n"); |
| printf("v\t\t\t: Generate VME SYSRESET\n"); |
| printf("w[x] <f> <start> <end>\t: Write VME into file <f>, h=Intel Hex\n"); |
| printf("x <start> [val]\t\t: Read/Write to interface register @ start\n"); |
| printf("y[1/0]\t\t\t: Read/set/clear SYSFAIL\n"); |
| printf("z[0..2]\t\t\t: Show interface internals\n"); |
| printf("\n"); |
| printf("m = mode, e.g. b=byte, w=word, l=long (double) word; h = help, x= hex\n"); |
| printf("start(address), end(address), src=source, dest=destination, []=option\n"); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // initialize the interface to VME |
| static int InitAt(char *szDevicePath, int *nIfcNum) /* Gibt bei Fehler False aus */ |
| { |
| int result; |
| |
| if (result = Init_Interface(szDevicePath, AdrMode, nIfcNum)) /* Pruefung des Interfaces */ |
| { |
| printf("\n"); |
| switch (result) |
| { |
| case ENXIO: |
| printf("Can't find interface driver path!\n"); |
| printf("Please <q>uit or <c>onfigure interface!\n"); |
| return FALSE; |
| case ENOENT: |
| printf("Can't find interface driver!\n"); |
| printf("Please <q>uit or <c>onfigure interface!\n"); |
| return FALSE; |
| case ENODEV: |
| printf("VMEMM #%d not connected or VME crate switched off!\n", nInterfaceHandle); |
| printf("Please check connection or switch VME crate on or <c>onfigure.\n"); |
| printf("Then <q>uit and restart again.\n"); |
| return FALSE; |
| |
| default: |
| printf("Unknown error '%d' occured!\n", result); |
| printf("Please check the hardware and software setup and restart again.\n"); |
| return FALSE; |
| |
| } |
| } |
| |
| return(True); /* Kein Fehler */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // get the name of the configuration file |
| static void CfgName(STRG Stg) /* Ermittelt Namen Config-File */ |
| { |
| Stg[0]='\0'; |
| if (ArgV[0] != NULL) |
| { |
| strcpy(Stg,ArgV[0]); |
| if (strrchr(Stg,'/')!=NULL) /* Versuche Dateinamen abzutrennen */ |
| *(strrchr(Stg,'/')+1)='\0'; /* So daß nur Pfad uebrigbleibt */ |
| else Stg[0]='\0'; /* Kein Pfad: String ist leer */ |
| } |
| strcat(Stg,"pvmon.cfg"); /* Mache einen Dateinamen */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // read in contents of configuration file |
| static void LoadKonfig(void) /* Wenn Config-Datei da, lese ein */ |
| { |
| STRG Stg; |
| FILE *InF; |
| char c; |
| __u32 dwLocalAdrMode; |
| |
| CfgName(Stg); /* Hole Dateinamen nach InS */ |
| if ((InF=fopen(Stg,"rt"))!=NULL) |
| { /* Wenn das oeffnen geklappt hat */ |
| fscanf(InF,"%*[^=]%*1s%s",Stg); |
| fscanf(InF,"%*[^=]%*1s%s",cszDevicePath); |
| fscanf(InF,"%*[^=]%*1s%x",&dwLocalAdrMode); |
| AdrMode = (__u8)dwLocalAdrMode; |
| fscanf(InF,"%*[^=]%*1s%c",&c); |
| fclose(InF); /* Datei wieder schließen */ |
| |
| c = tolower(c); |
| if (c == 'y') |
| WordMode = setWordMode(1); |
| else |
| WordMode = setWordMode(0); |
| |
| } /* if */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // provides configuration functionality to user |
| static void Konfig(void) /* Konfiguration einstellen */ |
| { |
| STRG InS; /* Eingabestring */ |
| FILE *OuF; /* Ausgabedatei */ |
| short change = 0; |
| char c; |
| |
| InS[0] = 0; |
| printf("Pathname of device (%s):",cszDevicePath); /* erfrage den Pfad zum Treiber */ |
| _gets(InS); |
| if ((InS[0] != '\n') && (InS[0])) |
| { |
| strcpy(cszDevicePath, InS); |
| change |= 1; |
| } |
| |
| InS[0] = 0; |
| printf("Default address modifier (%02x):",AdrMode); /* und den default Modifier */ |
| _gets(InS); |
| if ((InS[0] != '\n') && (InS[0])) |
| { |
| sscanf(InS,"%x",&AdrMode); |
| change |= 4; |
| } |
| |
| if (WordMode) |
| c = 'y'; |
| else |
| c = 'n'; |
| InS[0] = 0; |
| printf("16 bit VME BUS data path (%c) :", c); |
| _gets(InS); |
| if ((InS[0] != '\n') && (InS[0])) |
| { |
| sscanf(InS,"%c",&c); |
| change |= 8; |
| } |
| c = tolower(c); |
| if (c == 'y') |
| WordMode = setWordMode(1); |
| else |
| WordMode = setWordMode(0); |
| |
| if (change) |
| { |
| do |
| { |
| printf("Save (y/n):"); /* Wiederhole diese Frage bis */ |
| _gets(InS); /* sie ordentlich beantwortet wurde */ |
| strlwr(InS); /* DownCase String */ |
| } while (InS[0]!='y' && InS[0]!='n'); |
| |
| if (InS[0]=='y') |
| { |
| CfgName(InS); /* Hole Dateinamen nach InS */ |
| if ((OuF=fopen(InS,"wt"))!=NULL) |
| { |
| if (WordMode) |
| c = 'y'; |
| else |
| c = 'n'; |
| |
| fprintf(OuF,"Configuration=%s\n",__DATE__); |
| fprintf(OuF,"DevicePath=%s\n",cszDevicePath); /* Wenn das oeffnen geklappt hat */ |
| fprintf(OuF,"AddressModifier=%x\n",AdrMode); |
| fprintf(OuF,"WordMode=%c\n", c); |
| fclose(OuF); /* Datei schliessen */ |
| |
| if (change & 1) |
| printf("Please restart to put the new driver to work!\n"); |
| } |
| else printf("Can't open %s. ",InS); |
| } |
| } |
| } |
| |
| //----------------------------------------------------------------------------- |
| // read user initiated interrupt vector from VME BUS |
| static void ReadIrqVect(void) /* Interrupt-Vektoren lesen */ |
| { |
| STRG OSt; /* Ausgabestring */ |
| short Level = 0; |
| |
| switch (GetZug(&DefVec)) |
| { /* Zugriffsmodus festlegen */ |
| case 'L':sprintf(OSt, "%08hx", ReadVectorLong(nInterfaceHandle)); break; |
| case 'W':sprintf(OSt, "%04hx", ReadVectorWord(nInterfaceHandle)); break; |
| case 'B':sprintf(OSt, "%02hx", ReadVectorByte(nInterfaceHandle)); break; |
| }; |
| |
| if (GetError(nInterfaceHandle)) |
| { /* Im Fehlerfalle 'Error' ausgeben */ |
| ClearError(nInterfaceHandle); /* Fehlerflags zuruecksetzen */ |
| strcpy(OSt, "Error"); |
| } |
| printf("VME status/ID = %s\n", OSt); |
| } |
| |
| |
| //----------------------------------------------------------------------------- |
| // temporary jump to (D)OS |
| static void JumpToDos() /* (D)OS-Shell aufrufen */ |
| { |
| { |
| if (system("/bin/sh -c $SHELL") != 0) |
| printf("Fail to launch a new shell.\n"); |
| } |
| } |
| |
| //----------------------------------------------------------------------------- |
| // search responding ports in VME address range |
| static void SearchPort(char *Art, int Anz, unsigned short modf, |
| void (*SFunc)(int, unsigned long, unsigned short)) /* Durchsucht Adressraum */ |
| { |
| unsigned long Idx; |
| unsigned long Fst; /* Erster gefundener Port */ |
| unsigned long Lst; /* Letzer gefundener Port */ |
| unsigned long Ende; /* Durchsuch Ende */ |
| char Found; /* Schon was gefunden? */ |
| char Sequ; /* Schon eine Portsequenz */ |
| int Err; /* Fehler dagewesen? */ |
| int Tab; /* Tabulator-Zaehler */ |
| unsigned long Step; |
| |
| printf("%s-accesses valid with address modifier %02x to address: ", Art,modf); |
| |
| if (modf > 0x2F) |
| { |
| Ende = 0x01000000L; /* alle Standards */ |
| Step = 0x100; /* Stepweite */ |
| } |
| |
| if ((modf < 0x30) && (modf > 0x1f)) |
| { |
| Ende = 0x00010000L; /* Shorts */ |
| Step = Anz; |
| } |
| |
| if (modf < 0x20) |
| { |
| Ende = 0xFFFF0000L; /* alle Extendets, gemogelt */ |
| Step = 0x10000; /* Step */ |
| } |
| |
| Sequ=False; /* Noch keine Sequenz da */ |
| Found=False; |
| Tab=0; |
| Idx=0; |
| |
| do |
| { /* do while */ |
| SFunc(nInterfaceHandle, Idx, modf); /* Lese versuchsweise Port */ |
| Err=GetError(nInterfaceHandle); /* Fehlerzustand abfragen */ |
| if (Err) ClearError(nInterfaceHandle); /* Fehler bestaetigen */ |
| else |
| { |
| Lst=Idx; /* Merke Port als gueltig */ |
| if (!Sequ) |
| { /* Diese Seqenz faengt an? */ |
| Fst=Idx; /* Ja, neue Sequenz, merke */ |
| Sequ=True; /* auch ersten Port */ |
| } |
| } |
| |
| Idx+= Step; /* Erhoehe Adresse */ |
| |
| if ((Err || !(Idx < Ende)) && Sequ) |
| { /* Ausgeben bei Sequenzende */ |
| if (!Found) |
| { /* oder bei Schleifenende */ |
| if (Idx < Ende) printf("\n"); /* Kein <CRLF> bei Schleifenende */ |
| Found=True; |
| }; |
| /* Weitere Sequenz: Tab ausgeben */ |
| if (Fst==Lst) |
| { /* Sequenz mit nur 1 Element */ |
| printf("%08lx,\t", Fst); |
| Tab++; /* Merke Tab-Status */ |
| } |
| else |
| { |
| Tab=0; /* Tab-Status wieder zuruecksetzen */ |
| printf("%08lx-%08lx\n", Fst, Lst); /* Sequenz ausgeben */ |
| } |
| Sequ=False; /* Sequenz gilt als abgeschlossen */ |
| } /* if */ |
| } while ((Idx < Ende) && (!Abbruch)); /* Bis Idx einmal 'rum ist */ |
| |
| if (!Found) |
| printf("\nnothing found"); /* Wenn keinen Zugriff gefunden */ |
| printf("\n"); /* Immer mit <CRLF> abschließen */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // search responding ports |
| static void SearchPorts(void) /* Durchsucht Short-Adressraum */ |
| { /* nach Wort- und Bytes Zugriffen */ |
| unsigned short modf = AdrMode; |
| |
| if (ParaStr(2)!=NULL) |
| modf = (unsigned short)ParaNum(2); /* Anderer Adressmodifier */ |
| |
| ShowModifier(modf); printf("\n"); |
| SearchPort("Byte", 1, modf, (void(*)(int, unsigned long, unsigned short))ReadByte); |
| SearchPort("Word", 2, modf, (void(*)(int, unsigned long, unsigned short))ReadWord); |
| SearchPort("Long", 4, modf, (void(*)(int, unsigned long, unsigned short))ReadLong); |
| printf("\n"); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // converts parts of a string to a number |
| static unsigned int GibNum(char **PSt, char Anz) |
| { |
| unsigned int Val; /* Ermittelter Wert */ |
| unsigned int Num; /* Wieviel Zeichen genommen */ |
| char Frm[6]; /* Formatstring */ |
| |
| Val=0; /* Default setzen */ |
| strcpy(Frm,"%nx%n"); /* Default Format setzen */ |
| if (*PSt!=NULL) |
| { /* Nur wenn String gueltig */ |
| Frm[1]=Anz; /* Uebertrage Anzahl-Zeichen */ |
| *PSt=(sscanf(*PSt,Frm,&Val, /* Hole Nummer aus String */ |
| &Num)!=1) ? NULL : (*PSt)+Num; /* Fehler oder weitersetzen */ |
| } /* if */ |
| return(Val); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // read in a file and put the contents to VME |
| static int _ReadFile(void) /* Lese eine Datei in VME-Mem ein */ |
| { |
| unsigned long End; /* Endadresse */ |
| unsigned long Idx; /* Laufadresse */ |
| unsigned long Cnt; /* Bytezaehler */ |
| unsigned Adr; /* Adresse Record ab Start */ |
| int Len; /* Recordlaenge */ |
| int Ret; /* Returncode */ |
| int Hex; /* Intel Hex File? */ |
| int Typ; /* Typ des Records */ |
| STRG Nam; /* Dateiname */ |
| STRG Stg; /* Einlese-String */ |
| char *PSt; /* Scanzeiger */ |
| FILE *InF; /* Lesedatei */ |
| |
| Ret=1; /* Vorgabe ist Fehler */ |
| if (ParaStr(3)!=NULL) |
| { /* Startadr ist obligat */ |
| Hex=(ParaStr(1)[1]=='X'); /* Intel-Hex gewuenscht? */ |
| strcpy(Nam,ParaStr(2)); /* Dateinamen kopieren */ |
| *strchr(Nam,' ')='\0'; /* Restparameter abschneiden */ |
| Cnt=0; /* Noch nichts gelesen */ |
| Idx=ParaNum(3); /* Lege Startadresse fest */ |
| End=(ParaStr(4)==NULL) /* Endadr ist optional */ |
| ? 0xffffffffl : ParaNum(4); |
| |
| if (Idx<=End) |
| { /* Falsche Werte abweisen */ |
| if ((InF=fopen(Nam,(Hex) ? "rt":"rb"))!=NULL) |
| { |
| if (Hex) |
| { /* Intel-Hex gewuenscht? */ |
| fscanf(InF,"%x",Idx); |
| while (!feof(InF)) |
| { /* Bis zum Ende lesen */ |
| fgets(Stg,sizeof(Stg),InF); |
| if (strlen(Stg)>1) |
| { /* Ignoriere leere Zeilen */ |
| PSt=strchr(Stg,':'); /* Doppelpunkt ist obligat */ |
| if (PSt!=NULL) PSt++; /* Hinter ':' stellen */ |
| Len=GibNum(&PSt,'2'); /* Hole Recordlaenge */ |
| Adr=GibNum(&PSt,'4'); /* Hole Adresse */ |
| Typ=GibNum(&PSt,'2'); |
| if (!Typ) |
| { /* Datencode erkannt? */ |
| while (PSt!=NULL && Len) |
| { |
| WriteByte(nInterfaceHandle, Idx+Adr++,(char)GibNum(&PSt,'2'),AdrMode); |
| Cnt++; /* 1 Byte mehr gelesen */ |
| Len--; /* Laenge aufaddieren */ |
| } /* while */ |
| |
| if (GetError(nInterfaceHandle)) |
| { /* Fehlerpruefung: VME-Transfer ok? */ |
| ClearError(nInterfaceHandle); /* Fehlerflag zuruecksetzen */ |
| printf("--> Bus error: Adr=%08lx. ",Idx+Adr); |
| break; /* Abbruch mit Fehler */ |
| } /* if */ |
| } |
| else |
| { |
| if (Typ==1) |
| { /* Endcode erkannt? */ |
| Ret=0; /* Fehlerfrei gelesen */ |
| break; /* Ende while */ |
| } /* Ignoriere andere Typen */ |
| } /* else */ |
| if (PSt==NULL) |
| { |
| printf("Format error\n"); |
| break; |
| } /* if */ |
| } /* if len */ |
| } /* while */ |
| } |
| else |
| { /* Kein Intel-Hex-Format */ |
| do |
| { |
| if (feof(InF)) Idx=End; /* Ende der Datei erreicht */ |
| else |
| { |
| WriteByte(nInterfaceHandle, Idx,(char)fgetc(InF),AdrMode); |
| if (GetError(nInterfaceHandle)) |
| { /* Fehlerpruefung: VME-Transfer ok? */ |
| ClearError(nInterfaceHandle); /* Fehlerflag zuruecksetzen */ |
| printf("--> Bus error: Adr=%08lx. ",Idx); |
| break; /* Abbruch mit Fehler */ |
| } /* if GetError */ |
| |
| Cnt++; /* Ein Byte mehr gelesen */ |
| } /* else */ |
| } while (Idx++<End); /* Bis einschliesslich End lesen */ |
| fclose(InF); |
| if (Idx==End+1) Ret=0; /* Genug Byte geschafft? */ |
| } /* else Hex */ |
| } /* if fopen */ |
| else printf("Can't read file %s. ",Nam); |
| } /* if */ |
| printf("%lx Byte(s) read\n",Cnt); |
| } /* if */ |
| else printf("\a"); |
| return(Ret); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // seek for a pattern in VME BUS |
| static void SeekPatt(void) /* Suche nach Datenmustern */ |
| { |
| #define Max 32 /* Wieviele Suchbytes max. */ |
| unsigned long DefVon; /* Startadresse */ |
| unsigned long End; /* Endadresse */ |
| int Idx; /* Index */ |
| int Idy; /* Auch Index */ |
| int Len; /* Item Laenge */ |
| int Ok; /* Flag: gefunden oder nicht? */ |
| int Merk_error = 0; /* Fehler Flip-Flop */ |
| |
| union |
| { /* Suchmuster */ |
| unsigned char xs[Max]; |
| unsigned int xw[Max/2]; |
| unsigned long xl[Max/4]; |
| } Patt; |
| |
| if (ParaStr(4) != NULL) |
| { /* Von, Bis und 1 Item obligat */ |
| DefVon=ParaNum(2); /* Startadresse festlegen */ |
| End=ParaNum(3); /* Endadresse festlegen */ |
| Len=1; |
| switch (GetZug(&DefZug)) |
| { /* Zugriffsmodus festlegen */ |
| case 'L':Len+=2; /* Auf Long-Adresse biegen */ |
| case 'W':Len++; /* Auf Wort-Adresse biegen */ |
| } |
| |
| DefVon&=-(long)Len; /* Adressen geradebiegen */ |
| Idx=0; /* Suchmuster sammeln */ |
| while (Idx<Max/Len && ParaStr(Idx+4)!=NULL) |
| { |
| switch (DefZug) |
| { |
| case 'L':Patt.xl[Idx]=ParaNum(Idx+4); break; |
| case 'W':Patt.xw[Idx]=(unsigned)ParaNum(Idx+4); break; |
| case 'B':Patt.xs[Idx]=(unsigned char)ParaNum(Idx+4); break; |
| } /* switch */ |
| Idx++; /* Ein Item mehr da */ |
| } /* while */ |
| |
| while ((DefVon<=End) && (!Abbruch)) |
| { /* Suche nun den Bereich ab */ |
| Ok=True; /* Pattern an dieser Adresse? */ |
| for (Idy=0; Idy<Idx && Ok; Idy++) |
| { |
| switch (DefZug) |
| { |
| case 'L':if (Patt.xl[Idy] != (unsigned long)ReadLong(nInterfaceHandle, DefVon+(Idy<<2),AdrMode)) |
| Ok=False; |
| break; |
| case 'W':if (Patt.xw[Idy] != (unsigned short)ReadWord(nInterfaceHandle, DefVon+(Idy<<1),AdrMode)) |
| Ok=False; |
| break; |
| case 'B':if (Patt.xs[Idy] != (unsigned char)ReadByte(nInterfaceHandle, DefVon+Idy,AdrMode)) |
| Ok=False; |
| break; |
| } /* switch */ |
| |
| if (GetError(nInterfaceHandle)) |
| { /* Busfehler aufgetreten? */ |
| ClearError(nInterfaceHandle); /* Fehlerflags zuruecksetzen */ |
| Ok=False; /* Gefunden wurde auch nichts */ |
| Merk_error = 1; /* Setze Flip-Flop */ |
| } |
| } /* for */ |
| if (Ok) printf("%08lx\n",DefVon);/* Was gefunden: Adresse ausgeben */ |
| DefVon+=Len; |
| |
| if ((DefVon & 0xffl)==0) |
| { /* Ermoegliche Abbruch mit Ctrl-C */ |
| printf("\r"); |
| } |
| } /* while */ |
| if (Merk_error) printf("--> Failed to search\n"); |
| } |
| else printf("\a"); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // emulate a 68K test and set instruction |
| static void TestSet() /* Fuehre ein Test and Set auf */ |
| { /* Bit #7 eines Byte-Ports aus. */ |
| char Erg; |
| |
| if (ParaStr(2)!=NULL) |
| { /* Adresse ist obligat */ |
| Erg=TAS(nInterfaceHandle, ParaNum(2),AdrMode); /* Ergebnis merken, damit ein */ |
| if (GetError(nInterfaceHandle)) |
| { /* Fehler ausgegeben werden kann */ |
| ClearError(nInterfaceHandle); |
| printf("--> Failed to 'Test and Set'\n"); /* Zugriff gescheitert */ |
| } |
| else printf("Semafore @ 0x%08lx was%s set before.\n", |
| ParaNum(2),(Erg) ? "" : " not"); |
| } |
| else printf("\a"); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // raise a VME SYSRESET |
| static void ResetVme(void) /* Generiere SysReset auf VME-Bus */ |
| { /* Interrupt bei MailBox beachten */ |
| printf("Reset to VME raised.\n"); |
| Reset_VME(nInterfaceHandle); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // print out a line in HEX format |
| static int OutHex(FILE *OuF, int Siz, unsigned long Adr,int Typ, char Buf[]) |
| { |
| int Chk; /* Pruefsumme */ |
| int Idx; /* Laufindex */ |
| |
| fprintf(OuF,":%02X%04X%02X",Siz,Adr,Typ); |
| Chk=Siz+(Adr & 0xff)+(Adr>>8)+Typ; |
| for (Idx=0; Idx<Siz; Idx++) |
| { /* Pufferinhalt ausgeben */ |
| fprintf(OuF,"%02X",(unsigned char)Buf[Idx]); |
| Chk+=Buf[Idx]; /* Pruefsumme mitrechnen */ |
| } |
| fprintf(OuF,"%02X\n",(unsigned char)-Chk); /* Pruefsumme ausgeben */ |
| if (ferror(OuF)) |
| { /* Irgend ein Schreibfehler? */ |
| printf("Failed to write. "); |
| return(False); |
| } |
| else return(True); /* Fehlerfrei ausgefuehrt */ |
| } |
| |
| //----------------------------------------------------------------------------- |
| // write a file in HEX and get the data from VME |
| static int _WriteFile() /* Schreibt eine Datei aus VME */ |
| { |
| unsigned long End; /* Endadresse */ |
| unsigned long Idx; /* Laufadresse */ |
| unsigned long Cnt; /* Bytezaehler */ |
| int Ret; /* Returncode */ |
| int Adr; /* Adresse Record ab Start */ |
| int Hex; /* Intel Hex File? */ |
| char Buf[16]; /* Output-Puffer */ |
| STRG Nam; /* Dateiname */ |
| FILE *OuF; /* Lesedatei */ |
| |
| Ret=1; /* Vorgabe ist Fehler */ |
| if (ParaStr(4)!=NULL) |
| { /* Start & Endadr sind obligat */ |
| Hex=(ParaStr(1)[1]=='X'); /* Intel-Hex gewuenscht? */ |
| strcpy(Nam,ParaStr(2)); /* Dateinamen kopieren */ |
| *strchr(Nam,' ')='\0'; /* Restparameter abschneiden */ |
| Cnt=0; /* Noch nichts gelesen */ |
| Idx=ParaNum(3); /* Lege Startadresse fest */ |
| End=ParaNum(4); /* Lege Endadresse fest */ |
| if (Idx<=End) |
| { /* Falsche Werte abweisen */ |
| if ((OuF=fopen(Nam,(Hex) ? "wt":"wb"))!=NULL) |
| { |
| if (Hex) |
| { /* Intel-Hex gewuenscht? */ |
| Buf[0]=0 >> 0x8; /* HighByte Segmentadresse */ |
| Buf[1]=0 & 0xff; /* LowByte Segmentadresse */ |
| Adr=0; /* Offset grundsaetzlich bei 0 */ |
| if (OutHex(OuF,2,Adr,2,Buf)) |
| { |
| do |
| { |
| Buf[(int)Cnt & 0xf]=ReadByte(nInterfaceHandle, Idx,AdrMode); |
| if (GetError(nInterfaceHandle)) |
| { /* Fehlerpruefung: VME-Transfer ok? */ |
| ClearError(nInterfaceHandle); /* Fehlerflag zuruecksetzen */ |
| printf("--> Bus error: Adr=%08lx. ",Idx); |
| break; /* Abbruch */ |
| } /* if GetError */ |
| if (!((int)++Cnt & 0xf)) |
| { |
| if (OutHex(OuF,16,Adr,0,Buf)) Adr+=16; |
| else break; /* Zwischendurch Puffer schreiben */ |
| } |
| } while (Idx++<End); /* Bis einschließlich End schreiben */ |
| |
| if ((Idx==End+1) && /* Noch Rest im Puffer? */ |
| (!((int)Cnt & 0xf) || |
| OutHex(OuF,(int)Cnt & 0xf,Adr,0,Buf)) |
| && OutHex(OuF,0,0,1,NULL)) Ret=0; |
| } /* if */ /* Wenn Eof ausgegeben, Returns ok */ |
| } /* if Hex */ |
| else |
| do |
| { /* Nicht Intel-Hex */ |
| fputc(ReadByte(nInterfaceHandle, Idx,AdrMode),OuF); |
| if (GetError(nInterfaceHandle)) |
| { /* Fehlerpruefung: VME-Transfer ok? */ |
| ClearError(nInterfaceHandle); /* Fehlerflag zuruecksetzen */ |
| printf("--> Bus error: Adr=%08lx. ",Idx); |
| break; /* Abbruch */ |
| } /* if GetError */ |
| if (ferror(OuF)) |
| { |
| printf("Failed to write. "); |
| break; /* Abbruch */ |
| } /* if ferror */ |
| Cnt++; /* Ein Byte mehr geschrieben */ |
| } while (Idx++<End); /* Bis einschließlich End schreiben */ |
| |
| if (Idx==End+1) Ret=0; /* Genug Byte geschafft? */ |
| fclose(OuF); |
| } /* if fopen */ |
| else |
| printf("Can' open file %s. ",Nam); |
| } /* if */ |
| printf("%lx Byte(s) written.\n",Cnt); |
| } /* if */ |
| else |
| printf("\a"); |
| return(Ret); |
| } |
| |
| |
| //----------------------------------------------------------------------------- |
| // show and provide help about the VME address modifiers |
| static void ShowModifier(int Mode) /* Klartext fuer Adressmodifier */ |
| { |
| printf("Address modifier:\t%02x [", Mode); |
| if ((Mode & 0x3b) > 0x38) printf("standard"); |
| else if ((Mode & 0x3b)==0x29) printf("short"); |
| else if ((Mode & 0x3b)>=0x09 && (Mode & 0x3b)<=0x0b) printf("extendet"); |
| else if (Mode>=0x20 || Mode<=0x0f) |
| { |
| printf("reserved]\n"); return; |
| } |
| else |
| { |
| printf("user defined]\n"); return; |
| } |
| printf(((Mode & 0x0f)>=0x0c) ? " supervisory":" non-privileged"); |
| switch (Mode & 0x03) |
| { |
| case 1:printf(" data access"); break; |
| case 2:printf(" code access"); break; |
| case 3:printf(" block transfer"); break; |
| } |
| printf("]\n"); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // provides some diagnostic information abot interface registers |
| static void ShowRegister(void) /* Zeige Inhalt von ? */ |
| { |
| char *szInstg; |
| char type; |
| |
| if ((szInstg = ParaStr(1)) == NULL) |
| type = '0'; |
| else |
| type = szInstg[1]; |
| |
| if (type == 0) |
| type = '0'; |
| |
| GetInterfaceInfo(nInterfaceHandle, type); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // make a random memory test to VME |
| static void RandomTest(void) |
| { |
| char DefZug = ' '; /* Zugriffsart */ |
| int Len; /* Item Laenge */ |
| unsigned long Idx; /* Index */ |
| unsigned long End; /* Endadresse */ |
| unsigned long Seed; /* initial seed */ |
| unsigned char Merk_error = 0; /* Haelt error flag */ |
| int Patt; |
| unsigned long i; |
| |
| unsigned long lResult; |
| unsigned short wResult; |
| unsigned char bResult; |
| int repeats = 0; |
| int Loop = 0; |
| |
| if (GetZug(&DefZug)!=' ') |
| { |
| Len=1; |
| switch (GetZug(&DefZug)) /* Zugriffsmodus festlegen */ |
| { |
| case 'L':Len += 2; /* Auf Long-Adresse biegen */ |
| case 'W':Len++; /* Auf Wort-Adresse biegen */ |
| } |
| Idx=ParaNum(2) & -(long)Len; /* Adressen geradebiegen */ |
| End=ParaNum(3); /* Endadresse festlegen */ |
| if (ParaStr(4) == NULL) |
| Loop = 1; |
| else |
| Loop=ParaNum(4); |
| if (ParaStr(5) == NULL) |
| Seed = 0x1234; |
| else |
| Seed=ParaNum(5); |
| |
| do |
| { |
| srand(Seed + repeats); |
| i = Idx; |
| while ((i <= End) && (!Abbruch)) |
| { |
| Patt = rand(); |
| |
| switch (DefZug) |
| { |
| case 'L':Patt <<= 16; |
| Patt |= rand(); |
| WriteLong(nInterfaceHandle, i, Patt, AdrMode); |
| break; |
| case 'W':WriteWord(nInterfaceHandle, i, (short)Patt, AdrMode); |
| break; |
| case 'B':WriteByte(nInterfaceHandle, i, (char)Patt, AdrMode); |
| break; |
| } /* switch */ |
| |
| if (GetError(nInterfaceHandle)) |
| { |
| ClearError(nInterfaceHandle); /* Fehler abfangen */ |
| Merk_error |= 2; |
| } |
| |
| if ((i & 0xffl)==0) |
| { /* Ermoegliche Ctrl-C */ |
| printf("\r"); |
| } |
| |
| i += Len; |
| } /* while */ |
| |
| // read and compare |
| srand(Seed + repeats); |
| i = Idx; |
| while ((i <= End) && (!Abbruch)) |
| { |
| Patt = rand(); |
| |
| switch (DefZug) |
| { |
| case 'L':lResult = ReadLong(nInterfaceHandle, i, AdrMode); |
| Patt <<= 16; |
| Patt |= rand(); |
| if (lResult != (unsigned long)Patt) |
| { |
| printf("Compare Fail 0x%08x w=0x%08lx r=0x%08lx\n", i, Patt, lResult); |
| Merk_error |= 1; |
| } |
| break; |
| case 'W':wResult = ReadWord(nInterfaceHandle, i, AdrMode); |
| if (wResult != (unsigned short)Patt) |
| { |
| printf("Compare Fail 0x%08x w=0x%04x r=0x%04x\n", i, Patt & 0xFFFF, wResult); |
| Merk_error |= 1; |
| } |
| break; |
| case 'B':bResult = ReadByte(nInterfaceHandle, i, AdrMode); |
| if (bResult != (unsigned char)Patt) |
| { |
| printf("Compare Fail 0x%08x w=0x%02x r=0x%02x\n", i, Patt & 0xFF, bResult); |
| Merk_error |= 1; |
| } |
| break; |
| } /* switch */ |
| |
| if (GetError(nInterfaceHandle)) |
| { |
| ClearError(nInterfaceHandle); /* Fehler abfangen */ |
| Merk_error |= 2; |
| } |
| |
| if ((i & 0xffl)==0) |
| { /* Ermoegliche Ctrl-C */ |
| printf("\r"); |
| } |
| |
| i += Len; |
| } /* while */ |
| |
| if (Loop) |
| printf("\rRepeats: 0x%x\r", repeats); |
| repeats++; |
| } while ((Loop--) && !(Merk_error)); |
| |
| if (Merk_error) |
| printf("--> Compare failed %s\a\n", (Merk_error & 2) ? "with Bus Error" : ""); |
| else |
| printf("--> Compare successfull\n"); |
| |
| } |
| else printf("\a"); |
| |
| } |
| |
| //----------------------------------------------------------------------------- |
| // modify interface registers |
| static void ModifyRegister(void) |
| { |
| __u32 Erg; |
| |
| if (ParaStr(2) != NULL) |
| { |
| if (ParaStr(3) != NULL) |
| { |
| Erg = _SetRegister(nInterfaceHandle, ParaNum(2),ParaNum(3)); |
| printf("Interface register @ 0x%08lx set: 0x%02x, get: 0x%02x\n", |
| ParaNum(2), ParaNum(3), Erg); |
| } |
| else |
| { |
| Erg = _GetRegister(nInterfaceHandle, ParaNum(2)); |
| printf("Interface register @ 0x%08lx get: 0x%02x\n", ParaNum(2), Erg); |
| } |
| } |
| else |
| printf("\a"); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // the main menu |
| static int HauptMenue(STRG Stg) /* Eingabe & Dispatcher */ |
| { |
| char *SSt; /* Sourcezeiger */ |
| char *DSt; /* Destzeiger */ |
| char Del; /* Delimiter vorhanden? */ |
| int Ret; /* Returncode fuer Auto-Mode */ |
| char loop; /* irgedwie war baengg fuer loop */ |
| |
| |
| if (Stg == NULL) |
| loop = 1; |
| else |
| loop = 0; |
| |
| do |
| { |
| if (loop) |
| { /* Auto-Modus? */ |
| if (Abbruch) |
| { |
| printf("\n"); |
| Abbruch = 0; |
| } |
| |
| printf("pv: "); /* Nein, Prompt ausgeben und */ |
| if (*ReadMessageBuffer()) |
| { |
| printf("%s\n", ReadMessageBuffer()); |
| printf("pv: "); |
| InitMessageBuffer(); |
| } |
| _gets(InStg); /* Eingabestring holen */ |
| // GetError(nInterfaceHandle); /* because of interrupts */ |
| SSt=InStg; /* Init Sourcezeiger */ |
| } |
| else |
| SSt=Stg; /* Uebernehme Parameter aus Stg */ |
| |
| DSt=InStg; /* Init Destzeiger */ |
| Del=True; /* Weitere Delimiter raus */ |
| Ret=0; /* Keine Fehler bis jetzt */ |
| |
| while (*SSt) |
| { /* Arbeite String ab */ |
| if (UpCase(*SSt) >= 'A' && /* Filtern gueltiger Zeichen */ |
| UpCase(*SSt) <= 'Z' || |
| *SSt >= '0' && *SSt <= '9' || |
| *SSt == ':' || *SSt == '.' || |
| *SSt == '\\' || *SSt == '?') |
| { |
| *DSt=UpCase(*SSt); |
| Del=False; |
| DSt++; |
| } |
| else |
| { |
| if (!Del) |
| { |
| *DSt=' '; |
| DSt++; |
| } /* Mehrere Delimiter raus */ |
| Del=True; /* und durch ' ' ersetzen */ |
| } |
| SSt++; |
| } /* while (*SSt) */ |
| *DSt=*SSt; /* 0 auch uebertragen */ |
| |
| switch (*ParaStr(1)) |
| { |
| case 'A': SetModifier(); break; |
| case 'D': Dump(); break; |
| case 'E': Examine(); break; /* Speicherbereich aendern */ |
| case 'F': Fill(); break; /* Speicherbereich fuellen */ |
| case 'G': RandomTest(); break; /* random test of memory */ |
| case 'H': |
| case '?': Hilfe(); break; /* Hilf mir mal */ |
| case 'I': DeInit_Interface(nInterfaceHandle); |
| InitAt(cszDevicePath, &nInterfaceHandle); |
| break; /* Nochmals initialisieren */ |
| case 'C': Konfig(); break; /* Konfiguration */ |
| case 'L': ReadIrqVect(); break; /* Interrupt-Vektoren lesen */ |
| case 'M': Move(); break; /* Move Funktion */ |
| case 'O': JumpToDos(); break; /* DOS Ausgang */ |
| case 'P': SearchPorts(); break; /* Ports suchen */ |
| case 'Q': Raus();return(0); /* Ende des Debuggers */ |
| case 'R': Ret=_ReadFile(); break; /* Eine Datei nach VME lesen */ |
| case 'S': SeekPatt(); break; /* Suche nach Datenmustern */ |
| case 'T': TestSet(); break; /* Fuehre ein TAS aus */ |
| case 'V': ResetVme(); break; /* Erzeuge VME-Reset */ |
| case 'W': Ret=_WriteFile(); break;/* Eine Datei von VME schreiben */ |
| case 'Y': SysFail(); break; /* read, set Sysfail */ |
| case 'X': ModifyRegister(); break; /* modify register of the interface */ |
| case 'Z': ShowRegister(); break; /* Register ausgeben */ |
| default : |
| { |
| Ret=2; /* Fehlercode zurueck fuer Auto */ |
| if (!loop) |
| { /* Wenn Auto: Hilfsmessage */ |
| Hilfe(); |
| printf("\nSplit commands with \"/\" ,e.g. \"a39/d1000\""); |
| } |
| } |
| } /* switch */ |
| } while (loop); /* Hier raus bei Auto-Mode */ |
| return(Ret); |
| } |
| |
| //------------------------------------------------------------------------------------- |
| // the exit entry |
| static void MyExit(int bla) /* Wird im Ctrl-C-Falle aufgerufen */ |
| { |
| Abbruch = 1; |
| } |
| |
| //------------------------------------------------------------------------------------- |
| // where all starts |
| int main(int argc, char **argv, char *envp[]) |
| { |
| static STRG Stg; /* Zum zusammenlegen Parameter */ |
| char *PSt; /* Arbeitszeiger Multicommands */ |
| char *SSt; /* Quellzeiger Multicommands */ |
| int Idx; /* Index */ |
| int Ret; /* Returncode */ |
| |
| InitMessageBuffer(); |
| |
| cszDevicePath = &localBuffer[0]; |
| |
| Ret=1; /* Returncode auf Fehler setzen */ |
| ArgV=argv; /* Uebertrage argv fuer LoadKonfig */ |
| LoadKonfig(); /* Versuchen Konfigdatei zu lesen */ |
| |
| if (argc > 1) |
| { /* Kommandozeilenparameter da? */ |
| if (InitAt(cszDevicePath, &nInterfaceHandle)) |
| { /* Aufsetzen Interface */ |
| *Stg='\0'; /* Stg auf nix setzen */ |
| for (Idx=1; Idx < argc; Idx++) |
| { |
| strcat(Stg,argv[Idx]); /* Haenge Parameter hintereinander */ |
| strcat(Stg," "); /* Trenne mit Leerzeichen */ |
| } |
| |
| SSt=Stg; /* Saubloedes (*Zeug) mit den ARRAYS! */ |
| do |
| { |
| if ((PSt=strchr(SSt,'/'))!=NULL) *PSt='\0'; |
| Ret=HauptMenue(SSt); /* Hauptmenue automatisch aufrufen */ |
| SSt=PSt+1; /* SSt auf den Reststring setzen */ |
| } |
| |
| while (PSt!=NULL && !Ret); /* Bis Fehler oder Fertig */ |
| } |
| } |
| else |
| { |
| printf("Provided under GPL - version %s of pvmon of %s \n\n", VERSION, __DATE__); |
| printf("This program is free software; you can redistribute it and/or modify it\n"); |
| printf("under the terms of the GPL as published by the FSF (version 2 or later).\n"); |
| printf("Copyright: Ralf Dux, Sven Hannover, Klaus Hitschler, Sven Tuecke, AR\n"); |
| |
| InitAt(cszDevicePath, &nInterfaceHandle); /* Aufsetzen Interface */ |
| signal(SIGINT, MyExit); /* Eigenen Handler einklinken */ |
| Ret=HauptMenue(NULL); /* Hauptmenue manuell aufrufen */ |
| } /* else */ |
| DeInit_Interface(nInterfaceHandle); /* Interface ausschalten */ |
| |
| return(Ret); /* Fehlercode fuer ErrorLevel */ |
| } |
| |
| //------------------------------------------------------------------------------------------- |
| //------------------------------------------------------------------------------------------- |
| //------------------------------------------------------------------------------------------- |