Annotation of hatari/src/debug/vars.c, revision 1.1.1.3

1.1       root        1: /*
                      2:   Hatari - vars.c
                      3: 
                      4:   Copyright (c) 2016 by Eero Tamminen
                      5: 
                      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.
                      8: 
                      9:   vars.c - Hatari internal variable value and OS call number accessors
                     10:   for conditional breakpoint and evaluate commands.
                     11: */
                     12: const char Vars_fileid[] = "Hatari vars.c : " __DATE__ " " __TIME__;
                     13: 
                     14: #include <stdio.h>
                     15: #include <stdlib.h>
                     16: #include "main.h"
                     17: #include "configuration.h"
                     18: #include "stMemory.h"
                     19: #include "m68000.h"
1.1.1.3 ! root       20: #include "screen.h"     /* for defines needed by video.h */
        !            21: #include "video.h"      /* for Hatari video variable addresses */
        !            22: #include "hatari-glue.h" /* for currprefs */
1.1       root       23: 
                     24: #include "debugInfo.h"
                     25: #include "debugcpu.h"
                     26: #include "debugdsp.h"
                     27: #include "debugui.h"
                     28: #include "symbols.h"
                     29: #include "68kDisass.h"
                     30: #include "vars.h"
                     31: 
                     32: 
1.1.1.2   root       33: static Uint32 GetCycleCounter(void)
                     34: {
                     35:        /* 64-bit, so only lower 32-bits are returned */
                     36:        return CyclesGlobalClockCounter;
                     37: }
                     38: 
1.1       root       39: /* Accessor functions for calculated Hatari values */
                     40: static Uint32 GetLineCycles(void)
                     41: {
                     42:        int dummy1, dummy2, lcycles;
                     43:        Video_GetPosition(&dummy1, &dummy2 , &lcycles);
                     44:        return lcycles;
                     45: }
                     46: static Uint32 GetFrameCycles(void)
                     47: {
                     48:        int dummy1, dummy2, fcycles;
                     49:        Video_GetPosition(&fcycles, &dummy1, &dummy2);
                     50:        return fcycles;
                     51: }
                     52: 
                     53: /* helpers for TOS OS call opcode accessor functions */
                     54: #define INVALID_OPCODE 0xFFFFu
                     55: 
                     56: static inline Uint16 getLineOpcode(Uint8 line)
                     57: {
                     58:        Uint32 pc;
                     59:        Uint16 instr;
                     60:        pc = M68000_GetPC();
                     61:        instr = STMemory_ReadWord(pc);
                     62:        /* for opcode X, Line-A = 0xA00X, Line-F = 0xF00X */
                     63:        if ((instr >> 12) == line) {
                     64:                return instr & 0xFF;
                     65:        }
                     66:        return INVALID_OPCODE;
                     67: }
                     68: static inline bool isTrap(Uint8 trap)
                     69: {
                     70:        Uint32 pc;
                     71:        Uint16 instr;
                     72:        pc = M68000_GetPC();
                     73:        instr = STMemory_ReadWord(pc);
                     74:        return (instr == (Uint16)0x4e40u + trap);
                     75: }
                     76: static inline Uint16 getControlOpcode(void)
                     77: {
                     78:        /* Control[] address from D1, opcode in Control[0] */
                     79:        return STMemory_ReadWord(STMemory_ReadLong(Regs[REG_D1]));
                     80: }
                     81: static inline Uint16 getStackOpcode(void)
                     82: {
                     83:        return STMemory_ReadWord(Regs[REG_A7]);
                     84: }
                     85: 
                     86: /* Actual TOS OS call opcode accessor functions */
                     87: static Uint32 GetLineAOpcode(void)
                     88: {
                     89:        return getLineOpcode(0xA);
                     90: }
                     91: static Uint32 GetLineFOpcode(void)
                     92: {
                     93:        return getLineOpcode(0xF);
                     94: }
                     95: static Uint32 GetGemdosOpcode(void)
                     96: {
                     97:        if (isTrap(1)) {
                     98:                return getStackOpcode();
                     99:        }
                    100:        return INVALID_OPCODE;
                    101: }
                    102: static Uint32 GetBiosOpcode(void)
                    103: {
                    104:        if (isTrap(13)) {
                    105:                return getStackOpcode();
                    106:        }
                    107:        return INVALID_OPCODE;
                    108: }
                    109: static Uint32 GetXbiosOpcode(void)
                    110: {
                    111:        if (isTrap(14)) {
                    112:                return getStackOpcode();
                    113:        }
                    114:        return INVALID_OPCODE;
                    115: }
                    116: static Uint32 GetAesOpcode(void)
                    117: {
                    118:        if (isTrap(2)) {
                    119:                Uint16 d0 = Regs[REG_D0];
                    120:                if (d0 == 0xC8) {
                    121:                        return getControlOpcode();
                    122:                } else if (d0 == 0xC9) {
                    123:                        /* same as appl_yield() */
                    124:                        return 0x11;
                    125:                }
                    126:        }
                    127:        return INVALID_OPCODE;
                    128: }
                    129: static Uint32 GetVdiOpcode(void)
                    130: {
                    131:        if (isTrap(2)) {
                    132:                Uint16 d0 = Regs[REG_D0];
                    133:                if (d0 == 0x73) {
                    134:                        return getControlOpcode();
                    135:                } else if (d0 == 0xFFFE) {
                    136:                        /* -2 = vq_[v]gdos() */
                    137:                        return 0xFFFE;
                    138:                }
                    139:        }
                    140:        return INVALID_OPCODE;
                    141: }
                    142: 
