Annotation of hatari/src/debug/history.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * Hatari - history.c
                      3:  * 
                      4:  * Copyright (C) 2011 by Eero Tamminen
                      5:  *
1.1.1.2 ! root        6:  * This file is distributed under the GNU General Public License, version 2
        !             7:  * or at your option any later version. Read the file gpl.txt for details.
1.1       root        8:  *
                      9:  * history.c - functions for debugger entry & breakpoint history
                     10:  */
                     11: const char History_fileid[] = "Hatari history.c : " __DATE__ " " __TIME__;
                     12: 
                     13: #include <assert.h>
                     14: 
                     15: #include "main.h"
                     16: #include "debugui.h"
                     17: #include "debug_priv.h"
                     18: #include "dsp.h"
                     19: #include "dsp_core.h"
                     20: #include "evaluate.h"
                     21: #include "history.h"
                     22: #include "m68000.h"
                     23: #include "68kDisass.h"
                     24: 
1.1.1.2 ! root       25: 
        !            26: history_type_t HistoryTracking;
1.1       root       27: 
                     28: #define HISTORY_ITEMS  256
                     29: 
                     30: typedef struct {
                     31:        bool shown:1;
                     32:        bool valid:1;
                     33:        bool for_dsp:1;
                     34:        /* reason for debugger entry/breakpoint hit */
                     35:        debug_reason_t reason:8;
                     36:        union {
                     37:                Uint16 dsp;
                     38:                Uint32 cpu;
                     39:        } pc;
                     40: } hist_item_t;
                     41: 
                     42: static struct {
                     43:        unsigned idx;     /* index to current history item */
                     44:        unsigned count;   /* how many items of history are collected */
                     45:        hist_item_t item[HISTORY_ITEMS];  /* ring-buffer */
                     46: } History;
                     47: 
                     48: 
                     49: /**
                     50:  * Convert debugger entry/breakpoint entry reason to a string
                     51:  */
