Annotation of previous/src/debug/debugInfo.c, revision 1.1.1.3

1.1       root        1: /*
                      2:   Hatari - debuginfo.c
                      3: 
                      4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
                      6: 
                      7:   debuginfo.c - functions needed to show info about the atari HW & OS
                      8:    components and "lock" that info to be shown on entering the debugger.
                      9: */
                     10: const char DebugInfo_fileid[] = "Hatari debuginfo.c : " __DATE__ " " __TIME__;
                     11: 
                     12: #include <stdio.h>
                     13: #include <assert.h>
1.1.1.3 ! root       14: #include <ctype.h>
1.1       root       15: #include "main.h"
                     16: #include "configuration.h"
                     17: #include "debugInfo.h"
                     18: #include "debugcpu.h"
                     19: #include "debugui.h"
                     20: #include "evaluate.h"
1.1.1.2   root       21: #include "file.h"
1.1       root       22: #include "ioMem.h"
                     23: #include "m68000.h"
                     24: #include "nextMemory.h"
1.1.1.2   root       25: #include "screen.h"
1.1       root       26: #include "video.h"
                     27: 
                     28: /* ------------------------------------------------------------------
                     29:  * Next HW information
                     30:  */
                     31: 
1.1.1.3 ! root       32: char* get_rtc_ram_info(void);
        !            33: 
1.1       root       34: /**
                     35:  * DebugInfo_Rtc : display the Videl registers values.
                     36:  */
