OpenCores
URL https://opencores.org/ocsvn/xulalx25soc/xulalx25soc/trunk

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [sw/] [zipdbg.cpp] - Blame information for rev 5

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 dgisselq
///////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    zipdbg.cpp
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
6
//
7
// Purpose:     
8
//
9
//
10
// Creator:     Dan Gisselquist, Ph.D.
11
//              Gisselquist Tecnology, LLC
12
//
13
///////////////////////////////////////////////////////////////////////////////
14
//
15
// Copyright (C) 2015, Gisselquist Technology, LLC
16
//
17
// This program is free software (firmware): you can redistribute it and/or
18
// modify it under the terms of  the GNU General Public License as published
19
// by the Free Software Foundation, either version 3 of the License, or (at
20
// your option) any later version.
21
//
22
// This program is distributed in the hope that it will be useful, but WITHOUT
23
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
24
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25
// for more details.
26
//
27
// License:     GPL, v3, as defined and found on www.gnu.org,
28
//              http://www.gnu.org/licenses/gpl.html
29
//
30
//
31
///////////////////////////////////////////////////////////////////////////////
32
//
33
//
34
#include <stdlib.h>
35
#include <signal.h>
36
#include <time.h>
37
#include <unistd.h>
38
 
39
#include <ctype.h>
40
#include <ncurses.h>
41
 
42
#include "zopcodes.h"
43
#include "zparser.h"
44
#include "devbus.h"
45
#include "regdefs.h"
46
 
47
#include "usbi.h"
48
#include "port.h"
49
 
50
#define CMD_REG         0
51
#define CMD_DATA        1
52
#define CMD_HALT        (1<<10)
53
#define CMD_STALL       (1<<9)
54
#define CMD_STEP        (1<<8)
55
#define CMD_INT         (1<<7)
56
#define CMD_RESET       (1<<6)
57
 
58
#define KEY_ESCAPE      27
59
#define KEY_RETURN      10
60
#define CTRL(X)         ((X)&0x01f)
61
 
62
#define MAXERR  1000    // 1k cycles
63
 
64
bool    gbl_err = false;
65
 