1.1.1.3 ! root      143: /** return first word in OS call parameters
        !           144:  */
        !           145: static Uint32 GetOsCallParam(void)
        !           146: {
        !           147:        /* skip OS call opcode */
        !           148:        return STMemory_ReadWord(Regs[REG_A7]+SIZE_WORD);
        !           149: }
        !           150: 
1.1       root      151: static Uint32 GetNextPC(void)
                    152: {
                    153:        return Disasm_GetNextPC(M68000_GetPC());
                    154: }
                    155: 
                    156: /* sorted by variable name so that this can be bisected */
                    157: static const var_addr_t hatari_vars[] = {
                    158:        { "AesOpcode", (Uint32*)GetAesOpcode, VALUE_TYPE_FUNCTION32, 16, "$FFFF when not on AES trap" },
                    159:        { "Basepage", (Uint32*)DebugInfo_GetBASEPAGE, VALUE_TYPE_FUNCTION32, 0, "invalid before Desktop is up" },
                    160:        { "BiosOpcode", (Uint32*)GetBiosOpcode, VALUE_TYPE_FUNCTION32, 16, "$FFFF when not on BIOS trap" },
                    161:        { "BSS", (Uint32*)DebugInfo_GetBSS, VALUE_TYPE_FUNCTION32, 0, "invalid before Desktop is up" },
                    162:        { "CpuInstr", (Uint32*)DebugCpu_InstrCount, VALUE_TYPE_FUNCTION32, 0, "CPU instructions count" },
                    163:        { "CpuOpcodeType", (Uint32*)DebugCpu_OpcodeType, VALUE_TYPE_FUNCTION32, 0, "internal CPU instruction type" },
1.1.1.3 ! root      164:        { "CycleCounter", (Uint32*)GetCycleCounter, VALUE_TYPE_FUNCTION32, 0, "global cycles counter (lower 32 bits)" },
1.1       root      165:        { "DATA", (Uint32*)DebugInfo_GetDATA, VALUE_TYPE_FUNCTION32, 0, "invalid before Desktop is up" },
                    166: #if ENABLE_DSP_EMU
                    167:        { "DspInstr", (Uint32*)DebugDsp_InstrCount, VALUE_TYPE_FUNCTION32, 0, "DSP instructions count" },
                    168:        { "DspOpcodeType", (Uint32*)DebugDsp_OpcodeType, VALUE_TYPE_FUNCTION32, 0, "internal DSP instruction type" },
                    169: #endif
                    170:        { "FrameCycles", (Uint32*)GetFrameCycles, VALUE_TYPE_FUNCTION32, 0, NULL },
                    171:        { "GemdosOpcode", (Uint32*)GetGemdosOpcode, VALUE_TYPE_FUNCTION32, 16, "$FFFF when not on GEMDOS trap" },
                    172:        { "HBL", (Uint32*)&nHBL, VALUE_TYPE_VAR32, sizeof(nHBL)*8, NULL },
                    173:        { "LineAOpcode", (Uint32*)GetLineAOpcode, VALUE_TYPE_FUNCTION32, 16, "$FFFF when not on Line-A opcode" },
                    174:        { "LineCycles", (Uint32*)GetLineCycles, VALUE_TYPE_FUNCTION32, 0, "is always divisable by 4" },
                    175:        { "LineFOpcode", (Uint32*)GetLineFOpcode, VALUE_TYPE_FUNCTION32, 16, "$FFFF when not on Line-F opcode" },
                    176:        { "NextPC", (Uint32*)GetNextPC, VALUE_TYPE_FUNCTION32, 0, NULL },
1.1.1.3 ! root      177:        { "OsCallParam", (Uint32*)GetOsCallParam, VALUE_TYPE_FUNCTION32, 16, "word value, valid only on OS call opcode breakpoint" },
1.1       root      178:        { "TEXT", (Uint32*)DebugInfo_GetTEXT, VALUE_TYPE_FUNCTION32, 0, "invalid before Desktop is up" },
                    179:        { "TEXTEnd", (Uint32*)DebugInfo_GetTEXTEnd, VALUE_TYPE_FUNCTION32, 0, "invalid before Desktop is up" },
                    180:        { "VBL", (Uint32*)&nVBLs, VALUE_TYPE_VAR32, sizeof(nVBLs)*8, NULL },
                    181:        { "VdiOpcode", (Uint32*)GetVdiOpcode, VALUE_TYPE_FUNCTION32, 16, "$FFFF when not on VDI trap" },
                    182:        { "XbiosOpcode", (Uint32*)GetXbiosOpcode, VALUE_TYPE_FUNCTION32, 16, "$FFFF when not on XBIOS trap" }
                    183: };
                    184: 
                    185: 
                    186: /**
                    187:  * Readline match callback for Hatari variable and CPU variable/symbol name completion.
                    188:  * STATE = 0 -> different text from previous one.
                    189:  * Return next match or NULL if no matches.
                    190:  */
                    191: char *Vars_MatchCpuVariable(const char *text, int state)
                    192: {
                    193:        static int i, len;
                    194:        const char *name;
                    195: 
                    196:        if (!state) {
                    197:                /* first match */
                    198:                len = strlen(text);
                    199:                i = 0;
                    200:        }
                    201:        /* next match */
                    202:        while (i < ARRAY_SIZE(hatari_vars)) {
                    203:                name = hatari_vars[i++].name;
                    204:                if (strncasecmp(name, text, len) == 0)
                    205:                        return (strdup(name));
                    206:        }
                    207:        /* no variable match, check all CPU symbols */
                    208:        return Symbols_MatchCpuAddress(text, state);
                    209: }
                    210: 
                    211: 
                    212: /**
                    213:  * If given string matches Hatari variable name, return its struct pointer,
                    214:  * otherwise return NULL.
                    215:  */
                    216: const var_addr_t *Vars_ParseVariable(const char *name)
                    217: {
                    218:        const var_addr_t *hvar;
                    219:        /* left, right, middle, direction */
                    220:         int l, r, m, dir;
                    221: 
                    222:        /* bisect */
                    223:        l = 0;
                    224:        r = ARRAY_SIZE(hatari_vars) - 1;
                    225:        do {
                    226:                m = (l+r) >> 1;
                    227:                hvar = hatari_vars + m;
                    228:                dir = strcasecmp(name, hvar->name);
                    229:                if (dir == 0) {
                    230:                        return hvar;
                    231:                }
                    232:                if (dir < 0) {
                    233:                        r = m-1;
                    234:                } else {
                    235:                        l = m+1;
                    236:                }
                    237:        } while (l <= r);
                    238:        return NULL;
                    239: }
                    240: 
                    241: 
                    242: /**
                    243:  * Return Uint32 value from given Hatari variable struct*
                    244:  */
                    245: Uint32 Vars_GetValue(const var_addr_t *hvar)
                    246: {
                    247:        switch (hvar->vtype) {
                    248:        case VALUE_TYPE_FUNCTION32:
                    249:                return ((Uint32(*)(void))(hvar->addr))();
                    250:        case VALUE_TYPE_VAR32:
                    251:                return *(hvar->addr);
                    252:        default:
                    253:                fprintf(stderr, "ERROR: variable '%s' has unsupported type '%d'\n",
                    254:                        hvar->name, hvar->vtype);
                    255:                exit(-1);
                    256:        }
                    257: }
                    258: 
                    259: 
                    260: /**
                    261:  * If given string is a Hatari variable name, set value to given
                    262:  * variable's value and return true, otherwise return false.
                    263:  */
                    264: bool Vars_GetVariableValue(const char *name, Uint32 *value)
                    265: {
                    266:        const var_addr_t *hvar;
                    267: 
                    268:        if (!(hvar = Vars_ParseVariable(name))) {
                    269:                return false;
                    270:        }
                    271:        *value = Vars_GetValue(hvar);
                    272:        return true;
                    273: }
                    274: 
                    275: 
                    276: /**
                    277:  * List Hatari variable names & current values
                    278:  */
                    279: int Vars_List(int nArgc, char *psArgv[])
                    280: {
                    281:        Uint32 value;
                    282:        int i;
                    283:        fputs("Hatari debugger builtin symbols and their values are:\n", stderr);
                    284:        for (i = 0; i < ARRAY_SIZE(hatari_vars); i++) {
                    285:                const var_addr_t *hvar = hatari_vars + i;
                    286:                value = Vars_GetValue(hvar);
                    287:                fprintf(stderr, "  - %s: $%X / #%d", hvar->name, value, value);
                    288:                if (hvar->info) {
                    289:                        fprintf(stderr, " -- %s\n", hvar->info);
                    290:                } else {
                    291:                        fprintf(stderr, "\n");
                    292:                }
                    293:        }
                    294:        return DEBUGGER_CMDDONE;
                    295: }

unix.superglobalmegacorp.com

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