Subversion Repositories f9daq

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
9 f9daq 1
//-------------------------------------------------------------------------------------------
2
// pvmon.c - the body of a simple tool to access VME BUS resources
3
//
4
// (c) 1999-2002 ARW Elektronik
5
//
6
// this source code is published under GPL (Open Source). You can use, redistrubute and 
7
// modify it unless this header  is  not modified or deleted. No warranty is given that 
8
// this software will work like expected.
9
// This product is not authorized for use as critical component in life support systems
10
// wihout the express written approval of ARW Elektronik Germany.
11
//
12
// Please announce changes and hints to ARW Elektronik
13
// 
14
// $Log: pvmon.c,v $
15
// Revision 1.6  2002/11/14 19:57:56  klaus
16
// improvement, still bugs active
17
//
18
// Revision 1.5  2002/10/20 18:07:48  klaus
19
// mostly working alpha version
20
//
21
// Revision 1.4  2002/10/20 11:49:33  klaus
22
// first parts working
23
//
24
// Revision 1.3  2002/10/19 09:47:30  klaus
25
// first success compiling project
26
//
27
// Revision 1.2  2002/10/19 09:44:38  klaus
28
// first success compiling project
29
//
30
// Revision 1.1.1.1  2002/10/18 22:14:29  klaus
31
//
32
// first parts written and published from
33
// Sven Hannover, Sven Tuecke, Klaus Hitschler, Ralf Dux                                        1991
34
//
35
 
36
//-------------------------------------------------------------------------------------------
37
// INCLUDES
38
//
39
#include <unistd.h>
40
#include <sys/types.h>
41
#include <sys/ioctl.h>
42
#include <sys/stat.h>
43
#include <fcntl.h>
44
#include <errno.h>
45
 
46
#include <setjmp.h>
47
#include <signal.h>
48
#include <stdio.h>
49
#include <stdlib.h>
50
#include <string.h>
51
#include <time.h>
52
 
53
#include <slang.h>
54
 
55
#include <../driver/vme.h>                      /* constants about VME BUS     */
56
#include <mbuffer.h>                    /* simple message buffering    */
57
#include <pcilibLx.h>                   /* device access  functions    */
58
 
59
//-------------------------------------------------------------------------------------------
60
// DEFINES
61
//
62
#define VERSION "6.0Lx"
63
#define True 1
64
#define False 0
65
 
66
#if !defined(FALSE) || !defined(TRUE)
67
#define FALSE False
68
#define TRUE  True
69
#endif
70
 
71
#define DEVPATH " - No input neccessary!"                 // not used
72
#define DEFDEVICENAME "/dev/vmemm_1"
73
#define DEFAULT_ADDRESS   0x00000000                      // default VME window base address
74
#define DEFAULT_MODIFIER  Std_NoPriv_Data                 // default address modifier
75
#define DEFAULT_TYPE      sizeof(char)                    // default data BUS access width
76
#define MAX_TIMEOUT_LOOPS 100000                          // maximum loops for waiting reset finished
77
 
78
//-------------------------------------------------------------------------------------------
79
// TYPEDEFS
80
//
81
typedef char STRG[BUFFERLENGTH];                /* Allgemeiner Stringtyp */
82
 
83
//-------------------------------------------------------------------------------------------
84
// LOCALS
85
//
86
static char  UpCase(char Zchn);            
87
static char *ParaStr(int Num);
88
static unsigned long ParaNum(int Num);
89
static void  SetModifier(void);
90
static void  PrintItem(unsigned long Addr, char Mode, unsigned char *Asc);
91
static char  GetZug(char *Zug);
92
static void  Dump(void);
93
static char  GetStrg(STRG Stg, int Len);
94
static void  Examine(void);
95
static void  Move(void);
96
static void  Fill(void);
97
static void  Hilfe(void);
98
static int   InitAt(char *szDevicePath, int *nInterfaceHandle);
99
static void  CfgName(STRG Stg);
100
static void  LoadKonfig(void);
101
static void  Konfig(void);
102
static void  ReadIrqVect(void);
103
static void  JumpToDos(void);
104
static void  Raus(void);
105
static void  SearchPort(char *Art,
106
                        int Anz,
107
                        unsigned short modf,
108
                        void(*SFunc)(int nHandle, unsigned long Adr,unsigned short AModifier));
109
static void  SearchPorts(void);
110
static unsigned GibNum(char **PSt,char Anz);
111
static int   _ReadFile(void);
112
static void  SeekPatt(void);
113
static void  TestSet(void);
114
static void  ResetVme(void);
115
static int   OutHex(FILE *OuF, int Siz, unsigned long Adr, int Typ, char Buf[]);
116
static int   _WriteFile(void);
117
static void  ShowModifier(int Mode);
118
static void  ShowRegister(void);
119
static int   HauptMenue(STRG Stg);
120
static void  MyExit(int);
121
static void  SysFail(void);
122
 
123
//-------------------------------------------------------------------------------------------
124
// EXTERNALS
125
//
126
 
127
//-------------------------------------------------------------------------------------------
128
// GLOBALS
129
//
130
static unsigned short AdrMode = Short_NoPriv;  /* Mein initialer Adressmodifier */
131
static char DefZug = 'B';                /* Default Zugriff */
132
static char DefVec = 'B';                /* Default Zugriff IrqVecs */
133
static char **ArgV;                      /* ArgV aus main() */
134
static STRG InStg;                       /* Allgemeiner Eingabestring */
135
 
136
static char *TsT;
137
static char Abbruch = 0;                 /* verzweig wg. SIGINT */
138
 
139
static int  nInterfaceHandle;            /* handle of device */
140
static char *cszDevicePath;              /* path of device */
141
static int  WordMode;                    /* mode of VME path operation */
142
 
143
static char localBuffer[BUFFERLENGTH] = DEFDEVICENAME;
144
 
145
//-------------------------------------------------------------------------------------------
146
// FUNCTIONS
147
//
148
//-----------------------------------------------------------------------------
149
// functions to emulate for this platform
150
static int getch(void)
151
{  
152
    return SLang_getkey();
153
}
154
 
155
 
156
static void strlwr(char *str)
157
{
158
    int i;
159
    char *ptr = str;
160
 
161
    for (i = 0; ((i < BUFFERLENGTH) && (*ptr)); i++)
162
    {
163
        *ptr = tolower(*ptr);
164
        ptr++;
165
    }
166
}
167
 
168
static int _gets(char *str)
169
{
170
    if (fgets(str, BUFFERLENGTH, (FILE *)stdin) == NULL)
171
        return EINVAL;
172
    else
173
    {
174
        // remove '\n' from string
175
        int i;
176
        char *ptr = str;
177
 
178
        for (i = 0; i < BUFFERLENGTH; i++, ptr++)
179
        {
180
            if (*ptr == '\n')
181
            {
182
                *ptr = 0;
183
                break;
184
            }
185
        }
186
        return 0;
187
    }
188
}
189
 
190
//-----------------------------------------------------------------------------
191
// get out of here
192
static void Raus(void)
193
{
194
    DeInit_Interface(nInterfaceHandle);
195
    exit(0);
196
}
197
 
198
//-----------------------------------------------------------------------------
199
// return the uppercase char
200
static char UpCase(char Zchn)                  /* Upcase eines Zeichens */
201
{
202
    return((Zchn >= 'a' && Zchn <= 'z') ? Zchn - 0x20 : Zchn);
203
}
204
 
205
//-----------------------------------------------------------------------------
206
// get the n-th parameter as string
207
static char *ParaStr(int Num)          /* Hole n-ten Parameter */
208
{                                      /* als String aus InStg */
209
    char *PSt;                           /* Evt. Ergebnis NULL bei (Num>1) */
210
 
211
    PSt=InStg;                           /* Fange bei InStg[0] an */
212
    if (Num > 1)
213
    {                                    /* Folgeparameter: suche Anfang */
214
        if (*PSt!='\0')
215
        {                                  /* Leerstring ignorieren */
216
            PSt++;
217
            switch (*PSt)
218
            {                                /* Teste evt. Modusparameter */
219
                case 'L':
220
                case 'W':
221
                case 'B':
222
                case 'X':
223
                case 'H':PSt++;
224
            }
225
 
226
            if (*PSt==' ') PSt++;            /* Evt. Delimiter ueberspringen */
227
        }
228
 
229
        if (*PSt=='\0') PSt=NULL;          /* Kein weiterer Parameter da */
230
        else
231
        {
232
            while (PSt!=NULL && Num>2)
233
            {
234
                PSt=strchr(PSt, ' ');          /* Suche nach Delimiter */
235
                if (PSt!=NULL) PSt++;          /* Delimiter ueberspringen */
236
                Num--;                         /* Naechster Parameter da */
237
            } /* while */
238
        } /* else */
239
    } /* if */
240
    return(PSt);
241
}
242
 
243
//-----------------------------------------------------------------------------
244
// get the n-th parameter as unsigned long
245
static unsigned long ParaNum(int Num)  /* Hole n-ten Parameter */
246
{                                      /* als Zahl aus InStg */
247
    unsigned long Erg;
248
    char         *PSt;
249
 
250
    PSt=ParaStr(Num);                    /* Hole Parameterstring */
251
    Erg=0;                               /* Hole Word aus String */
252
    if (PSt!=NULL) sscanf(PSt, "%lx", &Erg);
253
    return(Erg);
254
}
255
 