66
// No particular "parameters" need definition or redefinition here.
67
class   ZIPPY : public DEVBUS {
68
        typedef DEVBUS::BUSW    BUSW;
69
        DEVBUS  *m_fpga;
70
        int     m_cursor;
71
public:
72
        ZIPPY(DEVBUS *fpga) : m_fpga(fpga), m_cursor(0) {}
73
 
74
        void    kill(void) { m_fpga->kill(); }
75
        void    close(void) { m_fpga->close(); }
76
        void    writeio(const BUSW a, const BUSW v) { m_fpga->writeio(a, v); }
77
        BUSW    readio(const BUSW a) { return m_fpga->readio(a); }
78
        void    readi(const BUSW a, const int len, BUSW *buf) {
79
                return m_fpga->readi(a, len, buf); }
80
        void    readz(const BUSW a, const int len, BUSW *buf) {
81
                return m_fpga->readz(a, len, buf); }
82
        void    writei(const BUSW a, const int len, const BUSW *buf) {
83
                return m_fpga->writei(a, len, buf); }
84
        void    writez(const BUSW a, const int len, const BUSW *buf) {
85
                return m_fpga->writez(a, len, buf); }
86
        bool    poll(void) { return m_fpga->poll(); }
87
        void    usleep(unsigned ms) { m_fpga->usleep(ms); }
88
        void    wait(void) { m_fpga->wait(); }
89
        bool    bus_err(void) const { return m_fpga->bus_err(); }
90
        void    reset_err(void) { m_fpga->reset_err(); }
91
        void    clear(void) { m_fpga->clear(); }
92
 
93
        void    reset(void) { writeio(R_ZIPCTRL, CPU_RESET|CPU_HALT); }
94
        void    step(void) { writeio(R_ZIPCTRL, CPU_STEP); }
95
        void    go(void) { writeio(R_ZIPCTRL, CPU_GO); }
96
        void    halt(void) {    writeio(R_ZIPCTRL, CPU_HALT); }
97
        bool    stalled(void) { return ((readio(R_ZIPCTRL)&CPU_STALL)==0); }
98
 
99
        void    showval(int y, int x, const char *lbl, unsigned int v, bool c) {
100
                if (c)
101
                        mvprintw(y,x, ">%s> 0x%08x<", lbl, v);
102
                else
103
                        mvprintw(y,x, " %s: 0x%08x ", lbl, v);
104
        }
105
 
106
        void    dispreg(int y, int x, const char *n, unsigned int v, bool c) {
107
                // 4,4,8,1 = 17 of 20, +2 = 18
108
                if (c)
109
                        mvprintw(y, x, ">%s> 0x%08x<", n, v);
110
                else
111
                        mvprintw(y, x, " %s: 0x%08x ", n, v);
112
        }
113
 
114
        void    showins(int y, const char *lbl,
115
                        const int gie, const unsigned int pc) {
116
                char    line[80];
117
                unsigned int    v;
118
 
119
                mvprintw(y, 0, "%s: 0x%08x", lbl, pc);
120
 
121
                if (gie) attroff(A_BOLD);
122
                else    attron(A_BOLD);
123
 
124
                line[0] = '\0';
125
                try {
126
                        v= readio(pc);
127
                        zipi_to_string(v, line);
128
                        printw(" 0x%08x", v);
129
                        printw("  %-24s", &line[1]);
130
                } catch(BUSERR b) {
131
                        printw(" 0x%08x  %-24s", b.addr, "(Bus Error)");
132
                }
133
                attroff(A_BOLD);
134
        }
135
 
136
        unsigned int    cmd_read(unsigned int a) {
137
                int     errcount = 0;
138
 
139
                if (gbl_err)
140
                        return 0;
141
 
142
                writeio(R_ZIPCTRL, CMD_HALT|(a&0x3f));
143
                while(((readio(R_ZIPCTRL) & CPU_STALL) == 0)&&(errcount < MAXERR))
144
                        errcount++;
145
                if (errcount < MAXERR)
146
                        return readio(R_ZIPDATA);
147
                else {
148
                        gbl_err = true;
149
                        return 0;
150
                }
151
        }
152
 
153
        void    cmd_write(unsigned int a, int v) {
154
                if (gbl_err)
155
                        return;
156
 
157
                int     errcount = 0;
158
                writeio(R_ZIPCTRL, CMD_HALT|(a&0x3f));
159
                while(((readio(R_ZIPCTRL) & CPU_STALL) == 0)&&(errcount < MAXERR))
160
                        errcount++;
161
                if (errcount < MAXERR)
162
                        writeio(R_ZIPDATA, (unsigned int)v);
163
                else
164
                        gbl_err = true;
165
        }
166
 
167
        void    read_state(void) {
168
                int     ln= 0;
169
                bool    gie;
170
 
171
                if (m_cursor < 0)
172
                        m_cursor = 0;
173
                else if (m_cursor >= 44)
174
                        m_cursor = 43;
175
 
176
                mvprintw(ln,0, "Peripherals");
177
                mvprintw(ln,40,"%-40s", "CPU State: ");
178
                {
179
                        unsigned int v = readio(R_ZIPCTRL);
180
                        mvprintw(ln,51, "");
181
                        if (v & 0x010000)
182
                                printw("EXT-INT ");
183
                        if ((v & 0x003000) == 0x03000)
184
                                printw("Halted ");
185
                        else if (v & 0x001000)
186
                                printw("Sleeping ");
187
                        else if (v & 0x002000)
188
                                printw("Supervisor Mod ");
189
                        if (v & 0x008000)
190
                                printw("Break-Enabled ");
191
                        if (v & 0x000080)
192
                                printw("PIC Enabled ");
193
                } ln++;
194
                showval(ln, 0, "PIC ", cmd_read(32+ 0), (m_cursor==0));
195
                showval(ln,20, "WDT ", cmd_read(32+ 1), (m_cursor==1));
196
                showval(ln,40, "WBUS", cmd_read(32+ 2), (m_cursor==2));
197
                showval(ln,60, "PIC2", cmd_read(32+ 3), (m_cursor==3));
198
                ln++;
199
                showval(ln, 0, "TMRA", cmd_read(32+ 4), (m_cursor==4));
200
                showval(ln,20, "TMRB", cmd_read(32+ 5), (m_cursor==5));
201
                showval(ln,40, "TMRC", cmd_read(32+ 6), (m_cursor==6));
202
                showval(ln,60, "JIF ", cmd_read(32+ 7), (m_cursor==7));
203
 
204
                ln++;
205
                showval(ln, 0, "UTSK", cmd_read(32+12), (m_cursor==8));
206
                showval(ln,20, "UMST", cmd_read(32+13), (m_cursor==9));
207
                showval(ln,40, "UPST", cmd_read(32+14), (m_cursor==10));
208
                showval(ln,60, "UICT", cmd_read(32+15), (m_cursor==11));
209
 
210
                ln++;
211
                ln++;
212
                unsigned int cc = cmd_read(14);
213
                gie = (cc & 0x020);
214
                if (gie)
215
                        attroff(A_BOLD);
216
                else
217
                        attron(A_BOLD);
218
                mvprintw(ln, 0, "Supervisor Registers");
219
                ln++;
220
 
221
                dispreg(ln, 0, "sR0 ", cmd_read(0), (m_cursor==12));
222
                dispreg(ln,20, "sR1 ", cmd_read(1), (m_cursor==13));
223
                dispreg(ln,40, "sR2 ", cmd_read(2), (m_cursor==14));
224
                dispreg(ln,60, "sR3 ", cmd_read(3), (m_cursor==15)); ln++;
225
 
226
                dispreg(ln, 0, "sR4 ", cmd_read(4), (m_cursor==16));
227
                dispreg(ln,20, "sR5 ", cmd_read(5), (m_cursor==17));
228
                dispreg(ln,40, "sR6 ", cmd_read(6), (m_cursor==18));
229
                dispreg(ln,60, "sR7 ", cmd_read(7), (m_cursor==19)); ln++;
230
 
231
                dispreg(ln, 0, "sR8 ", cmd_read( 8), (m_cursor==20));
232
                dispreg(ln,20, "sR9 ", cmd_read( 9), (m_cursor==21));
233
                dispreg(ln,40, "sR10", cmd_read(10), (m_cursor==22));
234
                dispreg(ln,60, "sR11", cmd_read(11), (m_cursor==23)); ln++;
235
 
236
                dispreg(ln, 0, "sR12", cmd_read(12), (m_cursor==24));
237
                dispreg(ln,20, "sSP ", cmd_read(13), (m_cursor==25));
238
 
239
                mvprintw(ln,40, "%csCC :%s%s%s%s%s%s%s%s",
240
                        (m_cursor==26)?'>':' ',
241
                        (cc & 0x100)?"TP":"  ",
242
                        (cc & 0x040)?"ST":"  ",
243
                        (cc & 0x020)?"IE":"  ",
244
                        (cc & 0x010)?"SL":"  ",
245
                        (cc&8)?"V":" ",
246
                        (cc&4)?"N":" ",
247
                        (cc&2)?"C":" ",
248
                        (cc&1)?"Z":" ");
249
                dispreg(ln,60, "sPC ", cmd_read(15), (m_cursor==27));
250
                ln++;
251
 
252
                if (gie)
253
                        attron(A_BOLD);
254
                else
255
                        attroff(A_BOLD);
256
                mvprintw(ln, 0, "User Registers"); ln++;
257
                dispreg(ln, 0, "uR0 ", cmd_read(16), (m_cursor==28));
258
                dispreg(ln,20, "uR1 ", cmd_read(17), (m_cursor==29));
259
                dispreg(ln,40, "uR2 ", cmd_read(18), (m_cursor==30));
260
                dispreg(ln,60, "uR3 ", cmd_read(19), (m_cursor==31)); ln++;
261
 
262
                dispreg(ln, 0, "uR4 ", cmd_read(20), (m_cursor==32));
263
                dispreg(ln,20, "uR5 ", cmd_read(21), (m_cursor==33));
264
                dispreg(ln,40, "uR6 ", cmd_read(22), (m_cursor==34));
265
                dispreg(ln,60, "uR7 ", cmd_read(23), (m_cursor==35)); ln++;
266
 
267
                dispreg(ln, 0, "uR8 ", cmd_read(24), (m_cursor==36));
268
                dispreg(ln,20, "uR9 ", cmd_read(25), (m_cursor==37));
269
                dispreg(ln,40, "uR10", cmd_read(26), (m_cursor==38));
270
                dispreg(ln,60, "uR11", cmd_read(27), (m_cursor==39)); ln++;
271
 
272
                dispreg(ln, 0, "uR12", cmd_read(28), (m_cursor==40));
273
                dispreg(ln,20, "uSP ", cmd_read(29), (m_cursor==41));
274
                cc = cmd_read(30);
275
                mvprintw(ln,40, "%cuCC :%s%s%s%s%s%s%s%s",
276
                        (m_cursor == 42)?'>':' ',
277
                        (cc&0x100)?"TP":"  ",
278
                        (cc&0x040)?"ST":"  ",
279
                        (cc&0x020)?"IE":"  ",
280
                        (cc&0x010)?"SL":"  ",
281
                        (cc&8)?"V":" ",
282
                        (cc&4)?"N":" ",
283
                        (cc&2)?"C":" ",
284
                        (cc&1)?"Z":" ");
285
                dispreg(ln,60, "uPC ", cmd_read(31), (m_cursor==43));
286
 
287
                attroff(A_BOLD);
288
                ln+=2;
289
 
290
                ln+=3;
291
                BUSW pc = cmd_read((gie)?31:15);
292
                showins(ln, "I ", gie, pc+2); ln++;
293
                showins(ln, "Dc", gie, pc+1); ln++;
294
                showins(ln, "Op", gie, pc  ); ln++;
295
                showins(ln, "Al", gie, pc-1); ln++;
296
        }
297
 
298
        void    cursor_up(void) {
299
                if (m_cursor > 3)
300
                        m_cursor -= 4;
301
        } void  cursor_down(void) {
302
                if (m_cursor < 40)
303
                        m_cursor += 4;
304
        } void  cursor_left(void) {
305
                if (m_cursor > 0)
306
                        m_cursor--;
307
                else    m_cursor = 43;
308
        } void  cursor_right(void) {
309
                if (m_cursor < 43)
310
                        m_cursor++;
311
                else    m_cursor = 0;
312
        }
313
 
314
        int     cursor(void) { return m_cursor; }
315
};
316
 
