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

Subversion Repositories xulalx25soc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 76 dgisselq
////////////////////////////////////////////////////////////////////////////////
2 5 dgisselq
//
3 76 dgisselq
// Filename:    zipdbg.cpp
4 5 dgisselq
//
5 76 dgisselq
// Project:     XuLA2-LX25 SoC based upon the ZipCPU
6 5 dgisselq
//
7 76 dgisselq
// Purpose:     Provide a debugger to step through the ZipCPU assembler,
8
//              evaluate the ZipCPU's current state, modify registers as(if)
9
//      needed, etc.  All of this through the JTAG port of the XuLA2 board.
10 5 dgisselq
//
11
// Creator:     Dan Gisselquist, Ph.D.
12 76 dgisselq
//              Gisselquist Technology, LLC
13 5 dgisselq
//
14 76 dgisselq
////////////////////////////////////////////////////////////////////////////////
15 5 dgisselq
//
16 76 dgisselq
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
17 5 dgisselq
//
18
// This program is free software (firmware): you can redistribute it and/or
19
// modify it under the terms of  the GNU General Public License as published
20
// by the Free Software Foundation, either version 3 of the License, or (at
21
// your option) any later version.
22
//
23
// This program is distributed in the hope that it will be useful, but WITHOUT
24
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
25
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26
// for more details.
27
//
28 76 dgisselq
// You should have received a copy of the GNU General Public License along
29
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
30
// target there if the PDF file isn't present.)  If not, see
31
// <http://www.gnu.org/licenses/> for a copy.
32
//
33 5 dgisselq
// License:     GPL, v3, as defined and found on www.gnu.org,
34
//              http://www.gnu.org/licenses/gpl.html
35
//
36
//
37 76 dgisselq
////////////////////////////////////////////////////////////////////////////////
38 5 dgisselq
//
39
//
40 7 dgisselq
// BUGS:
41
//      - No ability to verify CPU functionality (3rd party simulator)
42
//      - No ability to set/clear breakpoints
43
//
44
//
45 5 dgisselq
#include <stdlib.h>
46
#include <signal.h>
47
#include <time.h>
48
#include <unistd.h>
49 7 dgisselq
#include <string.h>
50 5 dgisselq
 
51
#include <ctype.h>
52
#include <ncurses.h>
53
 
54
#include "zopcodes.h"
55
#include "zparser.h"
56
#include "devbus.h"
57
#include "regdefs.h"
58
 
59
#include "usbi.h"
60
#include "port.h"
61
 
62
#define CMD_REG         0
63
#define CMD_DATA        1
64
#define CMD_HALT        (1<<10)
65
#define CMD_STALL       (1<<9)
66
#define CMD_STEP        (1<<8)
67
#define CMD_INT         (1<<7)
68
#define CMD_RESET       (1<<6)
69
 
70
#define KEY_ESCAPE      27
71
#define KEY_RETURN      10
72
#define CTRL(X)         ((X)&0x01f)
73
 
74 7 dgisselq
class   SPARSEMEM {
75
public:
76
        bool    m_valid;
77
        unsigned int    m_a, m_d;
78
};
79 5 dgisselq
 
80
bool    gbl_err = false;
81 7 dgisselq
class   ZIPSTATE {
82
public:
83
        bool            m_valid, m_gie, m_last_pc_valid;
84
        unsigned int    m_sR[16], m_uR[16];
85
        unsigned int    m_p[20];
86
        unsigned int    m_last_pc, m_pc, m_sp;
87
        SPARSEMEM       m_smem[5];
88
        SPARSEMEM       m_imem[5];
89
        ZIPSTATE(void) : m_valid(false), m_last_pc_valid(false) {}
90 5 dgisselq
 
91 7 dgisselq
        void    step(void) {
92
                m_last_pc_valid = true;
93
                m_last_pc = m_pc;
94
        }
95
};
96
 