256
//-----------------------------------------------------------------------------
257
// set the address modifier for following accesses
258
static void SetModifier(void)          /* Neuen Adressmodifier setzen */
259
{
260
    int Idx;
261
 
262
    if (ParaStr(1)[1]=='H')
263
    {                                    /* Wenn Hilfsfunktion gewuenscht */
264
        if (ParaStr(2)==NULL)
265
        {                                  /* Noch ein Parameter da? */
266
            for (Idx=0; Idx<0x40; Idx++)
267
            {                                /* Nein: Liste ausgeben */
268
                ShowModifier(Idx);
269
                if ((Idx == 0x10) || (Idx == 0x20) || (Idx == 0x30))
270
                {
271
                    printf("\n go on ?\r");
272
                    getch();
273
                }
274
            }
275
            printf("\n");
276
        }
277
        else ShowModifier((int)ParaNum(2)); /* Nur gewuenschten Mode anzeigen */
278
    }
279
    else
280
    {
281
        if (ParaStr(2) != NULL)
282
        {
283
            if (ParaStr(1)[1] == 'M')
284
            {
285
                AdrMode=(int)ParaNum(3) & 0x3f;
286
            }
287
            else
288
            {
289
                AdrMode=(int)ParaNum(2) & 0x3f;  /* Adressmodifier merken */
290
            }
291
        }
292
        ShowModifier(AdrMode);             /* Status Adressmodifier zeigen */
293
    } /* else */
294
}
295
 
296
//-----------------------------------------------------------------------------
297
// print out an item
298
static void PrintItem(unsigned long Addr, char Mode, unsigned char *Asc)      
299
{
300
    unsigned long xl;
301
    unsigned int  xi;
302
    unsigned char xc;
303
 
304
    switch (Mode)
305
    {
306
        case 'L': xl=ReadLong(nInterfaceHandle, Addr, AdrMode);
307
            if (GetError(nInterfaceHandle))
308
            {
309
                ClearError(nInterfaceHandle); printf("********   ");
310
            }
311
            else
312
            {
313
                printf("%08lx   ", xl);
314
                if (Asc != NULL) *(unsigned long *)Asc=xl;
315
            }
316
            break;
317
        case 'W': xi=ReadWord(nInterfaceHandle, Addr, AdrMode);
318
            if (GetError(nInterfaceHandle))
319
            {
320
                ClearError(nInterfaceHandle); printf("**** ");
321
            }
322
            else
323
            {
324
                printf("%04hx ", xi);
325
                if (Asc != NULL) *(unsigned short *)Asc=xi;
326
            }
327
            break;
328
        case 'B': xc=ReadByte(nInterfaceHandle, Addr, AdrMode);
329
            if (GetError(nInterfaceHandle))
330
            {
331
                ClearError(nInterfaceHandle); printf("**");
332
            }
333
            else
334
            {
335
                printf("%02hx", xc);
336
                if (Asc != NULL) *Asc=xc;
337
            }
338
            break;
339
    }; /* switch */
340
}
341
 
342
//-----------------------------------------------------------------------------
343
// test whether byte word or long access
344
static char GetZug(char *Zug)          /* Moduszeichen feststellen */
345
{
346
    switch (ParaStr(1)[1])
347
    {                                    /* Moduszchn ist angegeben */
348
        case 'L':
349
        case 'W':
350
        case 'B':*Zug = ParaStr(1)[1];       /* Neues Moduszchn festlegen */
351
    }
352
    return(*Zug);
353
}
354
 
355
//-----------------------------------------------------------------------------
356
// get or set SYSFAIL
357
static void SysFail(void)
358
{
359
    if (ParaStr(2) != NULL)
360
    {
361
        if (ParaNum(2) > 0)
362
            SetSfail(nInterfaceHandle);
363
        else
364
            ClrSfail(nInterfaceHandle);
365
    }
366
 
367
    if (PollSfail(nInterfaceHandle))
368
        printf("SYSFAIL deasserted\n");
369
    else
370
        printf("SYSFAIL asserted\n");
371
}
372
 
373
 
374
//-----------------------------------------------------------------------------
375
// dump a range of memory
376
static void Dump(void)                 /* Ausgabe eines Bereichs */
377
{
378
    static unsigned long DefVon=0;       /* Default Addr fuer Dump */
379
 
380
    unsigned long Bis;                   /* Bis wohin ausgeben */
381
    unsigned int  Len;                   /* Wieviel Bytes/Ausgabe */
382
    unsigned int  Idx;                   /* Index */
383
    char Asc[16];        /* ohne static gehts bei dw nicht */
384
 
385
    if (ParaStr(2) != NULL)              /* Von-Adresse angegeben? */
386
        DefVon=ParaNum(2);
387
    Len=1;
388
 
389
    switch (GetZug(&DefZug))
390
    {                                    /* Zugriffsmodus festlegen */
391
        case 'L':Len+=2;                   /* Auf Long-Adresse biegen */
392
        case 'W':Len++;                    /* Auf Wort-Adresse biegen */
393
    }
394
 
395
    DefVon&=-(long)Len;                  /* Adressen geradebiegen */
396
    if (ParaStr(3) != NULL)
397
    {                                    /* Bis-Adresse angegeben? */
398
        Bis=ParaNum(3);
399
    }
400
    else
401
        Bis=(DefVon+0x7f) | 0x0f;       /* Default fuer Bis errechnen */
402
 
403
    printf("%08lx: ", DefVon);
404
    for (Idx=0; Idx < (DefVon & 0x0f)/Len*(2*Len+1); Idx++)
405
        printf(" ");
406
 
407
    memset(Asc, ' ', sizeof(Asc));       /* Initialize String to Spaces */
408
    while ((True) && (!Abbruch))
409
    {
410
        PrintItem(DefVon, DefZug,          /* Gebe eine Speicherstelle aus */
411
                  &Asc[DefVon & 0x0f]);            /* Merke Zeichen in Asc */
412
        DefVon+=Len;                       /* Zaehler erhoehen */
413
 
414
        if ((DefVon > Bis) || (!(DefVon & 0x0f)))
415
        {
416
            printf("   ");
417
            for (Idx=0; Idx < sizeof(Asc); Idx++)
418
            {
419
                if (Asc[Idx] < ' ') printf("."); /* Ascii-String ausgeben */
420
                else printf("%c", Asc[Idx]);   /* Ctrl-Zeichen als Punkte */
421
            }
422
 
423
            printf("\n");
424
            if (DefVon <= Bis)
425
            {
426
                printf("%08lx: ", DefVon);     /* Neue Zeile bei 16er-Grenze */
427
                memset(Asc, ' ', sizeof(Asc)); /* Init String */
428
            }
429
            else return;                     /* Ausstieg */
430
        }
431
        else
432
        {                                  /* Sonst Leerzeichen ausgeben */
433
            printf(((DefVon & 0x0f) == 0x08) ? "|":" ");
434
        }
435
    } /* while */
436
}
437
 
438
//-----------------------------------------------------------------------------
439
// read a string with editing functions
440
static char GetStrg(STRG Stg, int  Len) /* Lese String ein bis Spc */
441
{
442
    int  Idx;                            /* Zugriffsindex */
443
    char Zch;                            /* Eingabezeichen */
444
 
445
    Idx=0;                               /* Vorne anfangen */
446
    do
447
    {
448
        Zch=(char)getch();                 /* Hole ein Zeichen */
449
        if ((unsigned char)Zch >' ' && Zch!='\t')
450
        {
451
            if (Idx<Len)
452
            {
453
                printf("%c",Zch);              /* Zeichen ok, Ausgeben */
454
                Stg[Idx++]=Zch;                /* Zeichen ablegen */
455
            }
456
        }
457
        else
458
        {
459
            switch (Zch)
460
            {
461
                case '\b':if (Idx)
462
                    {                    /* Backspace=Delete? */
463
                        Idx--;             /* Loesche Zeichen aus String */
464
                        printf("\b \b");   /* und vom Bildschirm */
465
                    }
466
                case '\t':
467
                case '\r':break;               /* Return? Endezeichen 13 */
468
                default:Zch=0;                 /* Ende mit Endezeichen 0 */
469
            } /* switch */
470
        } /* else */
471
    } while (Zch && Zch!='\r' && Zch!='\n');
472
 
473
    Stg[Idx]='\0';                       /* Stringende eintragen */
474
    return(Zch);                         /* Returncode = Abschlusstaste */
475
}
476
 