317
FPGA    *m_fpga;
318
 
319
void    get_value(ZIPPY *zip) {
320
        int     wy, wx, ra;
321
        int     c = zip->cursor();
322
 
323
        wx = (c & 0x03) * 20 + 9 + 1;
324
        wy = (c >> 2);
325
        if (wy >= 3+4)
326
                wy++;
327
        if (wy > 3)
328
                wy += 2;
329
        wy++;
330
 
331
        if (c >= 12)
332
                ra = c - 12;
333
        else
334
                ra = c + 32;
335
 
336
        bool    done = false;
337
        char    str[16];
338
        int     pos = 0; str[pos] = '\0';
339
        while(!done) {
340
                int     chv = getch();
341
                switch(chv) {
342
                case KEY_ESCAPE:
343
                        pos = 0; str[pos] = '\0'; done = true;
344
                        break;
345
                case KEY_RETURN: case KEY_ENTER: case KEY_UP: case KEY_DOWN:
346
                        done = true;
347
                        break;
348
                case KEY_LEFT: case KEY_BACKSPACE:
349
                        if (pos > 0) pos--;
350
                        break;
351
                case KEY_CLEAR:
352
                        pos = 0;
353
                        break;
354
                case '0': case ' ': str[pos++] = '0'; break;
355
                case '1': str[pos++] = '1'; break;
356
                case '2': str[pos++] = '2'; break;
357
                case '3': str[pos++] = '3'; break;
358
                case '4': str[pos++] = '4'; break;
359
                case '5': str[pos++] = '5'; break;
360
                case '6': str[pos++] = '6'; break;
361
                case '7': str[pos++] = '7'; break;
362
                case '8': str[pos++] = '8'; break;
363
                case '9': str[pos++] = '9'; break;
364
                case 'A': case 'a': str[pos++] = 'A'; break;
365
                case 'B': case 'b': str[pos++] = 'B'; break;
366
                case 'C': case 'c': str[pos++] = 'C'; break;
367
                case 'D': case 'd': str[pos++] = 'D'; break;
368
                case 'E': case 'e': str[pos++] = 'E'; break;
369
                case 'F': case 'f': str[pos++] = 'F'; break;
370
                }
371
 
372
                if (pos > 8)
373
                        pos = 8;
374
                str[pos] = '\0';
375
 
376
                attron(A_NORMAL | A_UNDERLINE);
377
                mvprintw(wy, wx, "%-8s", str);
378
                if (pos > 0) {
379
                        attron(A_NORMAL | A_UNDERLINE | A_BLINK);
380
                        mvprintw(wy, wx+pos-1, "%c", str[pos-1]);
381
                }
382
                attrset(A_NORMAL);
383
        }
384
 
385
        if (pos > 0) {
386
                int     v;
387
                v = strtoul(str, NULL, 16);
388
                zip->cmd_write(ra, v);
389
        }
390
}
391
 