97 5 dgisselq
// No particular "parameters" need definition or redefinition here.
98
class   ZIPPY : public DEVBUS {
99 7 dgisselq
        static  const   int     MAXERR;
100 5 dgisselq
        typedef DEVBUS::BUSW    BUSW;
101
        DEVBUS  *m_fpga;
102
        int     m_cursor;
103 7 dgisselq
        ZIPSTATE        m_state;
104 113 dgisselq
        bool    m_user_break, m_show_users_timers, m_show_cc;
105 5 dgisselq
public:
106 7 dgisselq
        ZIPPY(DEVBUS *fpga) : m_fpga(fpga), m_cursor(0), m_user_break(false),
107 113 dgisselq
                m_show_users_timers(false), m_show_cc(false) {}
108 5 dgisselq
 
109 7 dgisselq
        void    read_raw_state(void) {
110
                m_state.m_valid = false;
111
                for(int i=0; i<16; i++)
112
                        m_state.m_sR[i] = cmd_read(i);
113
                for(int i=0; i<16; i++)
114
                        m_state.m_uR[i] = cmd_read(i+16);
115
                for(int i=0; i<20; i++)
116
                        m_state.m_p[i]  = cmd_read(i+32);
117
 
118
                m_state.m_gie = (m_state.m_sR[14] & 0x020);
119
                m_state.m_pc  = (m_state.m_gie) ? (m_state.m_uR[15]):(m_state.m_sR[15]);
120
                m_state.m_sp  = (m_state.m_gie) ? (m_state.m_uR[13]):(m_state.m_sR[13]);
121
 
122
                if (m_state.m_last_pc_valid)
123
                        m_state.m_imem[0].m_a = m_state.m_last_pc;
124
                else
125
                        m_state.m_imem[0].m_a = m_state.m_pc - 1;
126
                try {
127
                        m_state.m_imem[0].m_d = readio(m_state.m_imem[0].m_a);
128
                        m_state.m_imem[0].m_valid = true;
129
                } catch(BUSERR be) {
130
                        m_state.m_imem[0].m_valid = false;
131
                }
132
                m_state.m_imem[1].m_a = m_state.m_pc;
133
                try {
134
                        m_state.m_imem[1].m_d = readio(m_state.m_imem[1].m_a);
135
                        m_state.m_imem[1].m_valid = true;
136
                } catch(BUSERR be) {
137
                        m_state.m_imem[1].m_valid = false;
138
                }
139
 
140
                for(int i=1; i<4; i++) {
141
                        if (!m_state.m_imem[i].m_valid) {
142
                                m_state.m_imem[i+1].m_valid = false;
143
                                m_state.m_imem[i+1].m_a = m_state.m_imem[i].m_a+1;
144
                                continue;
145
                        }
146
                        m_state.m_imem[i+1].m_a = zop_early_branch(
147
                                        m_state.m_imem[i].m_a,
148
                                        m_state.m_imem[i].m_d);
149
                        try {
150
                                m_state.m_imem[i+1].m_d = readio(m_state.m_imem[i+1].m_a);
151
                                m_state.m_imem[i+1].m_valid = true;
152
                        } catch(BUSERR be) {
153
                                m_state.m_imem[i+1].m_valid = false;
154
                        }
155
                }
156
 
157
                m_state.m_smem[0].m_a = m_state.m_sp;
158
                for(int i=1; i<5; i++)
159
                        m_state.m_smem[i].m_a = m_state.m_smem[i-1].m_a+1;
160
                for(int i=0; i<5; i++) {
161 76 dgisselq
                        m_state.m_smem[i].m_valid = true;
162
                        if (m_state.m_smem[i].m_a < 0x2000)
163
                                m_state.m_smem[i].m_valid = false;
164
                        else if (m_state.m_smem[i].m_a < 0x4000)
165 110 dgisselq
                                m_state.m_smem[i].m_valid = true;
166 76 dgisselq
                        else if (m_state.m_smem[i].m_a < 0x800000)
167
                                m_state.m_smem[i].m_valid = false;
168
                        else if (m_state.m_smem[i].m_a < 0x1000000)
169
                                m_state.m_smem[i].m_valid = true;
170
                        else
171
                                m_state.m_smem[i].m_valid = false;
172
                        if (m_state.m_smem[i].m_valid)
173 7 dgisselq
                        try {
174
                                m_state.m_smem[i].m_d = readio(m_state.m_smem[i].m_a);
175
                                m_state.m_smem[i].m_valid = true;
176
                        } catch(BUSERR be) {
177
                                m_state.m_smem[i].m_valid = false;
178
                        }
179
                }
180
                m_state.m_valid = true;
181
        }
182
 
183 5 dgisselq
        void    kill(void) { m_fpga->kill(); }
184
        void    close(void) { m_fpga->close(); }
185
        void    writeio(const BUSW a, const BUSW v) { m_fpga->writeio(a, v); }
186
        BUSW    readio(const BUSW a) { return m_fpga->readio(a); }
187
        void    readi(const BUSW a, const int len, BUSW *buf) {
188
                return m_fpga->readi(a, len, buf); }
189
        void    readz(const BUSW a, const int len, BUSW *buf) {
190
                return m_fpga->readz(a, len, buf); }
191
        void    writei(const BUSW a, const int len, const BUSW *buf) {
192
                return m_fpga->writei(a, len, buf); }
193
        void    writez(const BUSW a, const int len, const BUSW *buf) {
194
                return m_fpga->writez(a, len, buf); }
195
        bool    poll(void) { return m_fpga->poll(); }
196
        void    usleep(unsigned ms) { m_fpga->usleep(ms); }
197
        void    wait(void) { m_fpga->wait(); }
198
        bool    bus_err(void) const { return m_fpga->bus_err(); }
199
        void    reset_err(void) { m_fpga->reset_err(); }
200
        void    clear(void) { m_fpga->clear(); }
201
 
202
        void    reset(void) { writeio(R_ZIPCTRL, CPU_RESET|CPU_HALT); }
203 7 dgisselq
        void    step(void) { writeio(R_ZIPCTRL, CPU_STEP); m_state.step(); }
204 5 dgisselq
        void    go(void) { writeio(R_ZIPCTRL, CPU_GO); }
205
        void    halt(void) {    writeio(R_ZIPCTRL, CPU_HALT); }
206
        bool    stalled(void) { return ((readio(R_ZIPCTRL)&CPU_STALL)==0); }
207
 
208 7 dgisselq
        void    show_user_timers(bool v) {
209
                m_show_users_timers = v;
210
        }
211
 
212 113 dgisselq
        void    toggle_cc(void) {
213
                m_show_cc = !m_show_cc;
214
        }
215
 
216 5 dgisselq
        void    showval(int y, int x, const char *lbl, unsigned int v, bool c) {
217
                if (c)
218
                        mvprintw(y,x, ">%s> 0x%08x<", lbl, v);
219
                else
220
                        mvprintw(y,x, " %s: 0x%08x ", lbl, v);
221
        }
222
 
223
        void    dispreg(int y, int x, const char *n, unsigned int v, bool c) {
224
                // 4,4,8,1 = 17 of 20, +2 = 18
225
                if (c)
226
                        mvprintw(y, x, ">%s> 0x%08x<", n, v);
227
                else
228
                        mvprintw(y, x, " %s: 0x%08x ", n, v);
229
        }
230
 
231 7 dgisselq
        int     showins(int y, const char *lbl, const unsigned int pcidx) {
232
                char    la[80], lb[80];
233
                int     r = y-1;
234 5 dgisselq
 
235 7 dgisselq
                mvprintw(y, 0, "%s0x%08x", lbl, m_state.m_imem[pcidx].m_a);
236 5 dgisselq
 
237 7 dgisselq
                if (m_state.m_gie) attroff(A_BOLD);
238 5 dgisselq
                else    attron(A_BOLD);
239
 
240 7 dgisselq
                la[0] = '\0';
241
                lb[0] = '\0';
242
                if (m_state.m_imem[pcidx].m_valid) {
243
                        zipi_to_string(m_state.m_imem[pcidx].m_d, la, lb);
244
                        printw(" 0x%08x", m_state.m_imem[pcidx].m_d);
245
                        printw("  %-25s", la);
246
                        if (lb[0]) {
247
                                mvprintw(y-1, 0, "%s", lbl);
248
                                mvprintw(y-1, strlen(lbl)+10+3+8+2, "%-25s", lb);
249
                                r--;
250
                        }
251
                } else {
252
                        printw(" 0x--------  %-25s", "(Bus Error)");
253 5 dgisselq
                }
254
                attroff(A_BOLD);
255 7 dgisselq
 
256
                return r;
257 5 dgisselq
        }
258
 
259 7 dgisselq
        void    showstack(int y, const char *lbl, const unsigned int idx) {
260
                mvprintw(y, 27+26, "%s%08x ", lbl, m_state.m_smem[idx].m_a);
261
 
262
                if (m_state.m_gie) attroff(A_BOLD);
263
                else    attron(A_BOLD);
264
 
265
                if (m_state.m_smem[idx].m_valid)
266
                        printw("0x%08x", m_state.m_smem[idx].m_d);
267
                else
268
                        printw("(Bus Err)");
269
                attroff(A_BOLD);
270
        }
271
 
272 5 dgisselq
        unsigned int    cmd_read(unsigned int a) {
273 7 dgisselq
                int errcount = 0;
274
                unsigned int    s;
275 5 dgisselq
 
276
                writeio(R_ZIPCTRL, CMD_HALT|(a&0x3f));
277 7 dgisselq
                while((((s=readio(R_ZIPCTRL))&CPU_STALL)== 0)&&(errcount<MAXERR)
278
                                &&(!m_user_break))
279 5 dgisselq
                        errcount++;
280 7 dgisselq
                if (m_user_break) {
281
                        endwin();
282
                        exit(EXIT_SUCCESS);
283
                } else if (errcount >= MAXERR) {
284
                        endwin();
285
                        printf("ERR: errcount(%d) >= MAXERR on cmd_read(a=%2x)\n", errcount, a);
286
                        printf("ZIPCTRL = 0x%08x", s);
287
                        if ((s & 0x0200)==0) printf(" STALL");
288
                        if  (s & 0x0400) printf(" HALTED");
289
                        if ((s & 0x03000)==0x01000)
290
                                printf(" SW-HALT");
291
                        else {
292
                                if (s & 0x01000) printf(" SLEEPING");
293
                                if (s & 0x02000) printf(" GIE(UsrMode)");
294
                        } printf("\n");
295
                        exit(EXIT_FAILURE);
296 5 dgisselq
                }
297 7 dgisselq
                return readio(R_ZIPDATA);
298 5 dgisselq
        }
299
 
300
        void    cmd_write(unsigned int a, int v) {
301 7 dgisselq
                int errcount = 0;
302
                unsigned int    s;
303 5 dgisselq
 
304
                writeio(R_ZIPCTRL, CMD_HALT|(a&0x3f));
305 7 dgisselq
                while((((s=readio(R_ZIPCTRL))&CPU_STALL)== 0)&&(errcount<MAXERR)
306
                                &&(!m_user_break))
307 5 dgisselq
                        errcount++;
308 7 dgisselq
                if (m_user_break) {
309
                        endwin();
310
                        exit(EXIT_SUCCESS);
311
                } else if (errcount >= MAXERR) {
312
                        endwin();
313
                        printf("ERR: errcount(%d) >= MAXERR on cmd_read(a=%2x)\n", errcount, a);
314
                        printf("ZIPCTRL = 0x%08x", s);
315
                        if ((s & 0x0200)==0) printf(" STALL");
316
                        if  (s & 0x0400) printf(" HALTED");
317
                        if ((s & 0x03000)==0x01000)
318
                                printf(" SW-HALT");
319
                        else {
320
                                if (s & 0x01000) printf(" SLEEPING");
321
                                if (s & 0x02000) printf(" GIE(UsrMode)");
322
                        } printf("\n");
323
                        exit(EXIT_FAILURE);
324
                }
325
 
326
                writeio(R_ZIPDATA, (unsigned int)v);
327 5 dgisselq
        }
328
 
329
        void    read_state(void) {
330
                int     ln= 0;
331
                bool    gie;
332
 
333 7 dgisselq
                read_raw_state();
334
 
335 5 dgisselq
                if (m_cursor < 0)
336
                        m_cursor = 0;
337
                else if (m_cursor >= 44)
338
                        m_cursor = 43;
339
 
340
                mvprintw(ln,0, "Peripherals");
341 7 dgisselq
                mvprintw(ln,30,"%-50s", "CPU State: ");
342 5 dgisselq
                {
343
                        unsigned int v = readio(R_ZIPCTRL);
344 7 dgisselq
                        mvprintw(ln,41, "0x%08x ", v);
345
                        // if (v & 0x010000)
346
                                // printw("INT ");
347 5 dgisselq
                        if ((v & 0x003000) == 0x03000)
348 7 dgisselq
                                printw("Sleeping ");
349
                        else if (v & 0x001000)
350 5 dgisselq
                                printw("Halted ");
351
                        else if (v & 0x002000)
352 7 dgisselq
                                printw("User Mode ");
353
                        else
354
                                printw("Supervisor mode ");
355
                        if (v& 0x0200) {
356
                                v = m_state.m_sR[15];
357
 
358
                        } else printw("Stalled ");
359
                        // if (v & 0x008000)
360
                                // printw("Break-Enabled ");
361
                        // if (v & 0x000080)
362
                                // printw("PIC Enabled ");
363 5 dgisselq
                } ln++;
364 7 dgisselq
                showval(ln, 0, "PIC ", m_state.m_p[0], (m_cursor==0));
365
                showval(ln,20, "WDT ", m_state.m_p[1], (m_cursor==1));
366
                showval(ln,40, "WBUS", m_state.m_p[2], (m_cursor==2));
367
                showval(ln,60, "PIC2", m_state.m_p[3], (m_cursor==3));
368 5 dgisselq
                ln++;
369 7 dgisselq
                showval(ln, 0, "TMRA", m_state.m_p[4], (m_cursor==4));
370
                showval(ln,20, "TMRB", m_state.m_p[5], (m_cursor==5));
371
                showval(ln,40, "TMRC", m_state.m_p[6], (m_cursor==6));
372
                showval(ln,60, "JIF ", m_state.m_p[7], (m_cursor==7));
373 5 dgisselq
 
374
                ln++;
375 7 dgisselq
                if (!m_show_users_timers) {
376 92 dgisselq
                        showval(ln, 0, "MTSK", m_state.m_p[ 8], (m_cursor==8));
377
                        showval(ln,20, "MOST", m_state.m_p[ 9], (m_cursor==9));
378
                        showval(ln,40, "MPST", m_state.m_p[10], (m_cursor==10));
379
                        showval(ln,60, "MICT", m_state.m_p[11], (m_cursor==11));
380 7 dgisselq
                } else {
381 92 dgisselq
                        showval(ln, 0, "UTSK", m_state.m_p[12], (m_cursor==8));
382
                        showval(ln,20, "UMST", m_state.m_p[13], (m_cursor==9));
383
                        showval(ln,40, "UPST", m_state.m_p[14], (m_cursor==10));
384
                        showval(ln,60, "UICT", m_state.m_p[15], (m_cursor==11));
385 7 dgisselq
                }
386 5 dgisselq
 
387
                ln++;
388
                ln++;
389 7 dgisselq
                unsigned int cc = m_state.m_sR[14];
390 5 dgisselq
                gie = (cc & 0x020);
391
                if (gie)
392
                        attroff(A_BOLD);
393
                else
394
                        attron(A_BOLD);
395
                mvprintw(ln, 0, "Supervisor Registers");
396
                ln++;
397
 
398 7 dgisselq
                dispreg(ln, 0, "sR0 ", m_state.m_sR[0], (m_cursor==12));
399
                dispreg(ln,20, "sR1 ", m_state.m_sR[1], (m_cursor==13));
400
                dispreg(ln,40, "sR2 ", m_state.m_sR[2], (m_cursor==14));
401
                dispreg(ln,60, "sR3 ", m_state.m_sR[3], (m_cursor==15)); ln++;
402 5 dgisselq
 
403 7 dgisselq
                dispreg(ln, 0, "sR4 ", m_state.m_sR[4], (m_cursor==16));
404
                dispreg(ln,20, "sR5 ", m_state.m_sR[5], (m_cursor==17));
405
                dispreg(ln,40, "sR6 ", m_state.m_sR[6], (m_cursor==18));
406
                dispreg(ln,60, "sR7 ", m_state.m_sR[7], (m_cursor==19)); ln++;
407 5 dgisselq
 
408 7 dgisselq
                dispreg(ln, 0, "sR8 ", m_state.m_sR[ 8], (m_cursor==20));
409
                dispreg(ln,20, "sR9 ", m_state.m_sR[ 9], (m_cursor==21));
410
                dispreg(ln,40, "sR10", m_state.m_sR[10], (m_cursor==22));
411
                dispreg(ln,60, "sR11", m_state.m_sR[11], (m_cursor==23)); ln++;
412 5 dgisselq
 
413 7 dgisselq
                dispreg(ln, 0, "sR12", m_state.m_sR[12], (m_cursor==24));
414
                dispreg(ln,20, "sSP ", m_state.m_sR[13], (m_cursor==25));
415 5 dgisselq
 
416 113 dgisselq
                if (m_show_cc) {
417
                        mvprintw(ln,40, " sCC :%16s", "");
418
                        dispreg(ln, 40, "sCC ", m_state.m_sR[14], (m_cursor==26));
419
                } else {
420
                        mvprintw(ln,40, " sCC :%16s", "");
421
                        mvprintw(ln,40, "%ssCC :%s%s%s%s%s%s%s",
422
                                (m_cursor == 26)?">":" ",
423
                                (cc&0x1000)?"FE":"", // Floating point exception
424
                                (cc&0x0800)?"DV":"", // Division by zero
425
                                (cc&0x0400)?"BE":"", // Bus Error
426
                                (cc&0x0200)?"TP":"", // Trap
427
                                (cc&0x0100)?"IL":"", // Illegal instruction
428
                                (cc&0x0080)?"BK":"", // Break
429
                                ((gie==0)&&(cc&0x0010))?"HLT":""); // Halted
430
                        mvprintw(ln,54,"%s%s%s%s",
431
                                (cc&8)?"V":" ",
432
                                (cc&4)?"N":" ",
433
                                (cc&2)?"C":" ",
434
                                (cc&1)?"Z":" ");
435
                }
436 7 dgisselq
                dispreg(ln,60, "sPC ", m_state.m_sR[15], (m_cursor==27));
437 5 dgisselq
                ln++;
438
 
439
                if (gie)
440
                        attron(A_BOLD);
441
                else
442
                        attroff(A_BOLD);
443
                mvprintw(ln, 0, "User Registers"); ln++;
444 7 dgisselq
                dispreg(ln, 0, "uR0 ", m_state.m_uR[0], (m_cursor==28));
445
                dispreg(ln,20, "uR1 ", m_state.m_uR[1], (m_cursor==29));
446
                dispreg(ln,40, "uR2 ", m_state.m_uR[2], (m_cursor==30));
447
                dispreg(ln,60, "uR3 ", m_state.m_uR[3], (m_cursor==31)); ln++;
448 5 dgisselq
 
449 7 dgisselq
                dispreg(ln, 0, "uR4 ", m_state.m_uR[4], (m_cursor==32));
450
                dispreg(ln,20, "uR5 ", m_state.m_uR[5], (m_cursor==33));
451
                dispreg(ln,40, "uR6 ", m_state.m_uR[6], (m_cursor==34));
452
                dispreg(ln,60, "uR7 ", m_state.m_uR[7], (m_cursor==35)); ln++;
453 5 dgisselq
 
454 7 dgisselq
                dispreg(ln, 0, "uR8 ", m_state.m_uR[8], (m_cursor==36));
455
                dispreg(ln,20, "uR9 ", m_state.m_uR[9], (m_cursor==37));
456
                dispreg(ln,40, "uR10", m_state.m_uR[10], (m_cursor==38));
457
                dispreg(ln,60, "uR11", m_state.m_uR[11], (m_cursor==39)); ln++;
458 5 dgisselq
 
459 7 dgisselq
                dispreg(ln, 0, "uR12", m_state.m_uR[12], (m_cursor==40));
460
                dispreg(ln,20, "uSP ", m_state.m_uR[13], (m_cursor==41));
461
                cc = m_state.m_uR[14];
462 113 dgisselq
                if (m_show_cc) {
463
                        mvprintw(ln,40, " uCC :%16s", "");
464
                        dispreg(ln, 40, "uCC ", m_state.m_uR[14], (m_cursor==42));
465
                } else {
466
                        mvprintw(ln,40, " uCC :%16s", "");
467
                        mvprintw(ln,40, "%suCC :%s%s%s%s%s%s%s",
468
                                (m_cursor == 42)?">":" ",
469
                                (cc&0x1000)?"FE":"", // Floating point Exception
470
                                (cc&0x0800)?"DV":"", // Division by zero
471
                                (cc&0x0400)?"BE":"", // Bus Error
472
                                (cc&0x0200)?"TP":"", // Trap
473
                                (cc&0x0100)?"IL":"", // Illegal instruction
474
                                (cc&0x0040)?"ST":"", // Single-step
475
                                ((gie)&&(cc&0x0010))?"SL":""); // Sleep
476
                        mvprintw(ln,54,"%s%s%s%s",
477
                                (cc&8)?"V":" ",
478
                                (cc&4)?"N":" ",
479
                                (cc&2)?"C":" ",
480
                                (cc&1)?"Z":" ");
481
                }
482 7 dgisselq
                dispreg(ln,60, "uPC ", m_state.m_uR[15], (m_cursor==43));
483 5 dgisselq
 
484
                attroff(A_BOLD);
485 7 dgisselq
                ln+=3;
486 5 dgisselq
 
487 7 dgisselq
                showins(ln+4, " ", 0);
488
                {
489
                        int     lclln = ln+3;
490
                        for(int i=1; i<5; i++)
491
                                lclln = showins(lclln, (i==1)?">":" ", i);
492
                        for(int i=0; i<5; i++)
493
                                showstack(ln+i, (i==0)?">":" ", i);
494
                }
495 5 dgisselq
        }
496
 
497
        void    cursor_up(void) {
498
                if (m_cursor > 3)
499
                        m_cursor -= 4;
500
        } void  cursor_down(void) {
501
                if (m_cursor < 40)
502
                        m_cursor += 4;
503
        } void  cursor_left(void) {
504
                if (m_cursor > 0)
505
                        m_cursor--;
506
                else    m_cursor = 43;
507
        } void  cursor_right(void) {
508
                if (m_cursor < 43)
509
                        m_cursor++;
510
                else    m_cursor = 0;
511
        }
512
 
513
        int     cursor(void) { return m_cursor; }
514
};
515
 