477
//-----------------------------------------------------------------------------
478
// examine a memory location
479
static void Examine(void)              /* Speicherbereich aendern */
480
{
481
    unsigned long DefVon;                /* Anfangsadresse */
482
    unsigned long Inh;                   /* Neuer Inhalt */
483
    int           Len;                   /* Item-Laenge */
484
    int           Idx;                   /* Index */
485
    char          End;                   /* Endmodus */
486
    STRG          Stg;                   /* Eingabestring */
487
 
488
    if (ParaStr(2)!=NULL)
489
    {                                    /* Adresse benoetigt */
490
        Len=1;
491
        switch (GetZug(&DefZug))
492
        {         /* Zugriffsmodus festlegen */
493
            case 'L':Len+=2;                 /* Auf Long-Adresse biegen */
494
            case 'W':Len++;                  /* Auf Wort-Adresse biegen */
495
        }
496
        DefVon=ParaNum(2) & -(long)Len;    /* Adressen geradebiegen */
497
        if (ParaStr(3)!=NULL)
498
        {                                  /* Wert angegeben? */
499
            Inh=ParaNum(3);                  /* Hole auszugebenden Wert */
500
            switch (DefZug)
501
            {
502
                case 'L': WriteLong(nInterfaceHandle, DefVon,Inh,AdrMode);
503
                    break;
504
                case 'W': WriteWord(nInterfaceHandle, DefVon,(short)Inh,AdrMode);
505
                    break;
506
                case 'B': WriteByte(nInterfaceHandle, DefVon,(char)Inh,AdrMode);
507
                    break;
508
            }; /* switch */
509
 
510
            if (GetError(nInterfaceHandle))
511
            {                                /* Fehlerpruefung: VME-Transfer ok? */
512
                ClearError(nInterfaceHandle);                  /* Zuruecksetzen Fehlerflag */
513
                printf("Error\n");             /* Zugriff gescheitert */
514
            }
515
        }
516
        else
517
        {
518
            SLang_init_tty(-1, 0, 1);
519
            SLtt_get_terminfo();
520
 
521
            End='\n';                        /* Bei Einstieg drucke Adresse */
522
            do
523
            {
524
                if (End=='\n' || End=='\177' || !(DefVon % 8))
525
                {
526
                    if (End!='\n') printf("\n"); /* Bei Einstieg nicht <CRLF> */
527
                    printf("%08lx: ", DefVon);   /* Adresse ausgeben */
528
                }
529
 
530
                PrintItem(DefVon,DefZug,NULL); /* Gebe eine Speicherstelle aus */
531
                printf(".");
532
                SLtt_flush_output();
533
 
534
                End=GetStrg(Stg,Len << 1);     /* Hole begrenzte Eingabezeile */
535
 
536
                for (Idx=strlen(Stg); Idx<2+(Len << 1); Idx++)
537
                    printf(" ");
538
                if (sscanf(Stg,"%lx",&Inh)>0)
539
                {                              /* Hexzahl rausholen und ausgeben */
540
                    switch (DefZug)
541
                    {
542
                        case 'L': WriteLong(nInterfaceHandle, DefVon,Inh,AdrMode);
543
                            break;
544
                        case 'W': WriteWord(nInterfaceHandle, DefVon,(short)Inh,AdrMode);
545
                            break;
546
                        case 'B': WriteByte(nInterfaceHandle, DefVon,(char)Inh,AdrMode);
547
                            break;
548
                    }; /* switch */
549
 
550
                    if (GetError(nInterfaceHandle))
551
                        ClearError(nInterfaceHandle);/* Fehlerpruefung: VME-Transfer ok? */
552
                } /* if sscanf */
553
 
554
                if (End == '\177') DefVon-=Len;/* Naechste Speicherzelle ansteuern */
555
                else DefVon+=Len;
556
            } while (End!='\r');
557
            /* Ende bei <CR> */
558
            printf("\n");
559
 
560
            SLang_reset_tty();
561
        } /* else */
562
    } /* if */
563
    else printf("\a");                   /* Fehler: zuwenig Parameter */
564
}
565
 
566
//-----------------------------------------------------------------------------
567
// fill a range of memory
568
static void Fill(void)                 /* Fuellt Speicherbereich mit Wert */
569
{
570
    char          DefZug;                /* Zugriffsart */
571
    int           Len;                   /* Item Laenge */
572
    unsigned long Idx;                   /* Index */
573
    unsigned long End;                   /* Endadresse */
574
    unsigned long Patt;                  /* Fuellmuster */
575
    unsigned char Merk_error = 0;        /* Haelt error flag */
576
 
577
    DefZug=' ';                          /*  Modus muss angeben werden */
578
    if (GetZug(&DefZug)!=' ' && ParaStr(4)!=NULL)
579
    {
580
        Len=1;
581
        switch (GetZug(&DefZug))
582
        {                                  /* Zugriffsmodus festlegen */
583
            case 'L':Len+=2;                 /* Auf Long-Adresse biegen */
584
            case 'W':Len++;                  /* Auf Wort-Adresse biegen */
585
        }
586
        Idx=ParaNum(2) & -(long)Len;       /* Adressen geradebiegen */
587
        End=ParaNum(3);                    /* Endadresse festlegen */
588
        Patt=ParaNum(4);                   /* Pattern merken (geht schneller) */
589
 
590
        while ((Idx<=End) && (!Abbruch))
591
        {
592
            switch (DefZug)
593
            {
594
                case 'L':WriteLong(nInterfaceHandle, Idx, Patt, AdrMode);
595
                    break;
596
                case 'W':WriteWord(nInterfaceHandle, Idx, (short)Patt, AdrMode);
597
                    break;
598
                case 'B':WriteByte(nInterfaceHandle, Idx, (char)Patt, AdrMode);
599
                    break;
600
            } /* switch */
601
 
602
            if (GetError(nInterfaceHandle))
603
            {
604
                ClearError(nInterfaceHandle);                  /* Fehler abfangen */
605
                Merk_error = 1;
606
            }
607
            if ((Idx & 0xffl)==0)
608
            {                                /* Ermoegliche Ctrl-C */
609
                printf("\r");
610
            }
611
            Idx+=Len;
612
        } /* while */
613
        if (Merk_error) printf("--> Memory fill failed\a\n");
614
    }
615
    else printf("\a");
616
}
617
 
618
//-----------------------------------------------------------------------------
619
// moves a range of memory
620
static void Move(void)                 /* Schiebt Speicherbereich */
621
{
622
    char          DefZug;                /* Zugriffsart */
623
    int           Len;                   /* Item Laenge */
624
    unsigned long Idx;                   /* Index */
625
    unsigned long End;                   /* Endadresse */
626
    unsigned long Dest;                  /* Zieladresse */
627
    unsigned long Wert;                  /* Kopiewert */
628
    unsigned char Merk_error = 0;        /* Haelt error flag */
629
 
630
 
631
    DefZug=' ';                          /*  Modus muss angeben werden */
632
    if (GetZug(&DefZug)!=' ' && ParaStr(4)!=NULL)
633
    {
634
        Len=1;
635
        switch (GetZug(&DefZug))
636
        {                                  /* Zugriffsmodus festlegen */
637
            case 'L':Len+=2;                 /* Auf Long-Adresse biegen */
638
            case 'W':Len++;                  /* Auf Wort-Adresse biegen */
639
        }
640
        Idx=ParaNum(2) & -(long)Len;       /* Adressen geradebiegen */
641
        End=ParaNum(3);                    /* Endadresse festlegen */
642
        Dest=ParaNum(4);                   /* Zieladresse setzen */
643
 
644
        while ((Idx<=End) && (!Abbruch))
645
        {
646
            switch (DefZug)
647
            {
648
                case 'L': {
649
                        Wert = ReadLong(nInterfaceHandle, Idx, AdrMode);
650
                        WriteLong(nInterfaceHandle, Dest, Wert, AdrMode);
651
                    }
652
                    break;
653
                case 'W': {
654
                        Wert = ReadWord(nInterfaceHandle, Idx, AdrMode);
655
                        WriteWord(nInterfaceHandle, Dest, (short)Wert, AdrMode);
656
                    }
657
                    break;
658
                case 'B': {
659
                        Wert = ReadByte(nInterfaceHandle, Idx, AdrMode);
660
                        WriteByte(nInterfaceHandle, Dest, (char)Wert, AdrMode);
661
                    }
662
                    break;
663
            } /* switch */
664
 
665
            if (GetError(nInterfaceHandle))
666
            {
667
                ClearError(nInterfaceHandle);                        /* Fehler abfangen */
668
                Merk_error = 1;
669
            }
670
 
671
            if ((Idx & 0xffl)==0)
672
            {                                      /* Ermoegliche Ctrl-C */
673
                printf("\r");
674
            }
675
 
676
            Idx+=Len;
677
            Dest+=Len;
678
        } /* while */
679
        if (Merk_error) printf("--> Memory move failed\a\n");
680
    }
681
    else printf("\a");
682
}
683
 
684
//-----------------------------------------------------------------------------
685
// print out help to user
686
static void Hilfe(void)
687
{
688
    printf("a[h] [adrmode]\t\t: Change address modifiers, h=help\n");
689
    printf("c\t\t\t: Configure interface\n");
690
    printf("d[m] [start] [end]\t: Dump memory area\n");
691
    printf("e[m] <start> [value]\t: Examine or change memory area\n");
692
    printf("f<m> <start> <end> <x>\t: Fill memory from <start> til <end> with <x>\n");
693
    printf("g<m> <st> <en> [l] [x]\t: Generate random memory test. (loop l, seed x)\n");
694
    printf("h\t\t\t: This help\n");
695
    printf("i\t\t\t: Interface init\n");
696
    printf("l[m]\t\t\t: Get VME interrupt status/ID\n");
697
    printf("m<m> <src> <end> <dest>\t: Move memory area\n");
698
    printf("o\t\t\t: Jump to OS\n");
699
    printf("p[adrmode]\t\t: Port search\n");
700
    printf("q\t\t\t: Quit program\n");
701
    printf("r[x] <f> <start> [end]\t: Read file <f> to VME, x= x or s (HEX)\n");
702
    printf("s[m] <start> <end> <p>\t: Search pattern <p>=different Items\n");
703
    printf("t <start>\t\t: TAS emulation, 'Test and Set' bit 7\n");
704
    printf("v\t\t\t: Generate VME SYSRESET\n");
705
    printf("w[x] <f> <start> <end>\t: Write VME into file <f>, h=Intel Hex\n");
706
    printf("x <start> [val]\t\t: Read/Write to interface register @ start\n");
707
    printf("y[1/0]\t\t\t: Read/set/clear SYSFAIL\n");
708
    printf("z[0..2]\t\t\t: Show interface internals\n");
709
    printf("\n");
710
    printf("m = mode, e.g. b=byte, w=word, l=long (double) word; h = help, x= hex\n");
711
    printf("start(address), end(address), src=source, dest=destination, []=option\n");
712
}
713
 
