URL
https://opencores.org/ocsvn/xulalx25soc/xulalx25soc/trunk
Subversion Repositories xulalx25soc
[/] [xulalx25soc/] [trunk/] [sw/] [zipdbg.cpp] - Rev 5
Go to most recent revision | Compare with Previous | Blame | View Log
/////////////////////////////////////////////////////////////////////////////// // // Filename: zipdbg.cpp // // Project: Zip CPU -- a small, lightweight, RISC CPU soft core // // Purpose: // // // Creator: Dan Gisselquist, Ph.D. // Gisselquist Tecnology, LLC // /////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2015, Gisselquist Technology, LLC // // This program is free software (firmware): you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation, either version 3 of the License, or (at // your option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // License: GPL, v3, as defined and found on www.gnu.org, // http://www.gnu.org/licenses/gpl.html // // /////////////////////////////////////////////////////////////////////////////// // // #include <stdlib.h> #include <signal.h> #include <time.h> #include <unistd.h> #include <ctype.h> #include <ncurses.h> #include "zopcodes.h" #include "zparser.h" #include "devbus.h" #include "regdefs.h" #include "usbi.h" #include "port.h" #define CMD_REG 0 #define CMD_DATA 1 #define CMD_HALT (1<<10) #define CMD_STALL (1<<9) #define CMD_STEP (1<<8) #define CMD_INT (1<<7) #define CMD_RESET (1<<6) #define KEY_ESCAPE 27 #define KEY_RETURN 10 #define CTRL(X) ((X)&0x01f) #define MAXERR 1000 // 1k cycles bool gbl_err = false; // No particular "parameters" need definition or redefinition here. class ZIPPY : public DEVBUS { typedef DEVBUS::BUSW BUSW; DEVBUS *m_fpga; int m_cursor; public: ZIPPY(DEVBUS *fpga) : m_fpga(fpga), m_cursor(0) {} void kill(void) { m_fpga->kill(); } void close(void) { m_fpga->close(); } void writeio(const BUSW a, const BUSW v) { m_fpga->writeio(a, v); } BUSW readio(const BUSW a) { return m_fpga->readio(a); } void readi(const BUSW a, const int len, BUSW *buf) { return m_fpga->readi(a, len, buf); } void readz(const BUSW a, const int len, BUSW *buf) { return m_fpga->readz(a, len, buf); } void writei(const BUSW a, const int len, const BUSW *buf) { return m_fpga->writei(a, len, buf); } void writez(const BUSW a, const int len, const BUSW *buf) { return m_fpga->writez(a, len, buf); } bool poll(void) { return m_fpga->poll(); } void usleep(unsigned ms) { m_fpga->usleep(ms); } void wait(void) { m_fpga->wait(); } bool bus_err(void) const { return m_fpga->bus_err(); } void reset_err(void) { m_fpga->reset_err(); } void clear(void) { m_fpga->clear(); } void reset(void) { writeio(R_ZIPCTRL, CPU_RESET|CPU_HALT); } void step(void) { writeio(R_ZIPCTRL, CPU_STEP); } void go(void) { writeio(R_ZIPCTRL, CPU_GO); } void halt(void) { writeio(R_ZIPCTRL, CPU_HALT); } bool stalled(void) { return ((readio(R_ZIPCTRL)&CPU_STALL)==0); } void showval(int y, int x, const char *lbl, unsigned int v, bool c) { if (c) mvprintw(y,x, ">%s> 0x%08x<", lbl, v); else mvprintw(y,x, " %s: 0x%08x ", lbl, v); } void dispreg(int y, int x, const char *n, unsigned int v, bool c) { // 4,4,8,1 = 17 of 20, +2 = 18 if (c) mvprintw(y, x, ">%s> 0x%08x<", n, v); else mvprintw(y, x, " %s: 0x%08x ", n, v); } void showins(int y, const char *lbl, const int gie, const unsigned int pc) { char line[80]; unsigned int v; mvprintw(y, 0, "%s: 0x%08x", lbl, pc); if (gie) attroff(A_BOLD); else attron(A_BOLD); line[0] = '\0'; try { v= readio(pc); zipi_to_string(v, line); printw(" 0x%08x", v); printw(" %-24s", &line[1]); } catch(BUSERR b) { printw(" 0x%08x %-24s", b.addr, "(Bus Error)"); } attroff(A_BOLD); } unsigned int cmd_read(unsigned int a) { int errcount = 0; if (gbl_err) return 0; writeio(R_ZIPCTRL, CMD_HALT|(a&0x3f)); while(((readio(R_ZIPCTRL) & CPU_STALL) == 0)&&(errcount < MAXERR)) errcount++; if (errcount < MAXERR) return readio(R_ZIPDATA); else { gbl_err = true; return 0; } } void cmd_write(unsigned int a, int v) { if (gbl_err) return; int errcount = 0; writeio(R_ZIPCTRL, CMD_HALT|(a&0x3f)); while(((readio(R_ZIPCTRL) & CPU_STALL) == 0)&&(errcount < MAXERR)) errcount++; if (errcount < MAXERR) writeio(R_ZIPDATA, (unsigned int)v); else gbl_err = true; } void read_state(void) { int ln= 0; bool gie; if (m_cursor < 0) m_cursor = 0; else if (m_cursor >= 44) m_cursor = 43; mvprintw(ln,0, "Peripherals"); mvprintw(ln,40,"%-40s", "CPU State: "); { unsigned int v = readio(R_ZIPCTRL); mvprintw(ln,51, ""); if (v & 0x010000) printw("EXT-INT "); if ((v & 0x003000) == 0x03000) printw("Halted "); else if (v & 0x001000) printw("Sleeping "); else if (v & 0x002000) printw("Supervisor Mod "); if (v & 0x008000) printw("Break-Enabled "); if (v & 0x000080) printw("PIC Enabled "); } ln++; showval(ln, 0, "PIC ", cmd_read(32+ 0), (m_cursor==0)); showval(ln,20, "WDT ", cmd_read(32+ 1), (m_cursor==1)); showval(ln,40, "WBUS", cmd_read(32+ 2), (m_cursor==2)); showval(ln,60, "PIC2", cmd_read(32+ 3), (m_cursor==3)); ln++; showval(ln, 0, "TMRA", cmd_read(32+ 4), (m_cursor==4)); showval(ln,20, "TMRB", cmd_read(32+ 5), (m_cursor==5)); showval(ln,40, "TMRC", cmd_read(32+ 6), (m_cursor==6)); showval(ln,60, "JIF ", cmd_read(32+ 7), (m_cursor==7)); ln++; showval(ln, 0, "UTSK", cmd_read(32+12), (m_cursor==8)); showval(ln,20, "UMST", cmd_read(32+13), (m_cursor==9)); showval(ln,40, "UPST", cmd_read(32+14), (m_cursor==10)); showval(ln,60, "UICT", cmd_read(32+15), (m_cursor==11)); ln++; ln++; unsigned int cc = cmd_read(14); gie = (cc & 0x020); if (gie) attroff(A_BOLD); else attron(A_BOLD); mvprintw(ln, 0, "Supervisor Registers"); ln++; dispreg(ln, 0, "sR0 ", cmd_read(0), (m_cursor==12)); dispreg(ln,20, "sR1 ", cmd_read(1), (m_cursor==13)); dispreg(ln,40, "sR2 ", cmd_read(2), (m_cursor==14)); dispreg(ln,60, "sR3 ", cmd_read(3), (m_cursor==15)); ln++; dispreg(ln, 0, "sR4 ", cmd_read(4), (m_cursor==16)); dispreg(ln,20, "sR5 ", cmd_read(5), (m_cursor==17)); dispreg(ln,40, "sR6 ", cmd_read(6), (m_cursor==18)); dispreg(ln,60, "sR7 ", cmd_read(7), (m_cursor==19)); ln++; dispreg(ln, 0, "sR8 ", cmd_read( 8), (m_cursor==20)); dispreg(ln,20, "sR9 ", cmd_read( 9), (m_cursor==21)); dispreg(ln,40, "sR10", cmd_read(10), (m_cursor==22)); dispreg(ln,60, "sR11", cmd_read(11), (m_cursor==23)); ln++; dispreg(ln, 0, "sR12", cmd_read(12), (m_cursor==24)); dispreg(ln,20, "sSP ", cmd_read(13), (m_cursor==25)); mvprintw(ln,40, "%csCC :%s%s%s%s%s%s%s%s", (m_cursor==26)?'>':' ', (cc & 0x100)?"TP":" ", (cc & 0x040)?"ST":" ", (cc & 0x020)?"IE":" ", (cc & 0x010)?"SL":" ", (cc&8)?"V":" ", (cc&4)?"N":" ", (cc&2)?"C":" ", (cc&1)?"Z":" "); dispreg(ln,60, "sPC ", cmd_read(15), (m_cursor==27)); ln++; if (gie) attron(A_BOLD); else attroff(A_BOLD); mvprintw(ln, 0, "User Registers"); ln++; dispreg(ln, 0, "uR0 ", cmd_read(16), (m_cursor==28)); dispreg(ln,20, "uR1 ", cmd_read(17), (m_cursor==29)); dispreg(ln,40, "uR2 ", cmd_read(18), (m_cursor==30)); dispreg(ln,60, "uR3 ", cmd_read(19), (m_cursor==31)); ln++; dispreg(ln, 0, "uR4 ", cmd_read(20), (m_cursor==32)); dispreg(ln,20, "uR5 ", cmd_read(21), (m_cursor==33)); dispreg(ln,40, "uR6 ", cmd_read(22), (m_cursor==34)); dispreg(ln,60, "uR7 ", cmd_read(23), (m_cursor==35)); ln++; dispreg(ln, 0, "uR8 ", cmd_read(24), (m_cursor==36)); dispreg(ln,20, "uR9 ", cmd_read(25), (m_cursor==37)); dispreg(ln,40, "uR10", cmd_read(26), (m_cursor==38)); dispreg(ln,60, "uR11", cmd_read(27), (m_cursor==39)); ln++; dispreg(ln, 0, "uR12", cmd_read(28), (m_cursor==40)); dispreg(ln,20, "uSP ", cmd_read(29), (m_cursor==41)); cc = cmd_read(30); mvprintw(ln,40, "%cuCC :%s%s%s%s%s%s%s%s", (m_cursor == 42)?'>':' ', (cc&0x100)?"TP":" ", (cc&0x040)?"ST":" ", (cc&0x020)?"IE":" ", (cc&0x010)?"SL":" ", (cc&8)?"V":" ", (cc&4)?"N":" ", (cc&2)?"C":" ", (cc&1)?"Z":" "); dispreg(ln,60, "uPC ", cmd_read(31), (m_cursor==43)); attroff(A_BOLD); ln+=2; ln+=3; BUSW pc = cmd_read((gie)?31:15); showins(ln, "I ", gie, pc+2); ln++; showins(ln, "Dc", gie, pc+1); ln++; showins(ln, "Op", gie, pc ); ln++; showins(ln, "Al", gie, pc-1); ln++; } void cursor_up(void) { if (m_cursor > 3) m_cursor -= 4; } void cursor_down(void) { if (m_cursor < 40) m_cursor += 4; } void cursor_left(void) { if (m_cursor > 0) m_cursor--; else m_cursor = 43; } void cursor_right(void) { if (m_cursor < 43) m_cursor++; else m_cursor = 0; } int cursor(void) { return m_cursor; } }; FPGA *m_fpga; void get_value(ZIPPY *zip) { int wy, wx, ra; int c = zip->cursor(); wx = (c & 0x03) * 20 + 9 + 1; wy = (c >> 2); if (wy >= 3+4) wy++; if (wy > 3) wy += 2; wy++; if (c >= 12) ra = c - 12; else ra = c + 32; bool done = false; char str[16]; int pos = 0; str[pos] = '\0'; while(!done) { int chv = getch(); switch(chv) { case KEY_ESCAPE: pos = 0; str[pos] = '\0'; done = true; break; case KEY_RETURN: case KEY_ENTER: case KEY_UP: case KEY_DOWN: done = true; break; case KEY_LEFT: case KEY_BACKSPACE: if (pos > 0) pos--; break; case KEY_CLEAR: pos = 0; break; case '0': case ' ': str[pos++] = '0'; break; case '1': str[pos++] = '1'; break; case '2': str[pos++] = '2'; break; case '3': str[pos++] = '3'; break; case '4': str[pos++] = '4'; break; case '5': str[pos++] = '5'; break; case '6': str[pos++] = '6'; break; case '7': str[pos++] = '7'; break; case '8': str[pos++] = '8'; break; case '9': str[pos++] = '9'; break; case 'A': case 'a': str[pos++] = 'A'; break; case 'B': case 'b': str[pos++] = 'B'; break; case 'C': case 'c': str[pos++] = 'C'; break; case 'D': case 'd': str[pos++] = 'D'; break; case 'E': case 'e': str[pos++] = 'E'; break; case 'F': case 'f': str[pos++] = 'F'; break; } if (pos > 8) pos = 8; str[pos] = '\0'; attron(A_NORMAL | A_UNDERLINE); mvprintw(wy, wx, "%-8s", str); if (pos > 0) { attron(A_NORMAL | A_UNDERLINE | A_BLINK); mvprintw(wy, wx+pos-1, "%c", str[pos-1]); } attrset(A_NORMAL); } if (pos > 0) { int v; v = strtoul(str, NULL, 16); zip->cmd_write(ra, v); } } void on_sigint(int v) { endwin(); fprintf(stderr, "Interrupted!\n"); exit(-2); } int main(int argc, char **argv) { // FPGAOPEN(m_fpga); ZIPPY *zip; // int skp=0, port = FPGAPORT; bool use_usb = true; skp=1; for(int argn=0; argn<argc-skp; argn++) { if (argv[argn+skp][0] == '-') { if (argv[argn+skp][1] == 'u') use_usb = true; else if (argv[argn+skp][1] == 'p') { use_usb = false; if (isdigit(argv[argn+skp][2])) port = atoi(&argv[argn+skp][2]); } skp++; argn--; } else argv[argn] = argv[argn+skp]; } argc -= skp; if (use_usb) m_fpga = new FPGA(new USBI()); else m_fpga = new FPGA(new NETCOMMS(FPGAHOST, port)); zip = new ZIPPY(m_fpga); initscr(); raw(); noecho(); keypad(stdscr, true); signal(SIGINT, on_sigint); int chv; bool done = false; zip->halt(); for(int i=0; (i<5)&&(zip->stalled()); i++) ; if (!zip->stalled()) zip->read_state(); while((!done)&&(!gbl_err)) { chv = getch(); switch(chv) { case 'g': case 'G': m_fpga->writeio(R_ZIPCTRL, CPU_GO); // We just released the CPU, so we're now done. done = true; break; case 'l': case 'L': case CTRL('L'): redrawwin(stdscr); break; case 'q': case 'Q': case CTRL('C'): case KEY_CANCEL: case KEY_CLOSE: case KEY_EXIT: case KEY_ESCAPE: done = true; break; case 'r': case 'R': zip->reset(); erase(); break; case 's': case 'S': zip->step(); zip->read_state(); break; case KEY_IC: case KEY_ENTER: get_value(zip); break; case KEY_UP: zip->cursor_up(); break; case KEY_DOWN: zip->cursor_down(); break; case KEY_LEFT: zip->cursor_left(); break; case KEY_RIGHT: zip->cursor_right(); break; case ERR: case KEY_CLEAR: default: ; } if ((!done)&&(!gbl_err)) { if (zip->stalled()) erase(); } } endwin(); if (gbl_err) { printf("Killed on error: could not access bus!\n"); exit(-2); } }
Go to most recent revision | Compare with Previous | Blame | View Log