516 7 dgisselq
const   int ZIPPY::MAXERR = 100000;
517
 
518 5 dgisselq
FPGA    *m_fpga;
519
 
520
void    get_value(ZIPPY *zip) {
521
        int     wy, wx, ra;
522
        int     c = zip->cursor();
523
 
524
        wx = (c & 0x03) * 20 + 9 + 1;
525
        wy = (c >> 2);
526
        if (wy >= 3+4)
527
                wy++;
528
        if (wy > 3)
529
                wy += 2;
530
        wy++;
531
 
532
        if (c >= 12)
533
                ra = c - 12;
534
        else
535
                ra = c + 32;
536
 
537
        bool    done = false;
538
        char    str[16];
539
        int     pos = 0; str[pos] = '\0';
540 7 dgisselq
        attron(A_NORMAL | A_UNDERLINE);
541
        mvprintw(wy, wx, "%-8s", "");
542 5 dgisselq
        while(!done) {
543
                int     chv = getch();
544
                switch(chv) {
545
                case KEY_ESCAPE:
546
                        pos = 0; str[pos] = '\0'; done = true;
547
                        break;
548
                case KEY_RETURN: case KEY_ENTER: case KEY_UP: case KEY_DOWN:
549
                        done = true;
550
                        break;
551
                case KEY_LEFT: case KEY_BACKSPACE:
552
                        if (pos > 0) pos--;
553
                        break;
554
                case KEY_CLEAR:
555
                        pos = 0;
556
                        break;
557
                case '0': case ' ': str[pos++] = '0'; break;
558
                case '1': str[pos++] = '1'; break;
559
                case '2': str[pos++] = '2'; break;
560
                case '3': str[pos++] = '3'; break;
561
                case '4': str[pos++] = '4'; break;
562
                case '5': str[pos++] = '5'; break;
563
                case '6': str[pos++] = '6'; break;
564
                case '7': str[pos++] = '7'; break;
565
                case '8': str[pos++] = '8'; break;
566
                case '9': str[pos++] = '9'; break;
567
                case 'A': case 'a': str[pos++] = 'A'; break;
568
                case 'B': case 'b': str[pos++] = 'B'; break;
569
                case 'C': case 'c': str[pos++] = 'C'; break;
570
                case 'D': case 'd': str[pos++] = 'D'; break;
571
                case 'E': case 'e': str[pos++] = 'E'; break;
572
                case 'F': case 'f': str[pos++] = 'F'; break;
573
                }
574
 
575
                if (pos > 8)
576
                        pos = 8;
577
                str[pos] = '\0';
578
 
579
                attron(A_NORMAL | A_UNDERLINE);
580
                mvprintw(wy, wx, "%-8s", str);
581
                if (pos > 0) {
582
                        attron(A_NORMAL | A_UNDERLINE | A_BLINK);
583
                        mvprintw(wy, wx+pos-1, "%c", str[pos-1]);
584
                }
585
                attrset(A_NORMAL);
586
        }
587
 
588
        if (pos > 0) {
589
                int     v;
590
                v = strtoul(str, NULL, 16);
591
                zip->cmd_write(ra, v);
592
        }
593
}
594
 