714
//-----------------------------------------------------------------------------
715
// initialize the interface to VME
716
static int InitAt(char *szDevicePath, int *nIfcNum)                      /* Gibt bei Fehler False aus */
717
{
718
    int result;
719
 
720
    if (result = Init_Interface(szDevicePath, AdrMode, nIfcNum))         /* Pruefung des Interfaces */
721
    {
722
        printf("\n");
723
        switch (result)
724
        {
725
            case ENXIO:          
726
                printf("Can't find interface driver path!\n");
727
                printf("Please <q>uit or <c>onfigure interface!\n");
728
                return FALSE;
729
            case ENOENT:
730
                printf("Can't find interface driver!\n");
731
                printf("Please <q>uit or <c>onfigure interface!\n");
732
                return FALSE;
733
            case ENODEV:
734
                printf("VMEMM #%d not connected or VME crate switched off!\n", nInterfaceHandle);
735
                printf("Please check connection or switch VME crate on or <c>onfigure.\n");
736
                printf("Then <q>uit and restart again.\n");
737
                return FALSE;
738
 
739
            default:
740
                printf("Unknown error '%d' occured!\n", result);
741
                printf("Please check the hardware and software setup and restart again.\n");
742
                return FALSE;
743
 
744
        }
745
    }
746
 
747
    return(True);                        /* Kein Fehler */
748
}
749
 
750
//-----------------------------------------------------------------------------
751
// get the name of the configuration file 
752
static void CfgName(STRG Stg)          /* Ermittelt Namen Config-File */
753
{
754
    Stg[0]='\0';
755
    if (ArgV[0] != NULL)
756
    {
757
        strcpy(Stg,ArgV[0]);
758
        if (strrchr(Stg,'/')!=NULL)       /* Versuche Dateinamen abzutrennen */
759
            *(strrchr(Stg,'/')+1)='\0';     /* So daß nur Pfad uebrigbleibt */
760
        else Stg[0]='\0';                  /* Kein Pfad: String ist leer */
761
    }
762
    strcat(Stg,"pvmon.cfg");          /* Mache einen Dateinamen */
763
}
764
 
765
//-----------------------------------------------------------------------------
766
// read in contents of configuration file
767
static void LoadKonfig(void)           /* Wenn Config-Datei da, lese ein */
768
{
769
    STRG  Stg;
770
    FILE *InF;
771
    char c;
772
    __u32 dwLocalAdrMode;
773
 
774
    CfgName(Stg);                        /* Hole Dateinamen nach InS */
775
    if ((InF=fopen(Stg,"rt"))!=NULL)
776
    {                                    /* Wenn das oeffnen geklappt hat */
777
        fscanf(InF,"%*[^=]%*1s%s",Stg);
778
        fscanf(InF,"%*[^=]%*1s%s",cszDevicePath);
779
        fscanf(InF,"%*[^=]%*1s%x",&dwLocalAdrMode);
780
        AdrMode = (__u8)dwLocalAdrMode;
781
        fscanf(InF,"%*[^=]%*1s%c",&c);
782
        fclose(InF);                       /* Datei wieder schließen */
783
 
784
        c = tolower(c);
785
        if (c == 'y')
786
            WordMode = setWordMode(1);
787
        else
788
            WordMode = setWordMode(0);
789
 
790
    } /* if */
791
}
792
 
793
//-----------------------------------------------------------------------------
794
// provides configuration functionality to user
795
static void Konfig(void)               /* Konfiguration einstellen */
796
{
797
    STRG  InS;                           /* Eingabestring */
798
    FILE *OuF;                           /* Ausgabedatei  */
799
    short change = 0;
800
    char  c;
801
 
802
    InS[0] = 0;
803
    printf("Pathname of device (%s):",cszDevicePath);   /* erfrage den Pfad zum Treiber */
804
    _gets(InS);
805
    if ((InS[0] != '\n') && (InS[0]))
806
    {
807
        strcpy(cszDevicePath, InS);
808
        change |= 1;
809
    }
810
 
811
    InS[0] = 0;
812
    printf("Default address modifier (%02x):",AdrMode); /* und den default Modifier */
813
    _gets(InS);
814
    if ((InS[0] != '\n') && (InS[0]))
815
    {
816
        sscanf(InS,"%x",&AdrMode);
817
        change |= 4;
818
    }
819
 
820
    if (WordMode)
821
        c = 'y';
822
    else
823
        c = 'n';
824
    InS[0] = 0;
825
    printf("16 bit VME BUS data path (%c) :", c);
826
    _gets(InS);
827
    if ((InS[0] != '\n') && (InS[0]))
828
    {
829
        sscanf(InS,"%c",&c);
830
        change |= 8;
831
    }
832
    c = tolower(c);
833
    if (c == 'y')
834
        WordMode = setWordMode(1);
835
    else
836
        WordMode = setWordMode(0);
837
 
838
    if (change)
839
    {
840
        do
841
        {
842
            printf("Save (y/n):");             /* Wiederhole diese Frage bis */
843
            _gets(InS);                         /* sie ordentlich beantwortet wurde */
844
            strlwr(InS);                       /* DownCase String */
845
        } while (InS[0]!='y' && InS[0]!='n');
846
 
847
        if (InS[0]=='y')
848
        {
849
            CfgName(InS);                      /* Hole Dateinamen nach InS */
850
            if ((OuF=fopen(InS,"wt"))!=NULL)
851
            {
852
                if (WordMode)
853
                    c = 'y';
854
                else
855
                    c = 'n';
856
 
857
                fprintf(OuF,"Configuration=%s\n",__DATE__);
858
                fprintf(OuF,"DevicePath=%s\n",cszDevicePath); /* Wenn das oeffnen geklappt hat */
859
                fprintf(OuF,"AddressModifier=%x\n",AdrMode);
860
                fprintf(OuF,"WordMode=%c\n", c);
861
                fclose(OuF);                     /* Datei schliessen */
862
 
863
                if (change & 1)
864
                    printf("Please restart to put the new driver to work!\n");
865
            }
866
            else printf("Can't open %s. ",InS);
867
        }
868
    }
869
}
870
 
871
//-----------------------------------------------------------------------------
872
// read user initiated interrupt vector from VME BUS
873
static void ReadIrqVect(void)          /* Interrupt-Vektoren lesen */
874
{
875
    STRG OSt;                            /* Ausgabestring */
876
    short Level = 0;
877
 
878
    switch (GetZug(&DefVec))
879
    {                                    /* Zugriffsmodus festlegen */
880
        case 'L':sprintf(OSt, "%08hx", ReadVectorLong(nInterfaceHandle)); break;
881
        case 'W':sprintf(OSt, "%04hx", ReadVectorWord(nInterfaceHandle)); break;
882
        case 'B':sprintf(OSt, "%02hx", ReadVectorByte(nInterfaceHandle)); break;
883
    };
884
 
885
    if (GetError(nInterfaceHandle))
886
    {                                    /* Im Fehlerfalle 'Error' ausgeben */
887
        ClearError(nInterfaceHandle);                      /* Fehlerflags zuruecksetzen */
888
        strcpy(OSt, "Error");
889
    }
890
    printf("VME status/ID = %s\n", OSt);
891
}
892
 
893
 
894
//-----------------------------------------------------------------------------
895
// temporary jump to (D)OS
896
static void JumpToDos()                       /* (D)OS-Shell aufrufen */
897
{
898
    {
899
        if (system("/bin/sh -c $SHELL") != 0)
900
            printf("Fail to launch a new shell.\n");
901
    }
902
}
903
 
904
//-----------------------------------------------------------------------------
905
// search responding ports in VME address range
906
static void SearchPort(char *Art, int Anz, unsigned short modf,
907
                       void (*SFunc)(int, unsigned long, unsigned short)) /* Durchsucht Adressraum */
