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

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

unix.superglobalmegacorp.com

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