1.1.1.3 ! root       37: static void DebugInfo_Rtc(Uint32 dummy) {
        !            38:     Update_StatusBar();
1.1       root       39:        fprintf(stdout,"%s",get_rtc_ram_info());
                     40: }
                     41: 
                     42: /* ------------------------------------------------------------------
                     43:  * CPU and DSP information wrappers
                     44:  */
                     45: 
                     46: /**
                     47:  * Helper to call debugcpu.c and debugdsp.c debugger commands
                     48:  */
                     49: static void DebugInfo_CallCommand(int (*func)(int, char* []), const char *command, Uint32 arg)
                     50: {
                     51:        char cmdbuffer[16], argbuffer[12];
                     52:        char *argv[] = { cmdbuffer, NULL };
                     53:        int argc = 1;
                     54: 
                     55:        assert(strlen(command) < sizeof(cmdbuffer));
                     56:        strcpy(cmdbuffer, command);
                     57:        if (arg) {
                     58:                sprintf(argbuffer, "$%x", arg);
                     59:                argv[argc++] = argbuffer;
                     60:        }
                     61:        func(argc, argv);
                     62: }
                     63: 
                     64: static void DebugInfo_CpuRegister(Uint32 arg)
                     65: {
                     66:        DebugInfo_CallCommand(DebugCpu_Register, "register", arg);
                     67: }
                     68: static void DebugInfo_CpuDisAsm(Uint32 arg)
                     69: {
                     70:        DebugInfo_CallCommand(DebugCpu_DisAsm, "disasm", arg);
                     71: }
                     72: static void DebugInfo_CpuMemDump(Uint32 arg)
                     73: {
                     74:        DebugInfo_CallCommand(DebugCpu_MemDump, "memdump", arg);
                     75: }
                     76: 
                     77: #if ENABLE_DSP_EMU
                     78: 
                     79: static void DebugInfo_DspRegister(Uint32 arg)
                     80: {
                     81: }
                     82: static void DebugInfo_DspDisAsm(Uint32 arg)
                     83: {
                     84: }
                     85: 
                     86: static void DebugInfo_DspMemDump(Uint32 arg)
                     87: {
                     88: }
                     89: 
                     90: /**
                     91:  * Convert arguments to Uint32 arg suitable for DSP memdump callback
                     92:  */
                     93: static Uint32 DebugInfo_DspMemArgs(int argc, char *argv[])
                     94: {
                     95:        Uint32 value;
                     96:        char space;
                     97:        if (argc != 2) {
                     98:                return 0;
                     99:        }
                    100:        space = toupper(argv[0][0]);
                    101:        if ((space != 'X' && space != 'Y' && space != 'P') || argv[0][1]) {
                    102:                fprintf(stderr, "ERROR: invalid DSP address space '%s'!\n", argv[0]);
                    103:                return 0;
                    104:        }
                    105:        if (!Eval_Number(argv[1], &value) || value > 0xffff) {
                    106:                fprintf(stderr, "ERROR: invalid DSP address '%s'!\n", argv[1]);
                    107:                return 0;
                    108:        }
                    109:        return ((Uint32)space<<16) | value;
                    110: }
                    111: 
                    112: #endif  /* ENABLE_DSP_EMU */
                    113: 
                    114: 
                    115: static void DebugInfo_RegAddr(Uint32 arg)
                    116: {
                    117: }
                    118: 
                    119: /**
                    120:  * Convert arguments to Uint32 arg suitable for RegAddr callback
                    121:  */
                    122: static Uint32 DebugInfo_RegAddrArgs(int argc, char *argv[])
                    123: {
                    124:        Uint32 value, *regaddr;
                    125:        if (argc != 2) {
                    126:                return 0;
                    127:        }
                    128: 
                    129:        if (strcmp(argv[0], "disasm") == 0) {
                    130:                value = 'D';
                    131:        } else if (strcmp(argv[0], "memdump") == 0) {
                    132:                value = 'M';
                    133:        } else {
                    134:                fprintf(stderr, "ERROR: regaddr operation can be only 'disasm' or 'memdump', not '%s'!\n", argv[0]);
                    135:                return 0;
                    136:        }
                    137: 
                    138:        if (strlen(argv[1]) != 2 ||
                    139:            (!DebugCpu_GetRegisterAddress(argv[1], &regaddr) &&
                    140:             (toupper(argv[1][0]) != 'R' || !isdigit(argv[1][1]) || argv[1][2]))) {
                    141:                /* not CPU register or Rx DSP register */
                    142:                fprintf(stderr, "ERROR: invalid address/data register '%s'!\n", argv[1]);
                    143:                return 0;
                    144:        }
                    145:        
                    146:        value |= argv[1][0] << 24;
                    147:        value |= argv[1][1] << 16;
                    148:        value &= 0xffff00ff;
                    149:        return value;
                    150: }
                    151: 
                    152: 
                    153: /* ------------------------------------------------------------------
1.1.1.2   root      154:  * wrappers for command to parse debugger input file
                    155:  */
                    156: 
                    157: /* file name to be given before calling the Parse function,
                    158:  * needs to be set separately as it's a host pointer which
                    159:  * can be 64-bit i.e. may not fit into Uint32.
                    160:  */
                    161: static char *parse_filename;
                    162: 
                    163: /**
                    164:  * Parse and exec commands in the previously given debugger input file
                    165:  */
                    166: static void DebugInfo_FileParse(Uint32 dummy)
                    167: {
                    168:     if (parse_filename) {
                    169:         DebugUI_ParseFile(parse_filename);
                    170:     } else {
1.1.1.3 ! root      171:        // fputs("ERROR: debugger input file name to parse isn't set!\n", stderr);
1.1.1.2   root      172:     }
                    173: }
                    174: 
                    175: /**
                    176:  * Set which input file to parse.
                    177:  * Return true if file exists, false on error
                    178:  */
                    179: static Uint32 DebugInfo_FileArgs(int argc, char *argv[])
                    180: {
                    181:     if (argc != 1) {
                    182:         return false;
                    183:     }
                    184:     if (!File_Exists(argv[0])) {
                    185:         fprintf(stderr, "ERROR: given file '%s' doesn't exist!\n", argv[0]);
                    186:         return false;
                    187:     }
                    188:     if (parse_filename) {
                    189:         free(parse_filename);
                    190:     }
                    191:     parse_filename = strdup(argv[0]);
                    192:     return true;
                    193: }
                    194: 
                    195: /* ------------------------------------------------------------------
1.1       root      196:  * Debugger & readline TAB completion integration
                    197:  */
                    198: 
                    199: /**
                    200:  * Default information on entering the debugger
                    201:  */
                    202: static void DebugInfo_Default(Uint32 dummy)
                    203: {
1.1.1.3 ! root      204:        fprintf(stderr, "\nCPU=$%x, DSP=",
        !           205:                M68000_GetPC());
1.1       root      206:                fprintf(stderr, "N/A\n");
                    207: }
                    208: 
                    209: static const struct {
1.1.1.2   root      210:        /* if overlaps with other functionality, list only for lock command */
1.1       root      211:        bool lock;
                    212:        const char *name;
                    213:        void (*func)(Uint32 arg);
                    214:        /* convert args in argv into single Uint32 for func */
                    215:        Uint32 (*args)(int argc, char *argv[]);
                    216:        const char *info;
                    217: } infotable[] = {
                    218:        { true, "default",   DebugInfo_Default,    NULL, "Show default debugger entry information" },
                    219:        { true, "disasm",    DebugInfo_CpuDisAsm,  NULL, "Disasm CPU from PC or given <address>" },
                    220: #if ENABLE_DSP_EMU
                    221:        { true, "dspdisasm", DebugInfo_DspDisAsm,  NULL, "Disasm DSP from given <address>" },
                    222:        { true, "dspmemdump",DebugInfo_DspMemDump, DebugInfo_DspMemArgs, "Dump DSP memory from given <space> <address>" },
1.1.1.2   root      223:        { true, "dspregs",   DebugInfo_DspRegister,NULL, "Show DSP registers values" },
1.1       root      224: #endif
1.1.1.2   root      225:     { true, "file",      DebugInfo_FileParse, DebugInfo_FileArgs, "Parse commands from given debugger input <file>" },
1.1       root      226:        { true, "memdump",   DebugInfo_CpuMemDump, NULL, "Dump CPU memory from given <address>" },
                    227:        { true, "regaddr",   DebugInfo_RegAddr, DebugInfo_RegAddrArgs, "Show <disasm|memdump> from CPU/DSP address pointed by <register>" },
1.1.1.2   root      228:        { true, "registers", DebugInfo_CpuRegister,NULL, "Show CPU registers values" },
1.1       root      229:        { false,"rtc",     DebugInfo_Rtc,      NULL, "Show Next's RTC registers" }
                    230: };
                    231: 