908
{
909
    unsigned long Idx;
910
    unsigned long Fst;                    /* Erster gefundener Port */
911
    unsigned long Lst;                    /* Letzer gefundener Port */
912
    unsigned long Ende;                   /* Durchsuch Ende */
913
    char          Found;                  /* Schon was gefunden? */
914
    char          Sequ;                   /* Schon eine Portsequenz */
915
    int           Err;                    /* Fehler dagewesen? */
916
    int           Tab;                    /* Tabulator-Zaehler */
917
    unsigned long Step;
918
 
919
    printf("%s-accesses valid with address modifier %02x to address: ", Art,modf);
920
 
921
    if (modf > 0x2F)
922
    {
923
        Ende = 0x01000000L;                /* alle Standards */
924
        Step = 0x100;                      /* Stepweite      */
925
    }
926
 
927
    if ((modf < 0x30) && (modf > 0x1f))
928
    {
929
        Ende = 0x00010000L;                /* Shorts */
930
        Step = Anz;
931
    }
932
 
933
    if (modf < 0x20)
934
    {
935
        Ende = 0xFFFF0000L;                /* alle Extendets, gemogelt */
936
        Step = 0x10000;                    /* Step */
937
    }
938
 
939
    Sequ=False;                          /* Noch keine Sequenz da */
940
    Found=False;
941
    Tab=0;
942
    Idx=0;
943
 
944
    do
945
    {                                    /* do while */
946
        SFunc(nInterfaceHandle, Idx, modf);                   /* Lese versuchsweise Port */
947
        Err=GetError(nInterfaceHandle);                    /* Fehlerzustand abfragen */
948
        if (Err) ClearError(nInterfaceHandle);             /* Fehler bestaetigen */
949
        else
950
        {
951
            Lst=Idx;                         /* Merke Port als gueltig */
952
            if (!Sequ)
953
            {                                /* Diese Seqenz faengt an? */
954
                Fst=Idx;                       /* Ja, neue Sequenz, merke */
955
                Sequ=True;                     /* auch ersten Port */
956
            }
957
        }
958
 
959
        Idx+= Step;                        /* Erhoehe Adresse */
960
 
961
        if ((Err || !(Idx < Ende)) && Sequ)
962
        {                                  /* Ausgeben bei Sequenzende */
963
            if (!Found)
964
            {                                /* oder bei Schleifenende */
965
                if (Idx < Ende) printf("\n");  /* Kein <CRLF> bei Schleifenende */
966
                Found=True;
967
            };
968
            /* Weitere Sequenz: Tab ausgeben */
969
            if (Fst==Lst)
970
            {                                /* Sequenz mit nur 1 Element */
971
                printf("%08lx,\t", Fst);
972
                Tab++;                         /* Merke Tab-Status */
973
            }
974
            else
975
            {
976
                Tab=0;                         /* Tab-Status wieder zuruecksetzen */
977
                printf("%08lx-%08lx\n", Fst, Lst); /* Sequenz ausgeben */
978
            }
979
            Sequ=False;                      /* Sequenz gilt als abgeschlossen */
980
        } /* if */
981
    } while ((Idx < Ende) && (!Abbruch));     /* Bis Idx einmal 'rum ist */
982
 
983
    if (!Found)
984
        printf("\nnothing found");         /* Wenn keinen Zugriff gefunden */
985
    printf("\n");                        /* Immer mit <CRLF> abschließen */
986
}
987
 
988
//-----------------------------------------------------------------------------
989
// search responding ports
990
static void SearchPorts(void)          /* Durchsucht Short-Adressraum */
991
{                                      /* nach Wort- und Bytes Zugriffen */
992
    unsigned short modf = AdrMode;  
993
 
994
    if (ParaStr(2)!=NULL)
995
        modf = (unsigned short)ParaNum(2); /* Anderer Adressmodifier      */
996
 
997
    ShowModifier(modf); printf("\n");
998
    SearchPort("Byte", 1, modf, (void(*)(int, unsigned long, unsigned short))ReadByte);
999
    SearchPort("Word", 2, modf, (void(*)(int, unsigned long, unsigned short))ReadWord);
1000
    SearchPort("Long", 4, modf, (void(*)(int, unsigned long, unsigned short))ReadLong);
1001
    printf("\n");
1002
}
1003
 
1004
//-----------------------------------------------------------------------------
1005
// converts parts of a string to a number
1006
static unsigned int GibNum(char **PSt, char Anz)
1007
{
1008
    unsigned int Val;                    /* Ermittelter Wert */
1009
    unsigned int Num;                    /* Wieviel Zeichen genommen */
1010
    char     Frm[6];                     /* Formatstring */
1011
 
1012
    Val=0;                               /* Default setzen */
1013
    strcpy(Frm,"%nx%n");                 /* Default Format setzen */
1014
    if (*PSt!=NULL)
1015
    {                                    /* Nur wenn String gueltig */
1016
        Frm[1]=Anz;                        /* Uebertrage Anzahl-Zeichen */
1017
        *PSt=(sscanf(*PSt,Frm,&Val,        /* Hole Nummer aus String */
1018
                     &Num)!=1) ? NULL : (*PSt)+Num;   /* Fehler oder weitersetzen */
1019
    } /* if */
1020
    return(Val);
1021
}
1022
 
1023
//-----------------------------------------------------------------------------
1024
// read in a file and put the contents to VME 
1025
static int _ReadFile(void)             /* Lese eine Datei in VME-Mem ein */
1026
{
1027
    unsigned long End;                   /* Endadresse */
1028
    unsigned long Idx;                   /* Laufadresse */
1029
    unsigned long Cnt;                   /* Bytezaehler */
1030
    unsigned      Adr;                   /* Adresse Record ab Start */
1031
    int           Len;                   /* Recordlaenge */
1032
    int           Ret;                   /* Returncode */
1033
    int           Hex;                   /* Intel Hex File? */
1034
    int           Typ;                   /* Typ des Records */
1035
    STRG          Nam;                   /* Dateiname */
1036
    STRG          Stg;                   /* Einlese-String */
1037
    char         *PSt;                   /* Scanzeiger */
1038
    FILE         *InF;                   /* Lesedatei */
1039
 
1040
    Ret=1;                               /* Vorgabe ist Fehler */
1041
    if (ParaStr(3)!=NULL)
1042
    {                                    /* Startadr ist obligat */
1043
        Hex=(ParaStr(1)[1]=='X');          /* Intel-Hex gewuenscht? */
1044
        strcpy(Nam,ParaStr(2));            /* Dateinamen kopieren */
1045
        *strchr(Nam,' ')='\0';             /* Restparameter abschneiden */
1046
        Cnt=0;                             /* Noch nichts gelesen */
1047
        Idx=ParaNum(3);                    /* Lege Startadresse fest */
1048
        End=(ParaStr(4)==NULL)             /* Endadr ist optional */
1049
            ? 0xffffffffl : ParaNum(4);
1050
 
1051
        if (Idx<=End)
1052
        {                                  /* Falsche Werte abweisen */
1053
            if ((InF=fopen(Nam,(Hex) ? "rt":"rb"))!=NULL)
1054
            {
1055
                if (Hex)
1056
                {                              /* Intel-Hex gewuenscht? */
1057
                    fscanf(InF,"%x",Idx);
1058
                    while (!feof(InF))
1059
                    {                            /* Bis zum Ende lesen */
1060
                        fgets(Stg,sizeof(Stg),InF);
1061
                        if (strlen(Stg)>1)
1062
                        {                          /* Ignoriere leere Zeilen */
1063
                            PSt=strchr(Stg,':');     /* Doppelpunkt ist obligat */
1064
                            if (PSt!=NULL) PSt++;    /* Hinter ':' stellen */
1065
                            Len=GibNum(&PSt,'2');    /* Hole Recordlaenge */
1066
                            Adr=GibNum(&PSt,'4');    /* Hole Adresse */
1067
                            Typ=GibNum(&PSt,'2');
1068
                            if (!Typ)
1069
                            {                        /* Datencode erkannt? */
1070
                                while (PSt!=NULL && Len)
1071
                                {
1072
                                    WriteByte(nInterfaceHandle, Idx+Adr++,(char)GibNum(&PSt,'2'),AdrMode);
1073
                                    Cnt++;               /* 1 Byte mehr gelesen */
1074
                                    Len--;               /* Laenge aufaddieren */
1075
                                } /* while */
1076
 
1077
                                if (GetError(nInterfaceHandle))
1078
                                {                      /* Fehlerpruefung: VME-Transfer ok? */
1079
                                    ClearError(nInterfaceHandle);        /* Fehlerflag zuruecksetzen */
1080
                                    printf("--> Bus error: Adr=%08lx. ",Idx+Adr);
1081
                                    break;               /* Abbruch mit Fehler */
1082
                                } /* if */
1083
                            }
1084
                            else
1085
                            {
1086
                                if (Typ==1)
1087
                                {                      /* Endcode erkannt? */
1088
                                    Ret=0;               /* Fehlerfrei gelesen */
1089
                                    break;               /* Ende while */
1090
                                }                      /* Ignoriere andere Typen */
1091
                            } /* else */
1092
                            if (PSt==NULL)
1093
                            {
1094
                                printf("Format error\n");
1095
                                break;
1096
                            } /* if */
1097
                        } /* if len */
1098
                    } /* while */
1099
                }
1100
                else
1101
                {                              /* Kein Intel-Hex-Format */
1102
                    do
1103
                    {
1104
                        if (feof(InF)) Idx=End;    /* Ende der Datei erreicht */
1105
                        else
1106
                        {
1107
                            WriteByte(nInterfaceHandle, Idx,(char)fgetc(InF),AdrMode);
1108
                            if (GetError(nInterfaceHandle))
1109
                            {                        /* Fehlerpruefung: VME-Transfer ok? */
1110
                                ClearError(nInterfaceHandle);          /* Fehlerflag zuruecksetzen */
1111
                                printf("--> Bus error: Adr=%08lx. ",Idx);
1112
                                break;                 /* Abbruch mit Fehler */
1113
                            } /* if GetError */
1114
 
1115
                            Cnt++;                   /* Ein Byte mehr gelesen */
1116
                        } /* else */
1117
                    } while (Idx++<End);         /* Bis einschliesslich End lesen */
1118
                    fclose(InF);
1119
                    if (Idx==End+1) Ret=0;       /* Genug Byte geschafft? */
1120
                } /* else Hex */
1121
            } /* if fopen */
1122
            else printf("Can't read file %s. ",Nam);
1123
        } /* if */
1124
        printf("%lx Byte(s) read\n",Cnt);
1125
    } /* if */
1126
    else printf("\a");
1127
    return(Ret);
1128
}
1129
 
