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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zipdbg/] [zipdbg.cpp] - Blame information for rev 191

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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