1.1.1.2   root      232: static int LockedFunction = 4; /* index for the "default" function */
1.1       root      233: static Uint32 LockedArgument;
                    234: 
                    235: /**
                    236:  * Show selected debugger session information
                    237:  * (when debugger is (again) entered)
                    238:  */
                    239: void DebugInfo_ShowSessionInfo(void)
                    240: {
                    241:        infotable[LockedFunction].func(LockedArgument);
                    242: }
                    243: 
                    244: 
                    245: /**
                    246:  * Readline match callback for info subcommand name completion.
                    247:  * STATE = 0 -> different text from previous one.
                    248:  * Return next match or NULL if no matches.
                    249:  */
                    250: static char *DebugInfo_Match(const char *text, int state, bool lock)
                    251: {
                    252:        static int i, len;
                    253:        const char *name;
                    254:        
                    255:        if (!state) {
                    256:                /* first match */
                    257:                len = strlen(text);
                    258:                i = 0;
                    259:        }
                    260:        /* next match */
                    261:        while (i++ < ARRAYSIZE(infotable)) {
                    262:                if (!lock && infotable[i-1].lock) {
                    263:                        continue;
                    264:                }
                    265:                name = infotable[i-1].name;
                    266:                if (strncmp(name, text, len) == 0)
                    267:                        return (strdup(name));
                    268:        }
                    269:        return NULL;
                    270: }
                    271: char *DebugInfo_MatchLock(const char *text, int state)
                    272: {
                    273:        return DebugInfo_Match(text, state, true);
                    274: }
                    275: char *DebugInfo_MatchInfo(const char *text, int state)
                    276: {
                    277:        return DebugInfo_Match(text, state, false);
                    278: }
                    279: 
                    280: 
                    281: /**
                    282:  * Show requested command information.
                    283:  */
                    284: int DebugInfo_Command(int nArgc, char *psArgs[])
                    285: {
                    286:        Uint32 value;
                    287:        const char *cmd;
                    288:        bool ok, lock;
                    289:        int i, sub;
                    290: 
                    291:        sub = -1;
                    292:        if (nArgc > 1) {
                    293:                cmd = psArgs[1];                
                    294:                /* which subcommand? */
                    295:                for (i = 0; i < ARRAYSIZE(infotable); i++) {
                    296:                        if (strcmp(cmd, infotable[i].name) == 0) {
                    297:                                sub = i;
                    298:                                break;
                    299:                        }
                    300:                }
                    301:        }
                    302: 
                    303:        if (infotable[sub].args) {
                    304:                /* value needs callback specific conversion */
                    305:                value = infotable[sub].args(nArgc-2, psArgs+2);
                    306:                ok = !!value;
                    307:        } else {
                    308:                if (nArgc > 2) {
                    309:                        /* value is normal number */
                    310:                        ok = Eval_Number(psArgs[2], &value);
                    311:                } else {
                    312:                        value = 0;
                    313:                        ok = true;
                    314:                }
                    315:        }
                    316: 
                    317:        lock = (strcmp(psArgs[0], "lock") == 0);
                    318:        
                    319:        if (sub < 0 || !ok) {
                    320:                /* no subcommand or something wrong with value, show info */
                    321:                fprintf(stderr, "%s subcommands are:\n", psArgs[0]);
                    322:                for (i = 0; i < ARRAYSIZE(infotable); i++) {
                    323:                        if (!lock && infotable[i].lock) {
                    324:                                continue;
                    325:                        }
                    326:                        fprintf(stderr, "- %s: %s\n",
                    327:                                infotable[i].name, infotable[i].info);
                    328:                }
                    329:                return DEBUGGER_CMDDONE;
                    330:        }
                    331: 
                    332:        if (lock) {
                    333:                /* lock given subcommand and value */
                    334:                LockedFunction = sub;
                    335:                LockedArgument = value;
                    336:                fprintf(stderr, "Locked %s output.\n", psArgs[1]);
                    337:        } else {
                    338:                /* do actual work */
                    339:                infotable[sub].func(value);
                    340:        }
                    341:        return DEBUGGER_CMDDONE;
                    342: }

unix.superglobalmegacorp.com

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