1130
//-----------------------------------------------------------------------------
1131
// seek for a pattern in VME BUS
1132
static void SeekPatt(void)             /* Suche nach Datenmustern */
1133
{
1134
#define Max 32                       /* Wieviele Suchbytes max. */
1135
    unsigned long DefVon;                /* Startadresse */
1136
    unsigned long End;                   /* Endadresse */
1137
    int           Idx;                   /* Index */
1138
    int           Idy;                   /* Auch Index */
1139
    int           Len;                   /* Item Laenge */
1140
    int           Ok;                    /* Flag: gefunden oder nicht? */
1141
    int           Merk_error = 0;        /* Fehler Flip-Flop */
1142
 
1143
    union
1144
    {                                    /* Suchmuster */
1145
        unsigned char xs[Max];
1146
        unsigned int  xw[Max/2];
1147
        unsigned long xl[Max/4];
1148
    } Patt;
1149
 
1150
    if (ParaStr(4) != NULL)
1151
    {                                    /* Von, Bis und 1 Item obligat */
1152
        DefVon=ParaNum(2);                 /* Startadresse festlegen */
1153
        End=ParaNum(3);                    /* Endadresse festlegen */
1154
        Len=1;
1155
        switch (GetZug(&DefZug))
1156
        {                                  /* Zugriffsmodus festlegen */
1157
            case 'L':Len+=2;                 /* Auf Long-Adresse biegen */
1158
            case 'W':Len++;                  /* Auf Wort-Adresse biegen */
1159
        }
1160
 
1161
        DefVon&=-(long)Len;                /* Adressen geradebiegen */
1162
        Idx=0;                             /* Suchmuster sammeln */
1163
        while (Idx<Max/Len && ParaStr(Idx+4)!=NULL)
1164
        {
1165
            switch (DefZug)
1166
            {
1167
                case 'L':Patt.xl[Idx]=ParaNum(Idx+4);                break;
1168
                case 'W':Patt.xw[Idx]=(unsigned)ParaNum(Idx+4);      break;
1169
                case 'B':Patt.xs[Idx]=(unsigned char)ParaNum(Idx+4); break;
1170
            } /* switch */
1171
            Idx++;                           /* Ein Item mehr da */
1172
        } /* while */
1173
 
1174
        while ((DefVon<=End) && (!Abbruch))
1175
        {                                  /* Suche nun den Bereich ab */
1176
            Ok=True;                         /* Pattern an dieser Adresse? */
1177
            for (Idy=0; Idy<Idx && Ok; Idy++)
1178
            {
1179
                switch (DefZug)
1180
                {
1181
                    case 'L':if (Patt.xl[Idy] != (unsigned long)ReadLong(nInterfaceHandle, DefVon+(Idy<<2),AdrMode))
1182
                            Ok=False;
1183
                        break;
1184
                    case 'W':if (Patt.xw[Idy] != (unsigned short)ReadWord(nInterfaceHandle, DefVon+(Idy<<1),AdrMode))
1185
                            Ok=False;
1186
                        break;
1187
                    case 'B':if (Patt.xs[Idy] != (unsigned char)ReadByte(nInterfaceHandle, DefVon+Idy,AdrMode))
1188
                            Ok=False;
1189
                        break;
1190
                } /* switch */
1191
 
1192
                if (GetError(nInterfaceHandle))
1193
                {                              /* Busfehler aufgetreten? */
1194
                    ClearError(nInterfaceHandle);                /* Fehlerflags zuruecksetzen */
1195
                    Ok=False;                    /* Gefunden wurde auch nichts */
1196
                    Merk_error = 1;              /* Setze Flip-Flop */
1197
                }
1198
            } /* for */
1199
            if (Ok) printf("%08lx\n",DefVon);/* Was gefunden: Adresse ausgeben */
1200
            DefVon+=Len;
1201
 
1202
            if ((DefVon & 0xffl)==0)
1203
            {                                /* Ermoegliche Abbruch mit Ctrl-C */
1204
                printf("\r");
1205
            }
1206
        } /* while */
1207
        if (Merk_error) printf("--> Failed to search\n");
1208
    }
1209
    else printf("\a");
1210
}
1211
 
1212
//-----------------------------------------------------------------------------
1213
// emulate a 68K test and set instruction
1214
static void TestSet()                  /* Fuehre ein Test and Set auf */
1215
{                                      /* Bit #7 eines Byte-Ports aus. */
1216
    char Erg;
1217
 
1218
    if (ParaStr(2)!=NULL)
1219
    {                                    /* Adresse ist obligat */
1220
        Erg=TAS(nInterfaceHandle, ParaNum(2),AdrMode);       /* Ergebnis merken, damit ein */
1221
        if (GetError(nInterfaceHandle))
1222
        {                                  /* Fehler ausgegeben werden kann */
1223
            ClearError(nInterfaceHandle);
1224
            printf("--> Failed to 'Test and Set'\n"); /* Zugriff gescheitert */
1225
        }
1226
        else printf("Semafore @ 0x%08lx was%s set before.\n",
1227
                    ParaNum(2),(Erg) ? "" : " not");
1228
    }
1229
    else printf("\a");
1230
}
1231
 
1232
//-----------------------------------------------------------------------------
1233
// raise a VME SYSRESET
1234
static void ResetVme(void)             /* Generiere SysReset auf VME-Bus */
1235
{                                      /* Interrupt bei MailBox beachten */
1236
    printf("Reset to VME raised.\n");
1237
    Reset_VME(nInterfaceHandle);
1238
}
1239
 
1240
//-----------------------------------------------------------------------------
1241
// print out a line in HEX format
1242
static int OutHex(FILE *OuF, int Siz, unsigned long Adr,int Typ, char Buf[])
1243
{
1244
    int Chk;                             /* Pruefsumme */
1245
    int Idx;                             /* Laufindex */
1246
 
1247
    fprintf(OuF,":%02X%04X%02X",Siz,Adr,Typ);
1248
    Chk=Siz+(Adr & 0xff)+(Adr>>8)+Typ;
1249
    for (Idx=0; Idx<Siz; Idx++)
1250
    {                                    /* Pufferinhalt ausgeben */
1251
        fprintf(OuF,"%02X",(unsigned char)Buf[Idx]);
1252
        Chk+=Buf[Idx];                     /* Pruefsumme mitrechnen */
1253
    }
1254
    fprintf(OuF,"%02X\n",(unsigned char)-Chk); /* Pruefsumme ausgeben */
1255
    if (ferror(OuF))
1256
    {                                    /* Irgend ein Schreibfehler? */
1257
        printf("Failed to write. ");
1258
        return(False);
1259
    }
1260
    else return(True);                   /* Fehlerfrei ausgefuehrt */
1261
}
1262
 
