Annotation of previous/src/dimension/i860dbg.cpp, revision 1.1

1.1     ! root        1: /***************************************************************************
        !             2: 
        !             3:     i860dbg.cpp
        !             4: 
        !             5:     Debugger for the Intel i860 emulator.
        !             6: 
        !             7:     Copyright (C) 1995-present Jason Eckhardt ([email protected])
        !             8:     Released for general non-commercial use under the MAME license
        !             9:     with the additional requirement that you are free to use and
        !            10:     redistribute this code in modified or unmodified form, provided
        !            11:     you list me in the credits.
        !            12:     Visit http://mamedev.org for licensing and usage restrictions.
        !            13: 
        !            14:     Changes for previous/NeXTdimension by Simon Schubiger (SC)
        !            15:  
        !            16: ***************************************************************************/
        !            17: 
        !            18: extern int i860_disassembler(UINT32 pc, UINT32 insn, char* buffer);
        !            19: 
        !            20: /* A simple internal debugger.  */
        !            21: void i860_cpu_device::debugger() {
        !            22:     debugger(0, "");
        !            23: }
        !            24: 
        !            25: void i860_cpu_device::debugger(char cmd, const char* format, ...) {
        !            26:     if(!(isatty(fileno(stdin)))) return;
        !            27:     
        !            28:     char buf[256];
        !            29:     UINT32 curr_disasm = m_pc;
        !            30:     UINT32 curr_dumpdb = 0;
        !            31:     int c = 0;
        !            32:     
        !            33:     if(format)
        !            34:         m_single_stepping = 0;
        !            35:         
        !            36:     if (m_single_stepping > 1 && m_single_stepping != m_pc)
        !            37:         return;
        !            38:     
        !            39:     lock(&m_debugger_lock);
        !            40:     
        !            41:     if(format) {
        !            42:         va_list ap;
        !            43:         va_start (ap, format);
        !            44:         fprintf(stderr, "\n[i860]");
        !            45:         if(format[0]) {
        !            46:             fprintf(stderr, " (");
        !            47:             vfprintf (stderr, format, ap);
        !            48:         }
        !            49:         va_end (ap);
        !            50:         if(format[0])
        !            51:             fprintf(stderr, ")");
        !            52:         fprintf(stderr, " debugger started (? for help).\n");
        !            53:     }
        !            54:         
        !            55:     if(!(cmd))
        !            56:         disasm (m_pc, (m_dim ? 2 : 1) + delay_slots(ifetch_notrap(m_pc)));
        !            57: 
        !            58:     buf[0] = 0;
        !            59:     fflush (stdin);
        !            60:     
        !            61:     m_single_stepping = 0;
        !            62:     
        !            63:     while(!m_single_stepping) {
        !            64:         if(cmd) {
        !            65:             m_lastcmd = cmd;
        !            66:             buf[0]    = cmd;
        !            67:             buf[1]    = 0;
        !            68:             cmd       = 0;
        !            69:         } else {
        !            70:             fprintf (stderr, ">");
        !            71:             for(;;) {
        !            72:                 char it = 0;
        !            73:                 if (read(STDIN_FILENO, &it, 1) == 1) {
        !            74:                     if (it == '\n') {
        !            75:                         buf[c] = 0;
        !            76:                         c = 0;
        !            77:                         break;
        !            78:                     }
        !            79:                     buf[c++] = it;
        !            80:                 }
        !            81:             }
        !            82:             if(buf[0] == 0) {
        !            83:                 buf[0] = m_lastcmd;
        !            84:                 buf[1] = 0;
        !            85:             } else {
        !            86:                 m_lastcmd = buf[0];
        !            87:             }
        !            88:         }
        !            89:         switch(buf[0]) {
        !            90:             case 'g':
        !            91:                 if (buf[1] == '0')
        !            92:                     sscanf (buf + 1, "%x", &m_single_stepping);
        !            93:                 else {
        !            94:                     m_single_stepping = 2;
        !            95:                     break;
        !            96:                 }
        !            97:                 buf[1] = 0;
        !            98:                 fprintf (stderr, "go until pc = 0x%08x.\n", m_single_stepping);
        !            99:                 break;
        !           100:             case 'h':
        !           101:                 halt(true);
        !           102:                 m_single_stepping = 2;
        !           103:                 break;
        !           104:             case 'c':
        !           105:                 halt(false);
        !           106:                 m_single_stepping = 2;
        !           107:                 break;
        !           108:             case 'r':
        !           109:                 dump_state();
        !           110:                 break;
        !           111:             case 'd':
        !           112:                 if (buf[1] == '0')
        !           113:                     sscanf (buf + 1, "%x", &curr_disasm);
        !           114:                 curr_disasm = disasm (curr_disasm, 10);
        !           115:                 buf[1] = 0;
        !           116:                 break;
        !           117:             case 'p':
        !           118:                 if (buf[1] >= '0' && buf[1] <= '4')
        !           119:                     dump_pipe (buf[1] - 0x30);
        !           120:                 buf[1] = 0;
        !           121:                 break;
        !           122:             case 's':
        !           123:                 m_single_stepping = 1;
        !           124:                 break;
        !           125:             case 'w':
        !           126:                 nd_dbg_cmd(buf);
        !           127:                 break;
        !           128:             case 'k':
        !           129:                 m_console[m_console_idx] = 0;
        !           130:                 fputs(m_console, stderr);
        !           131:                 fflush(stderr);
        !           132:                 break;
        !           133:             case 'b':
        !           134:                 SET_PSR_IT (1);
        !           135:                 m_flow |= TRAP_NORMAL;
        !           136:                 m_single_stepping = 2;
        !           137:                 break;
        !           138:             case 'm':
        !           139:                 if (buf[1] == '0')
        !           140:                     sscanf (buf + 1, "%x", &curr_dumpdb);
        !           141:                 dbg_db (curr_dumpdb, 32);
        !           142:                 curr_dumpdb += 32;
        !           143:                 break;
        !           144:             case 't': {
        !           145:                 int bufsz = sizeof(m_traceback) / sizeof(m_traceback[0]);
        !           146:                 int count = bufsz;
        !           147:                 if(buf[1])
        !           148:                     sscanf(buf + 1, "%d", &count);
        !           149:                 if(count >= bufsz) count = bufsz;
        !           150:                 fprintf (stderr, "Traceback of last %d instructions:\n", count);
        !           151:                 int before       = m_traceback_idx;
        !           152:                 m_traceback_idx += bufsz;
        !           153:                 m_traceback_idx -= count;
        !           154:                 while(count--)
        !           155:                     disasm(m_traceback[m_traceback_idx++ % bufsz], 1);
        !           156:                 m_traceback_idx = before;
        !           157:                 break;}
        !           158:             case 'x':
        !           159:                 if(buf[1] == '0') {
        !           160:                     UINT32 v;
        !           161:                     sscanf (buf + 1, "%x", &v);
        !           162:                     if (GET_DIRBASE_ATE ())
        !           163:                         fprintf (stderr, "vma 0x%08x ==> phys 0x%08x\n", v, get_address_translation (v, 1, 0));
        !           164:                     else
        !           165:                         fprintf (stderr, "not in virtual address mode.\n");
        !           166:                     break;
        !           167:                 }
        !           168:             case '?':
        !           169:                 fprintf (stderr,
        !           170:                          "   m: dump bytes (m[0xaddress])\n"
        !           171:                          "   r: dump registers\n"
        !           172:                          "   s: single-step\n"
        !           173:                          "   h: halt i860\n"
        !           174:                          "   c: continue i860\n"
        !           175:                          "   g: go back to emulator (g[0xaddress])\n"
        !           176:                          "   k: print console buffer\n"
        !           177:                          "   d: disassemble (u[0xaddress])\n"
        !           178:                          "   p: dump pipelines (p{0-4} for all, add, mul, load, graphics)\n"
        !           179:                          "   b: break - set trap on next instruction\n"
        !           180:                          "   t: dump traceback buffer (t[count])\n"
        !           181:                          "   x: give virt->phys translation (x{0xaddress})\n");
        !           182:                 nd_dbg_cmd(0);
        !           183:                 break;
        !           184:             default:
        !           185:                 if(!(nd_dbg_cmd(buf)))
        !           186:                     fprintf (stderr, "Bad command '%s'. Type '?' for help.\n", buf);
        !           187:                 break;
        !           188:         }
        !           189:     }
        !           190:     
        !           191:     /* Less noise when single-stepping.  */
        !           192:     if(m_single_stepping != 1) {
        !           193:         fprintf (stderr, "Debugger done, continuing emulation.\n");
        !           194:         if(m_single_stepping == 2) m_single_stepping = 0;
        !           195:     }
        !           196:     
        !           197:     unlock(&m_debugger_lock);
        !           198: }
        !           199: 
        !           200: /* Disassemble `len' instructions starting at `addr'.  */
        !           201: UINT32 i860_cpu_device::disasm (UINT32 addr, int len)
        !           202: {
        !           203:        UINT32 insn;
        !           204:        int j;
        !           205:        for (j = 0; j < len; j++) {
        !           206:                char buf[256];
        !           207:                /* Note that we print the incoming (possibly virtual) address as the
        !           208:                   PC rather than the translated address.  */
        !           209:                fprintf (stderr, " [i860] %08X: ", addr);
        !           210:                insn = ifetch_notrap(addr);
        !           211:         i860_disassembler(addr, insn, buf);
        !           212:         fprintf (stderr, "%s\n", buf);
        !           213:                addr += 4;
        !           214:        }
        !           215:     return addr;
        !           216: }
        !           217: 
        !           218: 
        !           219: /* Dump `len' bytes starting at `addr'.  */
        !           220: void i860_cpu_device::dbg_db (UINT32 addr, int len)
        !           221: {
        !           222:        UINT8 b[16];
        !           223:        int i;
        !           224:        /* This will always dump a multiple of 16 bytes, even if 'len' isn't.  */
        !           225:        while (len > 0)
        !           226:        {
        !           227:                /* Note that we print the incoming (possibly virtual) address
        !           228:                   rather than the translated address.  */
        !           229:                fprintf (stderr, "0x%08x: ", addr);
        !           230:                for (i = 0; i < 16; i++)
        !           231:                {
        !           232:                        UINT32 phys_addr = addr;
        !           233:                        if (GET_DIRBASE_ATE ())
        !           234:                                phys_addr = get_address_translation (addr, 1  /* is_dataref */, 0 /* is_write */);
        !           235: 
        !           236:                        rdmem[1](phys_addr, (UINT32*)&b[i]);
        !           237:                        fprintf (stderr, "%02x ", b[i]);
        !           238:                        addr++;
        !           239:                }
        !           240:                fprintf (stderr, "| ");
        !           241:                for (i = 0; i < 16; i++)
        !           242:                {
        !           243:                        if (isprint (b[i]))
        !           244:                                fprintf (stderr, "%c", b[i]);
        !           245:                        else
        !           246:                                fprintf (stderr, ".");
        !           247:                }
        !           248:                fprintf (stderr, "\n");
        !           249:                len -= 16;
        !           250:        }
        !           251: }
        !           252: 
        !           253: /* Do a pipeline dump.
        !           254:  type: 0 (all), 1 (add), 2 (mul), 3 (load), 4 (graphics).  */
        !           255: void i860_cpu_device::dump_pipe (int type)
        !           256: {
        !           257:     int i = 0;
        !           258:     
        !           259:     fprintf (stderr, "pipeline state:\n");
        !           260:     /* Dump the adder pipeline, if requested.  */
        !           261:     if (type == 0 || type == 1)
        !           262:     {
        !           263:         fprintf (stderr, "  A: ");
        !           264:         for (i = 0; i < 3; i++)
        !           265:         {
        !           266:             if (m_A[i].stat.arp)
        !           267:                 fprintf (stderr, "[%dd] 0x%016llx ", i + 1,
        !           268:                          *(UINT64 *)(&m_A[i].val.d));
        !           269:             else
        !           270:                 fprintf (stderr, "[%ds] 0x%08x ", i + 1,
        !           271:                          *(UINT32 *)(&m_A[i].val.s));
        !           272:         }
        !           273:         fprintf (stderr, "\n");
        !           274:     }
        !           275:     
        !           276:     
        !           277:     /* Dump the multiplier pipeline, if requested.  */
        !           278:     if (type == 0 || type == 2)
        !           279:     {
        !           280:         fprintf (stderr, "  M: ");
        !           281:         for (i = 0; i < 3; i++)
        !           282:         {
        !           283:             if (m_M[i].stat.mrp)
        !           284:                 fprintf (stderr, "[%dd] 0x%016llx ", i + 1,
        !           285:                          *(UINT64 *)(&m_M[i].val.d));
        !           286:             else
        !           287:                 fprintf (stderr, "[%ds] 0x%08x ", i + 1,
        !           288:                          *(UINT32 *)(&m_M[i].val.s));
        !           289:         }
        !           290:         fprintf (stderr, "\n");
        !           291:     }
        !           292:     
        !           293:     /* Dump the load pipeline, if requested.  */
        !           294:     if (type == 0 || type == 3)
        !           295:     {
        !           296:         fprintf (stderr, "  L: ");
        !           297:         for (i = 0; i < 3; i++)
        !           298:         {
        !           299:             if (m_L[i].stat.lrp)
        !           300:                 fprintf (stderr, "[%dd] 0x%016llx ", i + 1,
        !           301:                          *(UINT64 *)(&m_L[i].val.d));
        !           302:             else
        !           303:                 fprintf (stderr, "[%ds] 0x%08x ", i + 1,
        !           304:                          *(UINT32 *)(&m_L[i].val.s));
        !           305:         }
        !           306:         fprintf (stderr, "\n");
        !           307:     }
        !           308:     
        !           309:     /* Dump the graphics pipeline, if requested.  */
        !           310:     if (type == 0 || type == 4)
        !           311:     {
        !           312:         fprintf (stderr, "  I: ");
        !           313:         if (m_G.stat.irp)
        !           314:             fprintf (stderr, "[1d] 0x%016llx\n",
        !           315:                      *(UINT64 *)(&m_G.val.d));
        !           316:         else
        !           317:             fprintf (stderr, "[1s] 0x%08x\n",
        !           318:                      *(UINT32 *)(&m_G.val.s));
        !           319:     }
        !           320: }
        !           321: 
        !           322: 
        !           323: /* Do a register/state dump.  */
        !           324: void i860_cpu_device::dump_state()
        !           325: {
        !           326:     int rn;
        !           327:     
        !           328:     /* GR's first, 4 per line.  */
        !           329:     for (rn = 0; rn < 32; rn++)
        !           330:     {
        !           331:         if ((rn % 4) == 0)
        !           332:             fprintf (stderr, "\n");
        !           333:         fprintf (stderr, "%%r%-3d: 0x%08x  ", rn, get_iregval (rn));
        !           334:     }
        !           335:     fprintf (stderr, "\n");
        !           336:     
        !           337:     /* FR's (as 32-bits), 4 per line.  */
        !           338:     for (rn = 0; rn < 32; rn++)
        !           339:     {
        !           340:         float ff = get_fregval_s (rn);
        !           341:         if ((rn % 4) == 0)
        !           342:             fprintf (stderr, "\n");
        !           343:         fprintf (stderr, "%%f%-3d: 0x%08x  ", rn, *(UINT32 *)&ff);
        !           344:     }
        !           345:     fprintf (stderr, "\n");
        !           346:     fprintf(stderr, "    psr: CC=%d LCC=%d SC=%d IM=%d U=%d IT=%d FT=%d IAT=%d DAT=%d IN=%d PS=%d PM=%08X\n",
        !           347:             GET_PSR_CC (), GET_PSR_LCC (), GET_PSR_SC (), GET_PSR_IM (), GET_PSR_U (),
        !           348:             GET_PSR_IT (), GET_PSR_FT (), GET_PSR_IAT (), GET_PSR_DAT (), GET_PSR_IN (), GET_PSR_PS(), GET_PSR_PM());
        !           349:     fprintf(stderr, "   epsr: INT=%d, OF=%d BE=%d WP=%d\n",       GET_EPSR_INT (), GET_EPSR_OF (), GET_EPSR_BE (), GET_EPSR_WP());
        !           350:     fprintf(stderr, "dirbase: CS8=%d ATE=%d 0x%08x",              GET_DIRBASE_CS8(), GET_DIRBASE_ATE(), m_cregs[CR_DIRBASE]);
        !           351:     fprintf(stderr, "    fir: 0x%08x fsr: 0x%08x pc:0x%08x\n", m_cregs[CR_FIR], m_cregs[CR_FSR], m_pc);
        !           352:     fprintf(stderr, "  merge: 0x%016llx\n", m_merge);
        !           353: }
        !           354: 
        !           355: void i860_cpu_device::halt(bool state) {
        !           356:     if(state) {
        !           357:         m_halt = true;
        !           358:         Log_Printf(LOG_WARN, "[i860] **** HALTED ****");
        !           359:         Statusbar_SetNdLed(0);
        !           360:     } else {
        !           361:         Log_Printf(LOG_WARN, "[i860] **** RESTARTED ****");
        !           362:         m_halt = false;
        !           363:         Statusbar_SetNdLed(1);
        !           364:     }
        !           365: }
        !           366: 
        !           367: void i860_cpu_device::dbg_check_wr(UINT32 addr, int size, UINT8* data) {
        !           368:     if(addr == 0xF83FE800 || addr == 0xF80FF800) {
        !           369:         switch(*((UINT32*)data)) {
        !           370:             case 0:
        !           371:             case 4: {
        !           372:                 // catch ND console writes
        !           373:                 UINT32 ptr   = addr + 4;
        !           374:                 int    count; readmem_emu(ptr, 4, (UINT8*)&count);
        !           375:                 int    col   = 0;
        !           376:                 ptr += 4;
        !           377:                 if(count < 1024) { // sanity check
        !           378:                     for(int i = 0; i < count; i++) {
        !           379:                         char ch; readmem_emu(ptr++, 1, (UINT8*)&ch);
        !           380:                         switch(ch) { // msg cleanup & tab expand for debugger console
        !           381:                             case '\r': continue;
        !           382:                             case '\t': while(col++ % 16) m_console[m_console_idx++] = ' '; continue;
        !           383:                             case '\n':
        !           384:                                 col = -1;
        !           385:                                 // fall-through
        !           386:                             default:
        !           387:                                 m_console[m_console_idx++] = ch;
        !           388:                                 col++;
        !           389:                                 break;
        !           390:                         }
        !           391:                     }
        !           392:                     m_console[m_console_idx] = 0;
        !           393:                     if(strstr(m_console, "NeXTdimension Trap:"))
        !           394:                         m_break_on_next_msg = true;
        !           395:                     if(*((UINT32*)data) == 4) {
        !           396:                         char exit_code; readmem_emu(addr + 8, 1, (UINT8*)&exit_code);
        !           397:                         debugger('k', "NeXTdimension exit(%d)", exit_code);
        !           398:                     }
        !           399:                 }
        !           400:                 break;
        !           401:             }
        !           402:             case 5:
        !           403:                 if(m_break_on_next_msg) {
        !           404:                     m_break_on_next_msg = false;
        !           405:                     debugger('k', "NeXTdimension Trap");
        !           406:                 }
        !           407:                 break;
        !           408:         }
        !           409:     }
        !           410: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.