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

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

unix.superglobalmegacorp.com

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