1263
//-----------------------------------------------------------------------------
1264
// write a file in HEX and get the data from VME
1265
static int _WriteFile()                /* Schreibt eine Datei aus VME */
1266
{
1267
    unsigned long End;                   /* Endadresse */
1268
    unsigned long Idx;                   /* Laufadresse */
1269
    unsigned long Cnt;                   /* Bytezaehler */
1270
    int           Ret;                   /* Returncode */
1271
    int           Adr;                   /* Adresse Record ab Start */
1272
    int           Hex;                   /* Intel Hex File? */
1273
    char          Buf[16];               /* Output-Puffer */
1274
    STRG          Nam;                   /* Dateiname */
1275
    FILE         *OuF;                   /* Lesedatei */
1276
 
1277
    Ret=1;                               /* Vorgabe ist Fehler */
1278
    if (ParaStr(4)!=NULL)
1279
    {                                    /* Start & Endadr sind obligat */
1280
        Hex=(ParaStr(1)[1]=='X');          /* Intel-Hex gewuenscht? */
1281
        strcpy(Nam,ParaStr(2));            /* Dateinamen kopieren */
1282
        *strchr(Nam,' ')='\0';             /* Restparameter abschneiden */
1283
        Cnt=0;                             /* Noch nichts gelesen */
1284
        Idx=ParaNum(3);                    /* Lege Startadresse fest */
1285
        End=ParaNum(4);                    /* Lege Endadresse fest */
1286
        if (Idx<=End)
1287
        {                                  /* Falsche Werte abweisen */
1288
            if ((OuF=fopen(Nam,(Hex) ? "wt":"wb"))!=NULL)
1289
            {
1290
                if (Hex)
1291
                {                              /* Intel-Hex gewuenscht? */
1292
                    Buf[0]=0 >> 0x8;             /* HighByte Segmentadresse */
1293
                    Buf[1]=0 & 0xff;             /* LowByte Segmentadresse */
1294
                    Adr=0;                       /* Offset grundsaetzlich bei 0 */
1295
                    if (OutHex(OuF,2,Adr,2,Buf))
1296
                    {
1297
                        do
1298
                        {
1299
                            Buf[(int)Cnt & 0xf]=ReadByte(nInterfaceHandle, Idx,AdrMode);
1300
                            if (GetError(nInterfaceHandle))
1301
                            {                        /* Fehlerpruefung: VME-Transfer ok? */
1302
                                ClearError(nInterfaceHandle);          /* Fehlerflag zuruecksetzen */
1303
                                printf("--> Bus error: Adr=%08lx. ",Idx);
1304
                                break;                 /* Abbruch */
1305
                            } /* if GetError */
1306
                            if (!((int)++Cnt & 0xf))
1307
                            {
1308
                                if (OutHex(OuF,16,Adr,0,Buf)) Adr+=16;
1309
                                else break;            /* Zwischendurch Puffer schreiben */
1310
                            }
1311
                        } while (Idx++<End);       /* Bis einschließlich End schreiben */
1312
 
1313
                        if ((Idx==End+1) &&        /* Noch Rest im Puffer? */
1314
                            (!((int)Cnt & 0xf) ||
1315
                             OutHex(OuF,(int)Cnt & 0xf,Adr,0,Buf))
1316
                            && OutHex(OuF,0,0,1,NULL)) Ret=0;
1317
                    } /* if */                   /* Wenn Eof ausgegeben, Returns ok */
1318
                } /* if Hex */
1319
                else
1320
                    do
1321
                    {                            /* Nicht Intel-Hex */
1322
                        fputc(ReadByte(nInterfaceHandle, Idx,AdrMode),OuF);
1323
                        if (GetError(nInterfaceHandle))
1324
                        {                          /* Fehlerpruefung: VME-Transfer ok? */
1325
                            ClearError(nInterfaceHandle);            /* Fehlerflag zuruecksetzen */
1326
                            printf("--> Bus error: Adr=%08lx. ",Idx);
1327
                            break;                   /* Abbruch */
1328
                        } /* if GetError */
1329
                        if (ferror(OuF))
1330
                        {                          
1331
                            printf("Failed to write. ");
1332
                            break;                   /* Abbruch */
1333
                        } /* if ferror */
1334
                        Cnt++;                     /* Ein Byte mehr geschrieben */
1335
                    } while (Idx++<End);         /* Bis einschließlich End schreiben */
1336
 
1337
                if (Idx==End+1) Ret=0;       /* Genug Byte geschafft? */
1338
                fclose(OuF);
1339
            } /* if fopen */
1340
            else
1341
                printf("Can' open file %s. ",Nam);
1342
        } /* if */
1343
        printf("%lx Byte(s) written.\n",Cnt);
1344
    } /* if */
1345
    else
1346
        printf("\a");
1347
    return(Ret);
1348
}
1349
 
1350
 
1351
//-----------------------------------------------------------------------------
1352
// show and provide help about the VME address modifiers
1353
static void ShowModifier(int Mode)           /* Klartext fuer Adressmodifier */
1354
{
1355
    printf("Address modifier:\t%02x [", Mode);
1356
    if ((Mode & 0x3b) > 0x38) printf("standard");
1357
    else if ((Mode & 0x3b)==0x29) printf("short");
1358
    else if ((Mode & 0x3b)>=0x09 && (Mode & 0x3b)<=0x0b) printf("extendet");
1359
    else if (Mode>=0x20 || Mode<=0x0f)
1360
    {
1361
        printf("reserved]\n"); return;
1362
    }
1363
    else
1364
    {
1365
        printf("user defined]\n"); return;
1366
    }
1367
    printf(((Mode & 0x0f)>=0x0c) ? " supervisory":" non-privileged");
1368
    switch (Mode & 0x03)
1369
    {
1370
        case 1:printf(" data access"); break;
1371
        case 2:printf(" code access"); break;
1372
        case 3:printf(" block transfer"); break;
1373
    }
1374
    printf("]\n");
1375
}
1376
 
1377
//-----------------------------------------------------------------------------
1378
// provides some diagnostic information abot interface registers
1379
static void ShowRegister(void)                /* Zeige Inhalt von ? */
1380
{
1381
    char *szInstg;
1382
    char type;
1383
 
1384
    if ((szInstg = ParaStr(1)) == NULL)
1385
        type = '0';
1386
    else
1387
        type = szInstg[1];
1388
 
1389
    if (type == 0)
1390
        type = '0';
1391
 
1392
    GetInterfaceInfo(nInterfaceHandle, type);
1393
}
1394
 
1395
//-----------------------------------------------------------------------------
1396
// make a random memory test to VME
1397
static void RandomTest(void)
1398
{
1399
    char          DefZug = ' ';          /* Zugriffsart */
1400
    int           Len;                   /* Item Laenge */
1401
    unsigned long Idx;                   /* Index */
1402
    unsigned long End;                   /* Endadresse */
1403
    unsigned long Seed;                  /* initial seed */
1404
    unsigned char Merk_error = 0;        /* Haelt error flag */
1405
    int           Patt;
1406
    unsigned long i;
1407
 
1408
    unsigned long  lResult;
1409
    unsigned short wResult;
1410
    unsigned char  bResult;
1411
    int            repeats = 0;
1412
    int            Loop = 0;
1413
 
1414
    if (GetZug(&DefZug)!=' ')
1415
    {
1416
        Len=1;
1417
        switch (GetZug(&DefZug))           /* Zugriffsmodus festlegen */
1418
        {
1419
            case 'L':Len += 2;               /* Auf Long-Adresse biegen */
1420
            case 'W':Len++;                  /* Auf Wort-Adresse biegen */
1421
        }
1422
        Idx=ParaNum(2) & -(long)Len;       /* Adressen geradebiegen */
1423
        End=ParaNum(3);                    /* Endadresse festlegen */
1424
        if (ParaStr(4) == NULL)
1425
            Loop = 1;
1426
        else
1427
            Loop=ParaNum(4);
1428
        if (ParaStr(5) == NULL)
1429
            Seed = 0x1234;
1430
        else
1431
            Seed=ParaNum(5);
1432
 
1433
        do
1434
        {
1435
            srand(Seed + repeats);
1436
            i = Idx;
1437
            while ((i <= End) && (!Abbruch))
1438
            {
1439
                Patt = rand();
1440
 
1441
                switch (DefZug)
1442
                {
1443
                    case 'L':Patt <<= 16;
1444
                        Patt  |= rand();
1445
                        WriteLong(nInterfaceHandle, i, Patt, AdrMode);
1446
                        break;
1447
                    case 'W':WriteWord(nInterfaceHandle, i, (short)Patt, AdrMode);
1448
                        break;
1449
                    case 'B':WriteByte(nInterfaceHandle, i, (char)Patt, AdrMode);
1450
                        break;
1451
                } /* switch */
1452
 
1453
                if (GetError(nInterfaceHandle))
1454
                {
1455
                    ClearError(nInterfaceHandle);                  /* Fehler abfangen */
1456
                    Merk_error |= 2;
1457
                }
1458
 
1459
                if ((i & 0xffl)==0)
1460
                {                                /* Ermoegliche Ctrl-C */
1461
                    printf("\r");
1462
                }
1463
 
1464
                i += Len;
1465
            } /* while */
1466
 
1467
            // read and compare
1468
            srand(Seed + repeats);
1469
            i = Idx;
1470
            while ((i <= End) && (!Abbruch))
1471
            {
1472
                Patt = rand();
1473
 
1474
                switch (DefZug)
1475
                {
1476
                    case 'L':lResult = ReadLong(nInterfaceHandle, i, AdrMode);
1477
                        Patt <<= 16;
1478
                        Patt |= rand();
1479
                        if (lResult != (unsigned long)Patt)
1480
                        {
1481
                            printf("Compare Fail 0x%08x w=0x%08lx r=0x%08lx\n", i, Patt, lResult);
1482
                            Merk_error |= 1;
1483
                        }
1484
                        break;
1485
                    case 'W':wResult = ReadWord(nInterfaceHandle, i, AdrMode);
1486
                        if (wResult != (unsigned short)Patt)
1487
                        {
1488
                            printf("Compare Fail 0x%08x w=0x%04x r=0x%04x\n", i, Patt & 0xFFFF, wResult);
1489
                            Merk_error |= 1;
1490
                        }
1491
                        break;
1492
                    case 'B':bResult = ReadByte(nInterfaceHandle, i, AdrMode);
1493
                        if (bResult != (unsigned char)Patt)
1494
                        {
1495
                            printf("Compare Fail 0x%08x w=0x%02x r=0x%02x\n", i, Patt & 0xFF, bResult);
1496
                            Merk_error |= 1;
1497
                        }
1498
                        break;
1499
                } /* switch */
1500
 
1501
                if (GetError(nInterfaceHandle))
1502
                {
1503
                    ClearError(nInterfaceHandle);                  /* Fehler abfangen */
1504
                    Merk_error |= 2;
1505
                }
1506
 
1507
                if ((i & 0xffl)==0)
1508
                {                                /* Ermoegliche Ctrl-C */
1509
                    printf("\r");
1510
                }
1511
 
1512
                i += Len;
1513
            } /* while */
1514
 
1515
            if (Loop)
1516
                printf("\rRepeats: 0x%x\r", repeats);
1517
            repeats++;
1518
        } while ((Loop--) && !(Merk_error));
1519
 
1520
        if (Merk_error)
1521
            printf("--> Compare failed %s\a\n", (Merk_error & 2) ? "with Bus Error" : "");
1522
        else
1523
            printf("--> Compare successfull\n");
1524
 
1525
    }
1526
    else printf("\a");
1527
 
1528
}
1529
 
