Annotation of previous/src/dimension/i860dbg.cpp, revision 1.1.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.