595
void    on_sigint(int v) {
596
        endwin();
597
 
598
        fprintf(stderr, "Interrupted!\n");
599
        exit(-2);
600
}
601
 
602 7 dgisselq
void    stall_screen(void) {
603
        erase();
604
        mvprintw(0,0, "CPU is stalled.  (Q to quit)\n");
605
}
606
 
607 5 dgisselq
int     main(int argc, char **argv) {
608
        // FPGAOPEN(m_fpga);
609
        ZIPPY   *zip; //
610
 
611
        int     skp=0, port = FPGAPORT;
612
        bool    use_usb = true;
613
 
614
        skp=1;
615
        for(int argn=0; argn<argc-skp; argn++) {
616
                if (argv[argn+skp][0] == '-') {
617
                        if (argv[argn+skp][1] == 'u')
618
                                use_usb = true;
619
                        else if (argv[argn+skp][1] == 'p') {
620
                                use_usb = false;
621
                                if (isdigit(argv[argn+skp][2]))
622
                                        port = atoi(&argv[argn+skp][2]);
623
                        }
624
                        skp++; argn--;
625
                } else
626
                        argv[argn] = argv[argn+skp];
627
        } argc -= skp;
628
 
629
        if (use_usb)
630
                m_fpga = new FPGA(new USBI());
631
        else
632
                m_fpga = new FPGA(new NETCOMMS(FPGAHOST, port));
633
        zip = new ZIPPY(m_fpga);
634
 
635
 
636
        initscr();
637
        raw();
638
        noecho();
639
        keypad(stdscr, true);
640
 
641
        signal(SIGINT, on_sigint);
642
 
643
        int     chv;
644
        bool    done = false;
645
 
646
        zip->halt();
647
        for(int i=0; (i<5)&&(zip->stalled()); i++)
648
                ;
649
        if (!zip->stalled())
650
                zip->read_state();
651 7 dgisselq
        else
652
                stall_screen();
653 5 dgisselq
        while((!done)&&(!gbl_err)) {
654
                chv = getch();
655
                switch(chv) {
656 113 dgisselq
                case 'c': case 'C':
657
                        zip->toggle_cc();
658
                        break;
659 5 dgisselq
                case 'g': case 'G':
660
                        m_fpga->writeio(R_ZIPCTRL, CPU_GO);
661
                        // We just released the CPU, so we're now done.
662
                        done = true;
663
                        break;
664
                case 'l': case 'L': case CTRL('L'):
665
                        redrawwin(stdscr);
666 7 dgisselq
                case 'm': case 'M':
667
                        zip->show_user_timers(false);
668 5 dgisselq
                        break;
669
                case 'q': case 'Q': case CTRL('C'):
670
                case KEY_CANCEL: case KEY_CLOSE: case KEY_EXIT:
671
                case KEY_ESCAPE:
672
                        done = true;
673
                        break;
674
                case 'r': case 'R':
675
                        zip->reset();
676
                        erase();
677
                        break;
678 7 dgisselq
                case 't': case 'T':
679 5 dgisselq
                case 's': case 'S':
680
                        zip->step();
681
                        break;
682 7 dgisselq
                case 'u': case 'U':
683
                        zip->show_user_timers(true);
684
                        break;
685
                case '\r': case  '\n':
686 5 dgisselq
                case KEY_IC: case KEY_ENTER:
687
                        get_value(zip);
688
                        break;
689
                case KEY_UP:
690
                        zip->cursor_up();
691
                        break;
692
                case KEY_DOWN:
693
                        zip->cursor_down();
694
                        break;
695
                case KEY_LEFT:
696
                        zip->cursor_left();
697
                        break;
698
                case KEY_RIGHT:
699
                        zip->cursor_right();
700
                        break;
701
                case ERR: case KEY_CLEAR:
702
                default:
703
                        ;
704
                }
705
 
706 7 dgisselq
                if ((done)||(gbl_err))
707
                        break;
708
                else if (zip->stalled())
709
                        stall_screen();
710
                else
711
                        zip->read_state();
712 5 dgisselq
        }
713
 
714
        endwin();
715
 
716
        if (gbl_err) {
717
                printf("Killed on error: could not access bus!\n");
718
                exit(-2);
719
        }
720
}
721
 

powered by: WebSVN 2.1.0

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