392
void    on_sigint(int v) {
393
        endwin();
394
 
395
        fprintf(stderr, "Interrupted!\n");
396
        exit(-2);
397
}
398
 
399
int     main(int argc, char **argv) {
400
        // FPGAOPEN(m_fpga);
401
        ZIPPY   *zip; //
402
 
403
        int     skp=0, port = FPGAPORT;
404
        bool    use_usb = true;
405
 
406
        skp=1;
407
        for(int argn=0; argn<argc-skp; argn++) {
408
                if (argv[argn+skp][0] == '-') {
409
                        if (argv[argn+skp][1] == 'u')
410
                                use_usb = true;
411
                        else if (argv[argn+skp][1] == 'p') {
412
                                use_usb = false;
413
                                if (isdigit(argv[argn+skp][2]))
414
                                        port = atoi(&argv[argn+skp][2]);
415
                        }
416
                        skp++; argn--;
417
                } else
418
                        argv[argn] = argv[argn+skp];
419
        } argc -= skp;
420
 
421
        if (use_usb)
422
                m_fpga = new FPGA(new USBI());
423
        else
424
                m_fpga = new FPGA(new NETCOMMS(FPGAHOST, port));
425
        zip = new ZIPPY(m_fpga);
426
 
427
 
428
        initscr();
429
        raw();
430
        noecho();
431
        keypad(stdscr, true);
432
 
433
        signal(SIGINT, on_sigint);
434
 
435
        int     chv;
436
        bool    done = false;
437
 
438
        zip->halt();
439
        for(int i=0; (i<5)&&(zip->stalled()); i++)
440
                ;
441
        if (!zip->stalled())
442
                zip->read_state();
443
        while((!done)&&(!gbl_err)) {
444
                chv = getch();
445
                switch(chv) {
446
                case 'g': case 'G':
447
                        m_fpga->writeio(R_ZIPCTRL, CPU_GO);
448
                        // We just released the CPU, so we're now done.
449
                        done = true;
450
                        break;
451
                case 'l': case 'L': case CTRL('L'):
452
                        redrawwin(stdscr);
453
                        break;
454
                case 'q': case 'Q': case CTRL('C'):
455
                case KEY_CANCEL: case KEY_CLOSE: case KEY_EXIT:
456
                case KEY_ESCAPE:
457
                        done = true;
458
                        break;
459
                case 'r': case 'R':
460
                        zip->reset();
461
                        erase();
462
                        break;
463
                case 's': case 'S':
464
                        zip->step();
465
                        zip->read_state();
466
                        break;
467
                case KEY_IC: case KEY_ENTER:
468
                        get_value(zip);
469
                        break;
470
                case KEY_UP:
471
                        zip->cursor_up();
472
                        break;
473
                case KEY_DOWN:
474
                        zip->cursor_down();
475
                        break;
476
                case KEY_LEFT:
477
                        zip->cursor_left();
478
                        break;
479
                case KEY_RIGHT:
480
                        zip->cursor_right();
481
                        break;
482
                case ERR: case KEY_CLEAR:
483
                default:
484
                        ;
485
                }
486
 
487
                if ((!done)&&(!gbl_err)) {
488
                        if (zip->stalled())
489
                                erase();
490
                }
491
        }
492
 
493
        endwin();
494
 
495
        if (gbl_err) {
496
                printf("Killed on error: could not access bus!\n");
497
                exit(-2);
498
        }
499
}
500
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.