//-------------------------------------------------------------------------------------------
 
// 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,
 
                        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
 
{  
 
    return SLang_getkey();
 
}
 
 
 
 
 
static void strlwr(char *str)
 
{
 
    int i;
 
    char *ptr = str;
 
 
 
    for (i = 0; ((i < BUFFERLENGTH) && (*ptr)); i++)
 
    {
 
        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);
 
}
 
 
 
//-----------------------------------------------------------------------------
 
// 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))
 
                {
 
                }
 
            }
 
        }
 
        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
 
            {
 
                if (Asc != NULL) *(unsigned long *)Asc=xl;
 
            }
 
            break;
 
        case 'W': xi=ReadWord(nInterfaceHandle, Addr, AdrMode);
 
            if (GetError(nInterfaceHandle))
 
            {
 
                ClearError
(nInterfaceHandle
); printf("**** "); 
            }
 
            else
 
            {
 
                if (Asc != NULL) *(unsigned short *)Asc=xi;
 
            }
 
            break;
 
        case 'B': xc=ReadByte(nInterfaceHandle, Addr, AdrMode);
 
            if (GetError(nInterfaceHandle))
 
            {
 
                ClearError
(nInterfaceHandle
); printf("**"); 
            }
 
            else
 
            {
 
                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
 
}
 
 
 
 
 
//-----------------------------------------------------------------------------
 
// 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 */
 
 
 
    for (Idx=0; Idx < (DefVon & 0x0f)/Len*(2*Len+1); Idx++)
 
 
 
    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)))
 
        {
 
            for (Idx=0; Idx < sizeof(Asc); Idx++)
 
            {
 
                if (Asc
[Idx
] < ' ') printf("."); /* Ascii-String ausgeben */  
                else printf("%c", Asc
[Idx
]);   /* Ctrl-Zeichen als Punkte */  
            }
 
 
 
            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 */
 
                SLtt_flush_output();
 
 
 
                End=GetStrg(Stg,Len << 1);     /* Hole begrenzte Eingabezeile */
 
 
 
                for (Idx
=strlen(Stg
); Idx
<2+(Len 
<< 1); Idx
++)  
                {                              /* 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> */
 
 
 
            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 */
 
            }
 
            Idx+=Len;
 
        } /* while */
 
        if (Merk_error
) printf("--> Memory fill failed\a\n");  
    }
 
}
 
 
 
//-----------------------------------------------------------------------------
 
// 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 */
 
            }
 
 
 
            Idx+=Len;
 
            Dest+=Len;
 
        } /* while */
 
        if (Merk_error
) printf("--> Memory move failed\a\n");  
    }
 
}
 
 
 
//-----------------------------------------------------------------------------
 
// 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("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 */
 
    {
 
        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)
 
    {
 
        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 */  
 
 
        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]))
 
    {
 
        change |= 1;
 
    }
 
 
 
    InS[0] = 0;
 
    printf("Default address modifier (%02x):",AdrMode
); /* und den default Modifier */  
    _gets(InS);
 
    if ((InS[0] != '\n') && (InS[0]))
 
    {
 
        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]))
 
    {
 
        change |= 8;
 
    }
 
    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
);  
                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 */
 
    }
 
    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);  
 
 
    {
 
        Ende = 0x01000000L;                /* alle Standards */
 
        Step = 0x100;                      /* Stepweite      */
 
    }
 
 
 
    {
 
        Ende = 0x00010000L;                /* Shorts */
 
        Step = Anz;
 
    }
 
 
 
    {
 
        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 */
 
                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      */  
 
 
    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
); 
}
 
 
 
//-----------------------------------------------------------------------------
 
// 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? */
 
                    {                            /* Bis zum Ende lesen */
 
                        fgets(Stg
,sizeof(Stg
),InF
);  
                        {                          /* 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)
 
                            {
 
                                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 */
 
                    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 */
 
    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 */
 
            }
 
        } /* while */
 
        if (Merk_error
) printf("--> Failed to search\n");  
    }
 
}
 
 
 
//-----------------------------------------------------------------------------
 
// 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");
 
    }
 
}
 
 
 
//-----------------------------------------------------------------------------
 
// 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 */  
    {                                    /* Irgend ein Schreibfehler? */
 
        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 */
 
                        {                          
 
                            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? */
 
            } /* if fopen */
 
            else
 
                printf("Can' open file %s. ",Nam
);  
        } /* if */
 
        printf("%lx Byte(s) written.\n",Cnt
);  
    } /* if */
 
    else
 
    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;  
    }
 
}
 
 
 
//-----------------------------------------------------------------------------
 
// 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
 
        {
 
            i = Idx;
 
            while ((i <= End) && (!Abbruch))
 
            {
 
 
 
                switch (DefZug)
 
                {
 
                    case 'L':Patt <<= 16;
 
                        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 */
 
                }
 
 
 
                i += Len;
 
            } /* while */
 
 
 
            // read and compare
 
            i = Idx;
 
            while ((i <= End) && (!Abbruch))
 
            {
 
 
 
                switch (DefZug)
 
                {
 
                    case 'L':lResult = ReadLong(nInterfaceHandle, i, AdrMode);
 
                        Patt <<= 16;
 
                        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 */
 
                }
 
 
 
                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");  
 
 
    }
 
 
 
}
 
 
 
//-----------------------------------------------------------------------------
 
// 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
 
}
 
 
 
//-----------------------------------------------------------------------------
 
// 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)
 
            {
 
                Abbruch = 0;
 
            }
 
 
 
            printf("pv: ");                  /* Nein, Prompt ausgeben und */  
            if (*ReadMessageBuffer())
 
            {
 
                printf("%s\n", ReadMessageBuffer
());  
                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 */
 
}
 
 
 
//-------------------------------------------------------------------------------------------
 
//-------------------------------------------------------------------------------------------
 
//-------------------------------------------------------------------------------------------