1530
//-----------------------------------------------------------------------------
1531
// modify interface registers
1532
static void ModifyRegister(void)
1533
{
1534
    __u32 Erg;
1535
 
1536
    if (ParaStr(2) != NULL)
1537
    {
1538
        if (ParaStr(3) != NULL)
1539
        {
1540
            Erg = _SetRegister(nInterfaceHandle, ParaNum(2),ParaNum(3));
1541
            printf("Interface register @ 0x%08lx set: 0x%02x, get: 0x%02x\n",
1542
                   ParaNum(2), ParaNum(3), Erg);
1543
        }
1544
        else
1545
        {
1546
            Erg = _GetRegister(nInterfaceHandle, ParaNum(2));
1547
            printf("Interface register @ 0x%08lx get: 0x%02x\n", ParaNum(2), Erg);
1548
        }
1549
    }
1550
    else
1551
        printf("\a");
1552
}
1553
 
1554
//-----------------------------------------------------------------------------
1555
// the main menu
1556
static int HauptMenue(STRG Stg)        /* Eingabe & Dispatcher */
1557
{
1558
    char *SSt;                           /* Sourcezeiger */
1559
    char *DSt;                           /* Destzeiger */
1560
    char  Del;                           /* Delimiter vorhanden? */
1561
    int   Ret;                           /* Returncode fuer Auto-Mode */
1562
    char  loop;                          /* irgedwie war baengg fuer loop */
1563
 
1564
 
1565
    if (Stg == NULL)
1566
        loop = 1;
1567
    else
1568
        loop = 0;
1569
 
1570
    do
1571
    {
1572
        if (loop)
1573
        {                                  /* Auto-Modus? */
1574
            if (Abbruch)
1575
            {
1576
                printf("\n");
1577
                Abbruch = 0;
1578
            }
1579
 
1580
            printf("pv: ");                  /* Nein, Prompt ausgeben und */
1581
            if (*ReadMessageBuffer())
1582
            {
1583
                printf("%s\n", ReadMessageBuffer());
1584
                printf("pv: ");
1585
                InitMessageBuffer();
1586
            }
1587
            _gets(InStg);                     /* Eingabestring holen */
1588
            // GetError(nInterfaceHandle);                      /* because of interrupts */
1589
            SSt=InStg;                       /* Init Sourcezeiger */
1590
        }
1591
        else
1592
            SSt=Stg;                         /* Uebernehme Parameter aus Stg */
1593
 
1594
        DSt=InStg;                         /* Init Destzeiger */
1595
        Del=True;                          /* Weitere Delimiter raus */
1596
        Ret=0;                             /* Keine Fehler bis jetzt */
1597
 
1598
        while (*SSt)
1599
        {                                  /* Arbeite String ab */
1600
            if (UpCase(*SSt) >= 'A' &&       /* Filtern gueltiger Zeichen */
1601
                UpCase(*SSt) <= 'Z' ||
1602
                *SSt >= '0'  && *SSt <= '9' ||
1603
                *SSt == ':'  || *SSt == '.' ||
1604
                *SSt == '\\' || *SSt == '?')
1605
            {
1606
                *DSt=UpCase(*SSt);
1607
                Del=False;
1608
                DSt++;
1609
            }
1610
            else
1611
            {
1612
                if (!Del)
1613
                {
1614
                    *DSt=' ';
1615
                    DSt++;
1616
                }                              /* Mehrere Delimiter raus */
1617
                Del=True;                      /* und durch ' ' ersetzen */
1618
            }
1619
            SSt++;
1620
        } /* while (*SSt) */
1621
        *DSt=*SSt;                         /* 0 auch uebertragen */
1622
 
1623
        switch (*ParaStr(1))
1624
        {
1625
            case 'A': SetModifier(); break;
1626
            case 'D': Dump(); break;
1627
            case 'E': Examine(); break;      /* Speicherbereich aendern */
1628
            case 'F': Fill(); break;         /* Speicherbereich fuellen */
1629
            case 'G': RandomTest(); break;   /* random test of memory */
1630
            case 'H':
1631
            case '?': Hilfe(); break;        /* Hilf mir mal */
1632
            case 'I': DeInit_Interface(nInterfaceHandle);
1633
                      InitAt(cszDevicePath, &nInterfaceHandle);
1634
                      break;                 /* Nochmals initialisieren */
1635
            case 'C': Konfig(); break;       /* Konfiguration */
1636
            case 'L': ReadIrqVect(); break;  /* Interrupt-Vektoren lesen */
1637
            case 'M': Move(); break;         /* Move Funktion */
1638
            case 'O': JumpToDos(); break;    /* DOS Ausgang */
1639
            case 'P': SearchPorts(); break;  /* Ports suchen */
1640
            case 'Q': Raus();return(0);      /* Ende des Debuggers */
1641
            case 'R': Ret=_ReadFile(); break; /* Eine Datei nach VME lesen */
1642
            case 'S': SeekPatt(); break;     /* Suche nach Datenmustern */
1643
            case 'T': TestSet(); break;      /* Fuehre ein TAS aus */
1644
            case 'V': ResetVme(); break;     /* Erzeuge VME-Reset */
1645
            case 'W': Ret=_WriteFile(); break;/* Eine Datei von VME schreiben */
1646
            case 'Y': SysFail(); break;      /* read, set Sysfail */
1647
            case 'X': ModifyRegister(); break; /* modify register of the interface */
1648
            case 'Z': ShowRegister(); break; /* Register ausgeben */
1649
            default :
1650
                {
1651
                    Ret=2;                /* Fehlercode zurueck fuer Auto */
1652
                    if (!loop)
1653
                    {                     /* Wenn Auto: Hilfsmessage */
1654
                        Hilfe();
1655
                        printf("\nSplit commands with \"/\" ,e.g. \"a39/d1000\"");
1656
                    }
1657
                }
1658
        } /* switch */
1659
    } while (loop);                 /* Hier raus bei Auto-Mode */
1660
    return(Ret);
1661
}
1662
 
1663
//-------------------------------------------------------------------------------------
1664
// the exit entry
1665
static void MyExit(int bla)            /* Wird im Ctrl-C-Falle aufgerufen */
1666
{
1667
    Abbruch = 1;                      
1668
}
1669
 
1670
//-------------------------------------------------------------------------------------
1671
// where all starts
1672
int main(int argc, char **argv, char *envp[])
1673
{
1674
    static STRG  Stg;                    /* Zum zusammenlegen Parameter */
1675
    char *PSt;                           /* Arbeitszeiger Multicommands */
1676
    char *SSt;                           /* Quellzeiger Multicommands */
1677
    int   Idx;                           /* Index */
1678
    int   Ret;                           /* Returncode */
1679
 
1680
    InitMessageBuffer();
1681
 
1682
    cszDevicePath = &localBuffer[0];
1683
 
1684
    Ret=1;                               /* Returncode auf Fehler setzen */
1685
    ArgV=argv;                           /* Uebertrage argv fuer LoadKonfig */
1686
    LoadKonfig();                        /* Versuchen Konfigdatei zu lesen */
1687
 
1688
    if (argc > 1)
1689
    {                                    /* Kommandozeilenparameter da? */
1690
        if (InitAt(cszDevicePath, &nInterfaceHandle))
1691
        {                                  /* Aufsetzen Interface */
1692
            *Stg='\0';                       /* Stg auf nix setzen */
1693
            for (Idx=1; Idx < argc; Idx++)
1694
            {
1695
                strcat(Stg,argv[Idx]);         /* Haenge Parameter hintereinander */
1696
                strcat(Stg," ");               /* Trenne mit Leerzeichen */
1697
            }
1698
 
1699
            SSt=Stg;                         /* Saubloedes (*Zeug) mit den ARRAYS! */
1700
            do
1701
            {
1702
                if ((PSt=strchr(SSt,'/'))!=NULL) *PSt='\0';
1703
                Ret=HauptMenue(SSt);           /* Hauptmenue automatisch aufrufen */
1704
                SSt=PSt+1;                     /* SSt auf den Reststring setzen */
1705
            }
1706
 
1707
            while (PSt!=NULL && !Ret);     /* Bis Fehler oder Fertig */
1708
        }
1709
    }
1710
    else
1711
    {
1712
        printf("Provided under GPL - version %s of pvmon of %s \n\n", VERSION, __DATE__);
1713
        printf("This program is free software;  you can redistribute it and/or modify it\n");
1714
        printf("under the terms of the GPL as published by the FSF (version 2 or later).\n");
1715
        printf("Copyright:  Ralf Dux,  Sven Hannover,  Klaus Hitschler,  Sven Tuecke, AR\n");
1716
 
1717
        InitAt(cszDevicePath, &nInterfaceHandle); /* Aufsetzen Interface */
1718
        signal(SIGINT, MyExit);            /* Eigenen Handler einklinken */
1719
        Ret=HauptMenue(NULL);              /* Hauptmenue manuell aufrufen */
1720
    } /* else */
1721
    DeInit_Interface(nInterfaceHandle);  /* Interface ausschalten */
1722
 
1723
    return(Ret);                         /* Fehlercode fuer ErrorLevel */
1724
}
1725
 
1726
//-------------------------------------------------------------------------------------------
1727
//-------------------------------------------------------------------------------------------
1728
//-------------------------------------------------------------------------------------------