1.1.1.2 ! root       52: static const char* History_ReasonStr(debug_reason_t reason)
1.1       root       53: {
                     54:        switch(reason) {
                     55:        case REASON_CPU_EXCEPTION:
                     56:                return "CPU exception";
                     57:        case REASON_CPU_BREAKPOINT:
                     58:                return "CPU breakpoint";
                     59:        case REASON_DSP_BREAKPOINT:
                     60:                return "DSP breakpoint";
                     61:        case REASON_CPU_STEPS:
                     62:                return "CPU steps";
                     63:        case REASON_DSP_STEPS:
                     64:                return "DSP steps";
                     65:        case REASON_USER:
                     66:                return "User break";
                     67:        default:
                     68:                return "Unknown reason";
                     69:        }
                     70: }
                     71: 
                     72: 
                     73: /**
1.1.1.2 ! root       74:  * Set what kind of history is collected.
        !            75:  * Clear history if tracking type changes as rest of
        !            76:  * data wouldn't then be anymore valid.
1.1       root       77:  */
1.1.1.2 ! root       78: static void History_Enable(history_type_t track)
1.1       root       79: {
1.1.1.2 ! root       80:        const char *msg;
        !            81:        if (track != HistoryTracking) {
1.1       root       82:                memset(&History, 0, sizeof(History));
                     83:        }
1.1.1.2 ! root       84:        switch (track) {
        !            85:        case HISTORY_TRACK_NONE:
        !            86:                msg = "disabled";
        !            87:                break;
        !            88:        case HISTORY_TRACK_CPU:
        !            89:                msg = "enabled for CPU";
        !            90:                break;
        !            91:        case HISTORY_TRACK_DSP:
        !            92:                msg = "enabled for DSP";
        !            93:                break;
        !            94:        case HISTORY_TRACK_ALL:
        !            95:                msg = "enabled for CPU & DSP";
        !            96:                break;
        !            97:        default:
        !            98:                msg = "error";
        !            99:        }
        !           100:        HistoryTracking = track;
        !           101:        fprintf(stderr, "History tracking %s.\n", msg);
1.1       root      102: }
                    103: 
                    104: /**
                    105:  * Advance & initialize next history item in ring buffer
                    106:  */
                    107: static void History_Advance(void)
                    108: {
                    109:        History.idx++;
                    110:        History.idx %= HISTORY_ITEMS;
                    111:        History.item[History.idx].valid = true;
                    112:        History.item[History.idx].shown = false;
                    113:        History.item[History.idx].reason = REASON_NONE;
                    114:        History.count++;
                    115: }
                    116: 
                    117: /**
                    118:  * Add CPU PC to history
                    119:  */
                    120: void History_AddCpu(void)
                    121: {
                    122:        Uint32 pc = M68000_GetPC();
                    123: 
                    124:        History_Advance();
                    125:        History.item[History.idx].for_dsp = false;
                    126:        History.item[History.idx].pc.cpu = pc;
                    127: }
                    128: 
                    129: /**
                    130:  * Add DSP PC to history
                    131:  */
                    132: void History_AddDsp(void)
                    133: {
                    134:        Uint16 pc = DSP_GetPC();
                    135: 
                    136:        History_Advance();
                    137:        History.item[History.idx].for_dsp = true;
                    138:        History.item[History.idx].pc.dsp = pc;
                    139: }
                    140: 
                    141: /**
                    142:  * Flag last history entry as debugger entry point, with given reason
                    143:  */
                    144: void History_Mark(debug_reason_t reason)
                    145: {
                    146:        History.item[History.idx].reason = reason;
                    147: }
                    148: 
                    149: /**
                    150:  * Show collected CPU/DSP debugger/breakpoint history
                    151:  */
                    152: void History_Show(Uint32 count)
                    153: {
                    154:        bool show_all;
                    155:        int i;
                    156: 
                    157:        if (History.count > HISTORY_ITEMS) {
                    158:                History.count = HISTORY_ITEMS;
                    159:        }
                    160:        if (count > History.count) {
                    161:                count = History.count;
                    162:        } else {
                    163:                if (!count) {
                    164:                        /* default to all */
                    165:                        count = History.count;
                    166:                }
                    167:        }
                    168:        if (count <= 0) {
                    169:                fprintf(stderr,  "No history items to show.\n");
                    170:                return;
                    171:        }
                    172: 
                    173:        i = History.idx;
                    174:        show_all = false;
                    175:        if (History.item[i].shown) {
                    176:                /* even last item already shown, show all again */
                    177:                show_all = true;
                    178:        }
                    179:        i = (i + HISTORY_ITEMS - count) % HISTORY_ITEMS;
                    180: 
                    181:        while (count-- > 0) {
                    182:                i++;
                    183:                i %= HISTORY_ITEMS;
                    184:                if (!History.item[i].valid) {
                    185:                        fprintf(stderr, "ERROR: invalid history item %d!", count);
                    186:                }
                    187:                if (History.item[i].shown && !show_all) {
                    188:                        continue;
                    189:                }
                    190:                History.item[i].shown = true;
                    191: 
                    192:                if (History.item[i].for_dsp) {
                    193:                        Uint16 pc = History.item[i].pc.dsp;
1.1.1.2 ! root      194:                        DSP_DisasmAddress(stderr, pc, pc);
1.1       root      195:                } else {
                    196:                        Uint32 dummy;
1.1.1.2 ! root      197:                        Disasm(stderr, History.item[i].pc.cpu, &dummy, 1);
1.1       root      198:                }
                    199:                if (History.item[i].reason != REASON_NONE) {
                    200:                        fprintf(stderr, "Debugger: *%s*\n", History_ReasonStr(History.item[i].reason));
                    201:                }
                    202:        }
                    203: }
                    204: 
                    205: /**
                    206:  * Command: Show collected CPU/DSP debugger/breakpoint history
                    207:  */
                    208: int History_Parse(int nArgc, char *psArgs[])
                    209: {
                    210:        int count;
                    211: 
                    212:        if (nArgc != 2) {
                    213:                DebugUI_PrintCmdHelp(psArgs[0]);
                    214:                return DEBUGGER_CMDDONE;
                    215:        }
                    216: 
                    217:        count = atoi(psArgs[1]);
                    218:        if (count <= 0 || count > HISTORY_ITEMS) {
                    219:                /* no count -> enable or disable? */
                    220:                if (strcmp(psArgs[1], "on") == 0) {
1.1.1.2 ! root      221:                        History_Enable(HISTORY_TRACK_ALL);
1.1       root      222:                        return DEBUGGER_CMDDONE;
                    223:                }
                    224:                if (strcmp(psArgs[1], "off") == 0) {
1.1.1.2 ! root      225:                        History_Enable(HISTORY_TRACK_NONE);
        !           226:                        return DEBUGGER_CMDDONE;
        !           227:                }
        !           228:                if (strcmp(psArgs[1], "cpu") == 0) {
        !           229:                        History_Enable(HISTORY_TRACK_CPU);
        !           230:                        return DEBUGGER_CMDDONE;
        !           231:                }
        !           232:                if (strcmp(psArgs[1], "dsp") == 0) {
        !           233:                        History_Enable(HISTORY_TRACK_DSP);
1.1       root      234:                        return DEBUGGER_CMDDONE;
                    235:                }
                    236:                fprintf(stderr,  "History range is 1-%d!\n", HISTORY_ITEMS);
                    237:                DebugUI_PrintCmdHelp(psArgs[0]);
                    238:                return DEBUGGER_CMDDONE;
                    239:        }
                    240: 
                    241:        History_Show(count);
                    242:        return DEBUGGER_CMDDONE;
                    243: }

unix.superglobalmegacorp.com

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