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

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>
                     14: #include "main.h"
                     15: #include "configuration.h"
                     16: #include "debugInfo.h"
                     17: #include "debugcpu.h"
                     18: #include "debugdsp.h"
                     19: #include "debugui.h"
                     20: #include "dsp.h"
                     21: #include "evaluate.h"
1.1.1.2 ! root       22: #include "file.h"
        !            23: #include "gemdos.h"
1.1       root       24: #include "ioMem.h"
                     25: #include "m68000.h"
                     26: #include "stMemory.h"
                     27: #include "tos.h"
1.1.1.2 ! root       28: #include "screen.h"
        !            29: #include "vdi.h"
1.1       root       30: #include "video.h"
                     31: 
                     32: 
                     33: /* ------------------------------------------------------------------
                     34:  * TOS information
                     35:  */
                     36: #define OS_SYSBASE 0x4F2
                     37: #define OS_HEADER_SIZE 0x30
                     38: 
                     39: #define COOKIE_JAR 0x5A0
                     40: 
                     41: #define BASEPAGE_SIZE 0x100
                     42: 
                     43: #define GEM_MAGIC 0x87654321
                     44: #define GEM_MUPB_SIZE 0xC
                     45: 
                     46: #define RESET_MAGIC 0x31415926
                     47: #define RESET_VALID 0x426
                     48: #define RESET_VECTOR 0x42A
                     49: 
                     50: #define COUNTRY_SPAIN 4
                     51: 
1.1.1.2 ! root       52: 
1.1       root       53: /**
                     54:  * DebugInfo_GetSysbase: set osversion to given argument.
                     55:  * return sysbase address on success and zero on failure.
                     56:  */
                     57: static Uint32 DebugInfo_GetSysbase(Uint16 *osversion)
                     58: {
                     59:        Uint32 sysbase = STMemory_ReadLong(OS_SYSBASE);
                     60: 
                     61:        if (!STMemory_ValidArea(sysbase, OS_HEADER_SIZE)) {
                     62:                fprintf(stderr, "Invalid TOS base address!\n");
                     63:                return 0;
                     64:        }
                     65:        if (sysbase != TosAddress || sysbase != STMemory_ReadLong(sysbase+0x08)) {
                     66:                fprintf(stderr, "Sysbase and os_beg address in OS header mismatch!\n");
                     67:                return 0;
                     68:        }
                     69:        *osversion = STMemory_ReadWord(sysbase+0x02);
                     70:        return sysbase;
                     71: }
                     72: 
                     73: /**
                     74:  * DebugInfo_CurrentBasepage: get currently running TOS program basepage
                     75:  */
                     76: static Uint32 DebugInfo_CurrentBasepage(void)
                     77: {
                     78:        Uint32 basepage, sysbase;
                     79:        Uint16 osversion, osconf;
                     80: 
                     81:        sysbase = DebugInfo_GetSysbase(&osversion);
                     82:        if (!sysbase) {
                     83:                return 0;
                     84:        }
                     85:        if (osversion >= 0x0102) {
                     86:                basepage = STMemory_ReadLong(sysbase+0x28);
                     87:        } else {
                     88:                osconf = STMemory_ReadWord(sysbase+0x1C);
                     89:                if((osconf>>1) == COUNTRY_SPAIN) {
                     90:                        basepage = 0x873C;
                     91:                } else {
                     92:                        basepage = 0x602C;
                     93:                }
                     94:        }
                     95:        if (STMemory_ValidArea(basepage, 4)) {
                     96:                return STMemory_ReadLong(basepage);
                     97:        }
                     98:        fprintf(stderr, "Pointer 0x%06x to basepage address is invalid!\n", basepage);
                     99:        return 0;
                    100: }
                    101: 
1.1.1.2 ! root      102: 
        !           103: /**
        !           104:  * GetSegmentAddress: return segment address at given offset in
        !           105:  * TOS process basepage or zero if that is missing/invalid.
        !           106:  */
        !           107: static Uint32 GetSegmentAddress(unsigned offset)
        !           108: {
        !           109:        Uint32 basepage = DebugInfo_CurrentBasepage();
        !           110:        if (!basepage) {
        !           111:                return 0;
        !           112:        }
        !           113:        if (!STMemory_ValidArea(basepage, BASEPAGE_SIZE) ||
        !           114:            STMemory_ReadLong(basepage) != basepage) {
        !           115:                fprintf(stderr, "Basepage address 0x%06x is invalid!\n", basepage);
        !           116:                return 0;
        !           117:        }
        !           118:        return STMemory_ReadLong(basepage+offset);
        !           119: }
        !           120: 
        !           121: /**
        !           122:  * DebugInfo_GetTEXT: return current program TEXT segment address
        !           123:  * or zero if basepage missing/invalid.  For virtual debugger variable.
        !           124:  */
        !           125: Uint32 DebugInfo_GetTEXT(void)
        !           126: {
        !           127:        return GetSegmentAddress(0x08);
        !           128: }
        !           129: /**
        !           130:  * DebugInfo_GetDATA: return current program DATA segment address
        !           131:  * or zero if basepage missing/invalid.  For virtual debugger variable.
        !           132:  */
        !           133: Uint32 DebugInfo_GetDATA(void)
        !           134: {
        !           135:        return GetSegmentAddress(0x010);
        !           136: }
        !           137: /**
        !           138:  * DebugInfo_GetBSS: return current program BSS segment address
        !           139:  * or zero if basepage missing/invalid.  For virtual debugger variable.
        !           140:  */
        !           141: Uint32 DebugInfo_GetBSS(void)
        !           142: {
        !           143:        return GetSegmentAddress(0x18);
        !           144: }
        !           145: 
        !           146: 
1.1       root      147: /**
                    148:  * DebugInfo_Basepage: show TOS process basepage information
                    149:  * at given address.
                    150:  */
                    151: static void DebugInfo_Basepage(Uint32 basepage)
                    152: {
                    153:        Uint8 cmdlen;
                    154:        Uint32 env;
                    155: 
                    156:        if (!basepage) {
                    157:                /* default to current process basepage */
                    158:                basepage = DebugInfo_CurrentBasepage();
                    159:                if (!basepage) {
                    160:                        return;
                    161:                }
                    162:        }
                    163:        fprintf(stderr, "Process basepage information:\n");
                    164:        if (!STMemory_ValidArea(basepage, BASEPAGE_SIZE) ||
                    165:            STMemory_ReadLong(basepage) != basepage) {
                    166:                fprintf(stderr, "- address 0x%06x is invalid!\n", basepage);
                    167:                return;
                    168:        }
                    169:        fprintf(stderr, "- TPA start      : 0x%06x\n", STMemory_ReadLong(basepage));
                    170:        fprintf(stderr, "- TPA end +1     : 0x%06x\n", STMemory_ReadLong(basepage+0x04));
                    171:        fprintf(stderr, "- Text segment   : 0x%06x\n", STMemory_ReadLong(basepage+0x08));
                    172:        fprintf(stderr, "- Text size      : 0x%x\n",   STMemory_ReadLong(basepage+0x0C));
                    173:        fprintf(stderr, "- Data segment   : 0x%06x\n", STMemory_ReadLong(basepage+0x10));
                    174:        fprintf(stderr, "- Data size      : 0x%x\n",   STMemory_ReadLong(basepage+0x14));
                    175:        fprintf(stderr, "- BSS segment    : 0x%06x\n", STMemory_ReadLong(basepage+0x18));
                    176:        fprintf(stderr, "- BSS size       : 0x%x\n",   STMemory_ReadLong(basepage+0x1C));
                    177:        fprintf(stderr, "- Process DTA    : 0x%06x\n", STMemory_ReadLong(basepage+0x20));
                    178:        fprintf(stderr, "- Parent basepage: 0x%06x\n", STMemory_ReadLong(basepage+0x24));
                    179: 
                    180:        env = STMemory_ReadLong(basepage+0x2C);
                    181:        fprintf(stderr, "- Environment    : 0x%06x\n", env);
                    182:        if (STMemory_ValidArea(env, 4096)) {
                    183:                Uint32 end = env + 4096;
                    184:                while (env < end && *(STRam+env)) {
                    185:                        fprintf(stderr, "'%s'\n", STRam+env);
                    186:                        env += strlen((const char *)(STRam+env)) + 1;
                    187:                }
                    188:        }
                    189:        cmdlen = STMemory_ReadByte(basepage+0x80);
                    190:        fprintf(stderr, "- Command argslen: %d\n", cmdlen);
                    191:        if (cmdlen) {
                    192:                int offset = 0;
                    193:                while (offset < cmdlen) {
                    194:                        fprintf(stderr, " '%s'", STRam+basepage+0x81+offset);
                    195:                        offset += strlen((const char *)(STRam+basepage+0x81+offset)) + 1;
                    196:                }
                    197:                fprintf(stderr, "\n");
                    198:        }
                    199: }
                    200: 
                    201: /**
                    202:  * DebugInfo_OSHeader: display TOS OS Header
                    203:  */
                    204: static void DebugInfo_OSHeader(Uint32 dummy)
                    205: {
                    206:        Uint32 sysbase, gemblock, basepage;
1.1.1.2 ! root      207:        Uint16 osversion, osconf, langbits;
        !           208:        const char *lang;
        !           209:        static const char langs[][3] = {
        !           210:                "us", "de", "fr", "uk", "es", "it", "se", "ch" /* fr */, "ch" /* de */,
        !           211:                "tr", "fi", "no", "dk", "sa", "nl", "cs", "hu"
        !           212:        };
1.1       root      213: 
                    214:        sysbase = DebugInfo_GetSysbase(&osversion);
                    215:        if (!sysbase) {
                    216:                return;
                    217:        }
1.1.1.2 ! root      218:        fprintf(stderr, "TOS OS header information:\n");
1.1       root      219:        fprintf(stderr, "OS base addr : 0x%06x\n", sysbase);
                    220:        fprintf(stderr, "OS RAM end+1 : 0x%06x\n", STMemory_ReadLong(sysbase+0x0C));
                    221:        fprintf(stderr, "TOS version  : 0x%x\n", osversion);
                    222: 
                    223:        fprintf(stderr, "Reset handler: 0x%06x\n", STMemory_ReadLong(sysbase+0x04));
                    224:        fprintf(stderr, "Reset vector : 0x%06x\n", STMemory_ReadLong(RESET_VECTOR));
                    225:        fprintf(stderr, "Reset valid  : 0x%x (valid=0x%x)\n", STMemory_ReadLong(RESET_VALID), RESET_MAGIC);
                    226: 
                    227:        gemblock = STMemory_ReadLong(sysbase+0x14);
                    228:        fprintf(stderr, "GEM Memory Usage Parameter Block:\n");
                    229:        if (STMemory_ValidArea(gemblock, GEM_MUPB_SIZE)) {
                    230:                fprintf(stderr, "- Block addr : 0x%06x\n", gemblock);
                    231:                fprintf(stderr, "- GEM magic  : 0x%x (valid=0x%x)\n", STMemory_ReadLong(gemblock), GEM_MAGIC);
                    232:                fprintf(stderr, "- GEM entry  : 0x%06x\n", STMemory_ReadLong(gemblock+4));
                    233:                fprintf(stderr, "- GEM end    : 0x%06x\n", STMemory_ReadLong(gemblock+8));
                    234:        } else {
                    235:                fprintf(stderr, "- is at INVALID 0x%06x address.\n", gemblock);
                    236:        }
                    237: 
                    238:        fprintf(stderr, "OS date      : 0x%x\n", STMemory_ReadLong(sysbase+0x14));
                    239:        fprintf(stderr, "OS DOS date  : 0x%x\n", STMemory_ReadLong(sysbase+0x1E));
                    240: 
                    241:        osconf = STMemory_ReadWord(sysbase+0x1C);
1.1.1.2 ! root      242:        langbits = osconf >> 1;
        !           243:        if (langbits == 127) {
        !           244:                lang = "all";
        !           245:        } else if (langbits < ARRAYSIZE(langs)) {
        !           246:                lang = langs[langbits];
        !           247:        } else {
        !           248:                lang = "unknown";
        !           249:        }
        !           250:        fprintf(stderr, "OS Conf bits : 0x%04x (%s, %s)\n", osconf, lang, osconf&1 ? "PAL":"NTSC");
1.1       root      251: 
                    252:        if (osversion >= 0x0102) {
1.1.1.2 ! root      253:                /* last 3 OS header fields are only available as of TOS 1.02 */
1.1       root      254:                fprintf(stderr, "Memory pool  : 0x%06x\n", STMemory_ReadLong(sysbase+0x20));
                    255:                fprintf(stderr, "Kbshift addr : 0x%06x\n", STMemory_ReadLong(sysbase+0x24));
                    256:        } else {
1.1.1.2 ! root      257:                /* TOS 1.0 */
        !           258:                fprintf(stderr, "Memory pool  : 0x0056FA\n");
1.1       root      259:                fprintf(stderr, "Kbshift addr : 0x000E1B\n");
                    260:        }
                    261:        basepage = DebugInfo_CurrentBasepage();
                    262:        if (basepage) {
                    263:                fprintf(stderr, "Basepage     : 0x%06x\n", basepage);
                    264:        }
                    265: }
                    266: 
                    267: 
1.1.1.2 ! root      268: /**
        !           269:  * DebugInfo_Cookiejar: display TOS Cookiejar content
        !           270:  */
        !           271: static void DebugInfo_Cookiejar(Uint32 dummy)
        !           272: {
        !           273:        int items;
        !           274: 
        !           275:        Uint32 jar = STMemory_ReadLong(COOKIE_JAR);
        !           276:        if (!jar) {
        !           277:                fprintf(stderr, "Cookiejar is empty.\n");
        !           278:                return;
        !           279:        }
        !           280: 
        !           281:        fprintf(stderr, "Cookiejar contents:\n");
        !           282:        items = 0;
        !           283:        while (STMemory_ValidArea(jar, 8) && STMemory_ReadLong(jar)) {
        !           284:                fprintf(stderr, "%c%c%c%c = 0x%08x\n",
        !           285:                        STRam[jar], STRam[jar+1], STRam[jar+2], STRam[jar+3],
        !           286:                        STMemory_ReadLong(jar+4));
        !           287:                jar += 8;
        !           288:                items++;
        !           289:        }
        !           290:        fprintf(stderr, "%d items at 0x%06x.\n", items, STMemory_ReadLong(COOKIE_JAR));
        !           291: }
        !           292: 
        !           293: 
        !           294: /**
        !           295:  * DebugInfo_Video: display video related information
        !           296:  */
        !           297: static void DebugInfo_Video(Uint32 dummy)
        !           298: {
        !           299:        const char *mode;
        !           300:        switch (OverscanMode) {
        !           301:        case OVERSCANMODE_NONE:
        !           302:                mode = "none";
        !           303:                break;
        !           304:        case OVERSCANMODE_TOP:
        !           305:                mode = "top";
        !           306:                break;
        !           307:        case OVERSCANMODE_BOTTOM:
        !           308:                mode = "bottom";
        !           309:                break;
        !           310:        case OVERSCANMODE_TOP|OVERSCANMODE_BOTTOM:
        !           311:                mode = "top+bottom";
        !           312:                break;
        !           313:        default:
        !           314:                mode = "unknown";
        !           315:        }
        !           316:        fprintf(stderr, "Video base   : 0x%x\n", VideoBase);
        !           317:        fprintf(stderr, "VBL counter  : %d\n", nVBLs);
        !           318:        fprintf(stderr, "HBL line     : %d\n", nHBL);
        !           319:        fprintf(stderr, "V-overscan   : %s\n", mode);
        !           320:        fprintf(stderr, "Refresh rate : %d Hz\n", nScreenRefreshRate);
        !           321:        fprintf(stderr, "Frame skips  : %d\n", nFrameSkips);
        !           322: }
        !           323: 
1.1       root      324: /* ------------------------------------------------------------------
                    325:  * Falcon HW information
                    326:  */
                    327: 
                    328: /**
                    329:  * DebugInfo_Videl : display the Videl registers values.
                    330:  */
                    331: static void DebugInfo_Videl(Uint32 dummy)
                    332: {
                    333:        if (ConfigureParams.System.nMachineType != MACHINE_FALCON) {
                    334:                fprintf(stderr, "Not Falcon - no Videl!\n");
                    335:                return;
                    336:        }
                    337: 
1.1.1.2 ! root      338:        fprintf(stderr, "$FF8006.b : monitor type                     : %02x\n", IoMem_ReadByte(0xff8006));
        !           339:        fprintf(stderr, "$FF8201.b : Video Base Hi                    : %02x\n", IoMem_ReadByte(0xff8201));
        !           340:        fprintf(stderr, "$FF8203.b : Video Base Mi                    : %02x\n", IoMem_ReadByte(0xff8203));
        !           341:        fprintf(stderr, "$FF8205.b : Video Count Hi                   : %02x\n", IoMem_ReadByte(0xff8205));
        !           342:        fprintf(stderr, "$FF8207.b : Video Count Mi                   : %02x\n", IoMem_ReadByte(0xff8207));
        !           343:        fprintf(stderr, "$FF8209.b : Video Count Lo                   : %02x\n", IoMem_ReadByte(0xff8209));
        !           344:        fprintf(stderr, "$FF820A.b : Sync mode                        : %02x\n", IoMem_ReadByte(0xff820a));
        !           345:        fprintf(stderr, "$FF820D.b : Video Base Lo                    : %02x\n", IoMem_ReadByte(0xff820d));
        !           346:        fprintf(stderr, "$FF820E.w : offset to next line              : %04x\n", IoMem_ReadWord(0xff820e));
        !           347:        fprintf(stderr, "$FF8210.w : VWRAP - line width               : %04x\n", IoMem_ReadWord(0xff8210));
        !           348:        fprintf(stderr, "$FF8260.b : ST shift mode                    : %02x\n", IoMem_ReadByte(0xff8260));
        !           349:        fprintf(stderr, "$FF8264.w : Horizontal scroll register       : %04x\n", IoMem_ReadWord(0xff8264));
        !           350:        fprintf(stderr, "$FF8266.w : Falcon shift mode                : %04x\n", IoMem_ReadWord(0xff8266));
1.1       root      351:        fprintf(stderr, "\n");
1.1.1.2 ! root      352:        fprintf(stderr, "$FF8280.w : HHC - Horizontal Hold Counter    : %04x\n", IoMem_ReadWord(0xff8280));
        !           353:        fprintf(stderr, "$FF8282.w : HHT - Horizontal Hold Timer      : %04x\n", IoMem_ReadWord(0xff8282));
        !           354:        fprintf(stderr, "$FF8284.w : HBB - Horizontal Border Begin    : %04x\n", IoMem_ReadWord(0xff8284));
        !           355:        fprintf(stderr, "$FF8286.w : HBE - Horizontal Border End      : %04x\n", IoMem_ReadWord(0xff8286));
        !           356:        fprintf(stderr, "$FF8288.w : HDB - Horizontal Display Begin   : %04x\n", IoMem_ReadWord(0xff8288));
        !           357:        fprintf(stderr, "$FF828A.w : HDE - Horizontal Display End     : %04x\n", IoMem_ReadWord(0xff828a));
        !           358:        fprintf(stderr, "$FF828C.w : HSS - Horizontal SS              : %04x\n", IoMem_ReadWord(0xff828c));
        !           359:        fprintf(stderr, "$FF828E.w : HFS - Horizontal FS              : %04x\n", IoMem_ReadWord(0xff828e));
        !           360:        fprintf(stderr, "$FF8290.w : HEE - Horizontal EE              : %04x\n", IoMem_ReadWord(0xff8290));
1.1       root      361:        fprintf(stderr, "\n");
1.1.1.2 ! root      362:        fprintf(stderr, "$FF82A0.w : VFC - Vertical Frequency Counter : %04x\n", IoMem_ReadWord(0xff82a0));
        !           363:        fprintf(stderr, "$FF82A2.w : VFT - Vertical Frequency Timer   : %04x\n", IoMem_ReadWord(0xff82a2));
        !           364:        fprintf(stderr, "$FF82A4.w : VBB - Vertical Border Begin      : %04x\n", IoMem_ReadWord(0xff82a4));
        !           365:        fprintf(stderr, "$FF82A6.w : VBE - Vertical Border End        : %04x\n", IoMem_ReadWord(0xff82a6));
        !           366:        fprintf(stderr, "$FF82A8.w : VDB - Vertical Display Begin     : %04x\n", IoMem_ReadWord(0xff82a8));
        !           367:        fprintf(stderr, "$FF82AA.w : VDE - Vertical Display End       : %04x\n", IoMem_ReadWord(0xff82aa));
        !           368:        fprintf(stderr, "$FF82AC.w : VSS - Vertical SS                : %04x\n", IoMem_ReadWord(0xff82ac));
1.1       root      369:        fprintf(stderr, "\n");
1.1.1.2 ! root      370:        fprintf(stderr, "$FF82C0.w : VCO - Video control              : %04x\n", IoMem_ReadWord(0xff82c0));
        !           371:        fprintf(stderr, "$FF82C2.w : VMD - Video mode                 : %04x\n", IoMem_ReadWord(0xff82c2));
        !           372:        fprintf(stderr, "\n-------------------------\n");
        !           373: 
        !           374:        fprintf(stderr, "Video base  : %08x\n", (IoMem_ReadByte(0xff8201)<<16) + 
        !           375:                                                                                        (IoMem_ReadByte(0xff8203)<<8)  + 
        !           376:                                                                                        IoMem_ReadByte(0xff820d));
        !           377:        fprintf(stderr, "Video count : %08x\n", (IoMem_ReadByte(0xff8205)<<16) + 
        !           378:                                                                                        (IoMem_ReadByte(0xff8207)<<8)  + 
        !           379:                                                                                        IoMem_ReadByte(0xff8209));
1.1       root      380: }
                    381: 
                    382: /**
                    383:  * DebugInfo_Crossbar : display the Crossbar registers values.
                    384:  */
                    385: static void DebugInfo_Crossbar(Uint32 dummy)
                    386: {
                    387:        char matrixDMA[5], matrixDAC[5], matrixDSP[5], matrixEXT[5];
                    388:        char frqDMA[11], frqDAC[11], frqDSP[11], frqEXT[11];
1.1.1.2 ! root      389:        char frqSTE[30], frq25Mhz[30], frq32Mhz[30];
1.1       root      390:        char dataSize[15];
                    391:        
1.1.1.2 ! root      392:        static const Uint32 Ste_SampleRates[4] = {
        !           393:                6258, 12517, 25033, 50066
        !           394:        };
        !           395: 
        !           396:        static const Uint32 Falcon_SampleRates_25Mhz[15] = {
        !           397:                49170, 32780, 24585, 19668, 16390, 14049, 12292, 10927, 9834, 8940, 8195, 7565, 7024, 6556, 6146
        !           398:        };
        !           399: 
        !           400:        static const Uint32 Falcon_SampleRates_32Mhz[15] = {
        !           401:                62500, 41666, 31250, 25000, 20833, 17857, 15624, 13889, 12500, 11363, 10416, 9615, 8928, 8333, 7812
        !           402:        };
        !           403: 
1.1       root      404:        if (ConfigureParams.System.nMachineType != MACHINE_FALCON) {
                    405:                fprintf(stderr, "Not Falcon - no Crossbar!\n");
                    406:                return;
                    407:        }
                    408: 
1.1.1.2 ! root      409:        fprintf(stderr, "$FF8900.b : Sound DMA control                     : %02x\n", IoMem_ReadByte(0xff8900));
        !           410:        fprintf(stderr, "$FF8901.b : Sound DMA control                     : %02x\n", IoMem_ReadByte(0xff8901));
        !           411:        fprintf(stderr, "$FF8903.b : Frame Start High                      : %02x\n", IoMem_ReadByte(0xff8903));
        !           412:        fprintf(stderr, "$FF8905.b : Frame Start middle                    : %02x\n", IoMem_ReadByte(0xff8905));
        !           413:        fprintf(stderr, "$FF8907.b : Frame Start low                       : %02x\n", IoMem_ReadByte(0xff8907));
        !           414:        fprintf(stderr, "$FF8909.b : Frame Count High                      : %02x\n", IoMem_ReadByte(0xff8909));
        !           415:        fprintf(stderr, "$FF890B.b : Frame Count middle                    : %02x\n", IoMem_ReadByte(0xff890b));
        !           416:        fprintf(stderr, "$FF890D.b : Frame Count low                       : %02x\n", IoMem_ReadByte(0xff890d));
        !           417:        fprintf(stderr, "$FF890F.b : Frame End High                        : %02x\n", IoMem_ReadByte(0xff890f));
        !           418:        fprintf(stderr, "$FF8911.b : Frame End middle                      : %02x\n", IoMem_ReadByte(0xff8911));
        !           419:        fprintf(stderr, "$FF8913.b : Frame End low                         : %02x\n", IoMem_ReadByte(0xff8913));
1.1       root      420:        fprintf(stderr, "\n");
1.1.1.2 ! root      421:        fprintf(stderr, "$FF8920.b : Sound Mode Control                    : %02x\n", IoMem_ReadByte(0xff8920));
        !           422:        fprintf(stderr, "$FF8921.b : Sound Mode Control                    : %02x\n", IoMem_ReadByte(0xff8921));
        !           423:        fprintf(stderr, "$FF8930.w : DMA Crossbar Input Select Controller  : %04x\n", IoMem_ReadWord(0xff8930));
        !           424:        fprintf(stderr, "$FF8932.w : DMA Crossbar Output Select Controller : %04x\n", IoMem_ReadWord(0xff8932));
1.1       root      425:        fprintf(stderr, "\n");
1.1.1.2 ! root      426:        fprintf(stderr, "$FF8934.b : External Sync Frequency Divider       : %02x\n", IoMem_ReadByte(0xff8934));
        !           427:        fprintf(stderr, "$FF8935.b : Internal Sync Frequency Divider       : %02x\n", IoMem_ReadByte(0xff8935));
        !           428:        fprintf(stderr, "$FF8936.b : Record Track select                   : %02x\n", IoMem_ReadByte(0xff8936));
        !           429:        fprintf(stderr, "$FF8937.b : Codec Input Source                    : %02x\n", IoMem_ReadByte(0xff8937));
        !           430:        fprintf(stderr, "$FF8938.b : Codec ADC Input                       : %02x\n", IoMem_ReadByte(0xff8938));
        !           431:        fprintf(stderr, "$FF8939.b : Gain Settings Per Channel             : %02x\n", IoMem_ReadByte(0xff8939));
        !           432:        fprintf(stderr, "$FF893A.b : Attenuation Settings Per Channel      : %02x\n", IoMem_ReadByte(0xff893a));
        !           433:        fprintf(stderr, "$FF893C.w : Codec Status                          : %04x\n", IoMem_ReadWord(0xff893c));
        !           434:        fprintf(stderr, "$FF8940.w : GPIO Data Direction                   : %04x\n", IoMem_ReadWord(0xff8940));
        !           435:        fprintf(stderr, "$FF8942.w : GPIO Data                             : %04x\n", IoMem_ReadWord(0xff8942));
1.1       root      436:        fprintf(stderr, "\n");
                    437:        
                    438:        /* DAC connexion */
1.1.1.2 ! root      439:        switch ((IoMem_ReadWord(0xff8932) >> 13) & 0x3) {
        !           440:                case 0 : 
        !           441:                        /* DAC connexion with DMA Playback */
        !           442:                        if ((IoMem_ReadWord(0xff8930) & 0x1) == 1)
        !           443:                                strcpy(matrixDAC, "OOXO");
        !           444:                        else
        !           445:                                strcpy(matrixDAC, "OOHO");
        !           446:                        break;
        !           447:                case 1 :
        !           448:                        /* DAC connexion with DSP Transmit */
        !           449:                        if ((IoMem_ReadWord(0xff8930) & 0x10) == 0x10)
        !           450:                                strcpy(matrixDAC, "OXOO");
        !           451:                        else
        !           452:                                strcpy(matrixDAC, "OHOO");
        !           453:                        break;
        !           454:                case 2 :
        !           455:                        /* DAC connexion with External Input */
        !           456:                        if ((IoMem_ReadWord(0xff8930) & 0x100) == 0x100)
        !           457:                                strcpy(matrixDAC, "XOOO");
        !           458:                        else
        !           459:                                strcpy(matrixDAC, "HOOO");
        !           460:                        break;
        !           461:                case 3 : 
        !           462:                        /* DAC connexion with ADC */
        !           463:                        strcpy(matrixDAC, "OOOX");
        !           464:                        break;
1.1       root      465:        }
1.1.1.2 ! root      466: 
1.1       root      467:        /* DMA connexion */
1.1.1.2 ! root      468:        switch (IoMem_ReadWord(0xff8932) & 0x7) {
        !           469:                case 0 : strcpy(matrixDMA, "OOHO"); break;
        !           470:                case 1 : strcpy(matrixDMA, "OOXO"); break;
        !           471:                case 2 : strcpy(matrixDMA, "OHOO"); break;
        !           472:                case 3 : strcpy(matrixDMA, "OXOO"); break;
        !           473:                case 4 : strcpy(matrixDMA, "HOOO"); break;
        !           474:                case 5 : strcpy(matrixDMA, "XOOO"); break;
        !           475:                case 6 : strcpy(matrixDMA, "OOOH"); break;
        !           476:                case 7 : strcpy(matrixDMA, "OOOX"); break;
1.1       root      477:        }
                    478: 
                    479:        /* DSP connexion */
1.1.1.2 ! root      480:        switch ((IoMem_ReadWord(0xff8932) >> 4) & 0x7) {
        !           481:                case 0 : strcpy(matrixDSP, "OOHO"); break;
        !           482:                case 1 : strcpy(matrixDSP, "OOXO"); break;
        !           483:                case 2 : strcpy(matrixDSP, "OHOO"); break;
        !           484:                case 3 : strcpy(matrixDSP, "OXOO"); break;
        !           485:                case 4 : strcpy(matrixDSP, "HOOO"); break;
        !           486:                case 5 : strcpy(matrixDSP, "XOOO"); break;
        !           487:                case 6 : strcpy(matrixDSP, "OOOH"); break;
        !           488:                case 7 : strcpy(matrixDSP, "OOOX"); break;
1.1       root      489:        }
                    490: 
                    491:        /* External input connexion */
1.1.1.2 ! root      492:        switch ((IoMem_ReadWord(0xff8932) >> 8) & 0x7) {
        !           493:                case 0 : strcpy(matrixEXT, "OOHO"); break;
        !           494:                case 1 : strcpy(matrixEXT, "OOXO"); break;
        !           495:                case 2 : strcpy(matrixEXT, "OHOO"); break;
        !           496:                case 3 : strcpy(matrixEXT, "OXOO"); break;
        !           497:                case 4 : strcpy(matrixEXT, "HOOO"); break;
        !           498:                case 5 : strcpy(matrixEXT, "XOOO"); break;
        !           499:                case 6 : strcpy(matrixEXT, "OOOH"); break;
        !           500:                case 7 : strcpy(matrixEXT, "OOOX"); break;
1.1       root      501:        }
                    502: 
                    503:        if ((IoMem_ReadByte(0xff8935) & 0xf) == 0) {
                    504:                strcpy(frqDSP, "(STe Freq)");
1.1.1.2 ! root      505:                strcpy(frqDMA, "(STe Freq)");
        !           506:                strcpy(frqEXT, "(STe Freq)");
        !           507:                strcpy(frqDAC, "(STe Freq)");
        !           508:        }
        !           509:        else {
        !           510:                /* DSP Clock */
1.1       root      511:                switch ((IoMem_ReadWord(0xff8930) >> 5) & 0x3) {
                    512:                        case 0: strcpy(frqDSP, " (25 Mhz) "); break;
                    513:                        case 1: strcpy(frqDSP, "(External)"); break;
                    514:                        case 2: strcpy(frqDSP, " (32 Mhz) "); break;
1.1.1.2 ! root      515:                        default:  strcpy(frqDSP, "undefined "); break;
1.1       root      516:                }
                    517: 
1.1.1.2 ! root      518:                /* DMA Clock */
1.1       root      519:                switch ((IoMem_ReadWord(0xff8930) >> 1) & 0x3) {
                    520:                        case 0: strcpy(frqDMA, " (25 Mhz) "); break;
                    521:                        case 1: strcpy(frqDMA, "(External)"); break;
                    522:                        case 2: strcpy(frqDMA, " (32 Mhz) "); break;
1.1.1.2 ! root      523:                        default:  strcpy(frqDMA, "undefined "); break;
1.1       root      524:                }
                    525: 
1.1.1.2 ! root      526:                /* External Clock */
1.1       root      527:                switch ((IoMem_ReadWord(0xff8930) >> 9) & 0x3) {
                    528:                        case 0: strcpy(frqEXT, " (25 Mhz) "); break;
                    529:                        case 1: strcpy(frqEXT, "(External)"); break;
                    530:                        case 2: strcpy(frqEXT, " (32 Mhz) "); break;
1.1.1.2 ! root      531:                        default:  strcpy(frqEXT, "undefined "); break;
1.1       root      532:                }
                    533: 
1.1.1.2 ! root      534:                /* DAC Clock */
1.1       root      535:                strcpy(frqDAC, " (25 Mhz) ");
                    536:        }
                    537: 
                    538:        /* data size */
                    539:        switch ((IoMem_ReadByte(0xff8921) >> 6) & 0x3) {
                    540:                case 0: strcpy (dataSize, "8 bits stereo"); break;
                    541:                case 1: strcpy (dataSize, "16 bits stereo"); break;
                    542:                case 2: strcpy (dataSize, "8 bits mono"); break;
                    543:                default: strcpy (dataSize, "undefined"); break;
                    544:        }
                    545: 
1.1.1.2 ! root      546:        /* STE, 25Mhz and 32 Mhz sound frequencies */
        !           547:        if ((IoMem_ReadByte(0xff8935) & 0xf) == 0) {
        !           548:                sprintf(frqSTE, "Ste Freq    : %d Khz", Ste_SampleRates[IoMem_ReadByte(0xff8921) & 0x3]);
        !           549:                strcpy (frq25Mhz, "25 Mhz Freq : - Khz");
        !           550:                strcpy (frq32Mhz, "32 Mzh Freq : - Khz");
        !           551:        }
        !           552:        else {
        !           553:                strcpy (frqSTE, "Ste Freq    : - Khz");
        !           554:                sprintf(frq25Mhz, "25 Mhz Freq : %d Khz", Falcon_SampleRates_25Mhz[(IoMem_ReadByte(0xff8935) & 0xf) - 1]);
        !           555:                sprintf(frq32Mhz, "32 Mzh Freq : %d Khz", Falcon_SampleRates_32Mhz[(IoMem_ReadByte(0xff8935) & 0xf) - 1]);
        !           556:        }
        !           557: 
1.1       root      558:        /* Display the crossbar Matrix */
                    559:        fprintf(stderr, "           INPUT\n");
                    560:        fprintf(stderr, "External Imp  ---%c------%c------%c------%c\n", matrixDAC[0], matrixDMA[0], matrixDSP[0], matrixEXT[0]);
                    561:        fprintf(stderr, "%s       |      |      |      |    O = no connexion\n", frqEXT);
                    562:        fprintf(stderr, "                 |      |      |      |    X = connexion\n");
                    563:        fprintf(stderr, "Dsp Transmit  ---%c------%c------%c------%c    H = Handshake connexion\n", matrixDAC[1], matrixDMA[1], matrixDSP[1], matrixEXT[1]);
                    564:        fprintf(stderr, "%s       |      |      |      |\n", frqDSP);
                    565:        fprintf(stderr, "                 |      |      |      |    %s\n", dataSize);
                    566:        fprintf(stderr, "DMA PlayBack  ---%c------%c------%c------%c\n", matrixDAC[2], matrixDMA[2], matrixDSP[2], matrixEXT[2]);
1.1.1.2 ! root      567:        fprintf(stderr, "%s       |      |      |      |    Sound Freq :\n", frqDMA);
        !           568:        fprintf(stderr, "                 |      |      |      |      %s\n", frqSTE);
        !           569:        fprintf(stderr, "ADC           ---%c------%c------%c------%c      %s\n", matrixDAC[3], matrixDMA[3], matrixDSP[3], matrixEXT[3], frq25Mhz);
        !           570:        fprintf(stderr, "%s       |      |      |      |      %s\n", frqDAC, frq32Mhz);
1.1       root      571:        fprintf(stderr, "                 |      |      |      |\n");
                    572:        fprintf(stderr, "                DAC    DMA    DSP   External     OUTPUT\n");
                    573:        fprintf(stderr, "                     Record  Record   Out\n");
                    574:        fprintf(stderr, "\n");
                    575: }
                    576: 
                    577: 
                    578: /* ------------------------------------------------------------------
                    579:  * CPU and DSP information wrappers
                    580:  */
                    581: 
                    582: /**
                    583:  * Helper to call debugcpu.c and debugdsp.c debugger commands
                    584:  */
                    585: static void DebugInfo_CallCommand(int (*func)(int, char* []), const char *command, Uint32 arg)
                    586: {
                    587:        char cmdbuffer[16], argbuffer[12];
                    588:        char *argv[] = { cmdbuffer, NULL };
                    589:        int argc = 1;
                    590: 
                    591:        assert(strlen(command) < sizeof(cmdbuffer));
                    592:        strcpy(cmdbuffer, command);
                    593:        if (arg) {
                    594:                sprintf(argbuffer, "$%x", arg);
                    595:                argv[argc++] = argbuffer;
                    596:        }
                    597:        func(argc, argv);
                    598: }
                    599: 
                    600: static void DebugInfo_CpuRegister(Uint32 arg)
                    601: {
                    602:        DebugInfo_CallCommand(DebugCpu_Register, "register", arg);
                    603: }
                    604: static void DebugInfo_CpuDisAsm(Uint32 arg)
                    605: {
                    606:        DebugInfo_CallCommand(DebugCpu_DisAsm, "disasm", arg);
                    607: }
                    608: static void DebugInfo_CpuMemDump(Uint32 arg)
                    609: {
                    610:        DebugInfo_CallCommand(DebugCpu_MemDump, "memdump", arg);
                    611: }
                    612: 
                    613: #if ENABLE_DSP_EMU
                    614: 
                    615: static void DebugInfo_DspRegister(Uint32 arg)
                    616: {
                    617:        DebugInfo_CallCommand(DebugDsp_Register, "dspreg", arg);
                    618: }
                    619: static void DebugInfo_DspDisAsm(Uint32 arg)
                    620: {
                    621:        DebugInfo_CallCommand(DebugDsp_DisAsm, "dspdisasm", arg);
                    622: }
                    623: 
                    624: static void DebugInfo_DspMemDump(Uint32 arg)
                    625: {
                    626:        char cmdbuf[] = "dspmemdump";
                    627:        char addrbuf[6], spacebuf[2] = "X";
                    628:        char *argv[] = { cmdbuf, spacebuf, addrbuf };
                    629:        spacebuf[0] = (arg>>16)&0xff;
                    630:        sprintf(addrbuf, "$%x", (Uint16)(arg&0xffff));
                    631:        DebugDsp_MemDump(3, argv);
                    632: }
                    633: 
                    634: /**
                    635:  * Convert arguments to Uint32 arg suitable for DSP memdump callback
                    636:  */
                    637: static Uint32 DebugInfo_DspMemArgs(int argc, char *argv[])
                    638: {
                    639:        Uint32 value;
                    640:        char space;
                    641:        if (argc != 2) {
                    642:                return 0;
                    643:        }
                    644:        space = toupper(argv[0][0]);
                    645:        if ((space != 'X' && space != 'Y' && space != 'P') || argv[0][1]) {
                    646:                fprintf(stderr, "ERROR: invalid DSP address space '%s'!\n", argv[0]);
                    647:                return 0;
                    648:        }
                    649:        if (!Eval_Number(argv[1], &value) || value > 0xffff) {
                    650:                fprintf(stderr, "ERROR: invalid DSP address '%s'!\n", argv[1]);
                    651:                return 0;
                    652:        }
                    653:        return ((Uint32)space<<16) | value;
                    654: }
                    655: 
                    656: #endif  /* ENABLE_DSP_EMU */
                    657: 
                    658: 
                    659: static void DebugInfo_RegAddr(Uint32 arg)
                    660: {
                    661:        bool forDsp;
                    662:        char regname[3];
                    663:        Uint32 *regvalue, mask;
                    664:        char cmdbuf[12], addrbuf[6];
                    665:        char *argv[] = { cmdbuf, addrbuf };
                    666:        
                    667:        regname[0] = (arg>>24)&0xff;
                    668:        regname[1] = (arg>>16)&0xff;
                    669:        regname[2] = '\0';
                    670: 
                    671:        if (DebugCpu_GetRegisterAddress(regname, &regvalue)) {
                    672:                mask = 0xffffffff;
                    673:                forDsp = false;
                    674:        } else {
                    675:                if (!DSP_GetRegisterAddress(regname, &regvalue, &mask)) {
                    676:                        fprintf(stderr, "ERROR: invalid address/data register '%s'!\n", regname);
                    677:                        return;
                    678:                }
                    679:                forDsp = true;
                    680:        }
                    681:                sprintf(addrbuf, "$%x", *regvalue & mask);
                    682: 
                    683:        if ((arg & 0xff) == 'D') {
                    684:                strcpy(cmdbuf, "disasm");
                    685:                if (forDsp) {
                    686: #if ENABLE_DSP_EMU
                    687:                        DebugDsp_DisAsm(2, argv);
                    688: #endif
                    689:                } else {
                    690:                        DebugCpu_DisAsm(2, argv);
                    691:                }
                    692:        } else {
                    693:                strcpy(cmdbuf, "memdump");
                    694:                if (forDsp) {
                    695: #if ENABLE_DSP_EMU
                    696:                        DebugDsp_MemDump(2, argv);
                    697: #endif
                    698:                } else {
                    699:                        DebugCpu_MemDump(2, argv);
                    700:                }
                    701:        }
                    702: }
                    703: 
                    704: /**
                    705:  * Convert arguments to Uint32 arg suitable for RegAddr callback
                    706:  */
                    707: static Uint32 DebugInfo_RegAddrArgs(int argc, char *argv[])
                    708: {
                    709:        Uint32 value, *regaddr;
                    710:        if (argc != 2) {
                    711:                return 0;
                    712:        }
                    713: 
                    714:        if (strcmp(argv[0], "disasm") == 0) {
                    715:                value = 'D';
                    716:        } else if (strcmp(argv[0], "memdump") == 0) {
                    717:                value = 'M';
                    718:        } else {
                    719:                fprintf(stderr, "ERROR: regaddr operation can be only 'disasm' or 'memdump', not '%s'!\n", argv[0]);
                    720:                return 0;
                    721:        }
                    722: 
                    723:        if (strlen(argv[1]) != 2 ||
                    724:            (!DebugCpu_GetRegisterAddress(argv[1], &regaddr) &&
                    725:             (toupper(argv[1][0]) != 'R' || !isdigit(argv[1][1]) || argv[1][2]))) {
                    726:                /* not CPU register or Rx DSP register */
                    727:                fprintf(stderr, "ERROR: invalid address/data register '%s'!\n", argv[1]);
                    728:                return 0;
                    729:        }
                    730:        
                    731:        value |= argv[1][0] << 24;
                    732:        value |= argv[1][1] << 16;
                    733:        value &= 0xffff00ff;
                    734:        return value;
                    735: }
                    736: 
                    737: 
                    738: /* ------------------------------------------------------------------
1.1.1.2 ! root      739:  * wrappers for command to parse debugger input file
        !           740:  */
        !           741: 
        !           742: /* file name to be given before calling the Parse function,
        !           743:  * needs to be set separately as it's a host pointer which
        !           744:  * can be 64-bit i.e. may not fit into Uint32.
        !           745:  */
        !           746: static char *parse_filename;
        !           747: 
        !           748: /**
        !           749:  * Parse and exec commands in the previously given debugger input file
        !           750:  */
        !           751: static void DebugInfo_FileParse(Uint32 dummy)
        !           752: {
        !           753:        if (parse_filename) {
        !           754:                DebugUI_ParseFile(parse_filename);
        !           755:        } else {
        !           756:                fputs("ERROR: debugger input file name to parse isn't set!\n", stderr);
        !           757:        }
        !           758: }
        !           759: 
        !           760: /**
        !           761:  * Set which input file to parse.
        !           762:  * Return true if file exists, false on error
        !           763:  */
        !           764: static Uint32 DebugInfo_FileArgs(int argc, char *argv[])
        !           765: {
        !           766:        if (argc != 1) {
        !           767:                return false;
        !           768:        }
        !           769:        if (!File_Exists(argv[0])) {
        !           770:                fprintf(stderr, "ERROR: given file '%s' doesn't exist!\n", argv[0]);
        !           771:                return false;
        !           772:        }
        !           773:        if (parse_filename) {
        !           774:                free(parse_filename);
        !           775:        }
        !           776:        parse_filename = strdup(argv[0]);
        !           777:        return true;
        !           778: }
        !           779: 
        !           780: 
        !           781: /* ------------------------------------------------------------------
1.1       root      782:  * Debugger & readline TAB completion integration
                    783:  */
                    784: 
                    785: /**
                    786:  * Default information on entering the debugger
                    787:  */
                    788: static void DebugInfo_Default(Uint32 dummy)
                    789: {
                    790:        int hbl, fcycles, lcycles;
                    791:        Video_GetPosition(&fcycles, &hbl, &lcycles);
                    792:        fprintf(stderr, "\nCPU=$%x, VBL=%d, FrameCycles=%d, HBL=%d, LineCycles=%d, DSP=",
                    793:                M68000_GetPC(), nVBLs, fcycles, hbl, lcycles);
                    794:        if (bDspEnabled)
                    795:                fprintf(stderr, "$%x\n", DSP_GetPC());
                    796:        else
                    797:                fprintf(stderr, "N/A\n");
                    798: }
                    799: 
                    800: static const struct {
1.1.1.2 ! root      801:        /* if overlaps with other functionality, list only for lock command */
1.1       root      802:        bool lock;
                    803:        const char *name;
                    804:        void (*func)(Uint32 arg);
                    805:        /* convert args in argv into single Uint32 for func */
                    806:        Uint32 (*args)(int argc, char *argv[]);
                    807:        const char *info;
                    808: } infotable[] = {
1.1.1.2 ! root      809:        { false,"aes",       AES_Info,             NULL, "Show AES vector contents (with <value>, show opcodes)" },
1.1       root      810:        { false,"basepage",  DebugInfo_Basepage,   NULL, "Show program basepage info at given <address>" },
1.1.1.2 ! root      811:        { false,"cookiejar", DebugInfo_Cookiejar,  NULL, "Show TOS Cookiejar contents" },
1.1       root      812:        { false,"crossbar",  DebugInfo_Crossbar,   NULL, "Show Falcon crossbar HW register values" },
                    813:        { true, "default",   DebugInfo_Default,    NULL, "Show default debugger entry information" },
                    814:        { true, "disasm",    DebugInfo_CpuDisAsm,  NULL, "Disasm CPU from PC or given <address>" },
                    815: #if ENABLE_DSP_EMU
                    816:        { true, "dspdisasm", DebugInfo_DspDisAsm,  NULL, "Disasm DSP from given <address>" },
                    817:        { true, "dspmemdump",DebugInfo_DspMemDump, DebugInfo_DspMemArgs, "Dump DSP memory from given <space> <address>" },
1.1.1.2 ! root      818:        { true, "dspregs",   DebugInfo_DspRegister,NULL, "Show DSP registers values" },
1.1       root      819: #endif
1.1.1.2 ! root      820:        { true, "file",      DebugInfo_FileParse, DebugInfo_FileArgs, "Parse commands from given debugger input <file>" },
        !           821:        { false,"gemdos",    GemDOS_Info,          NULL, "Show GEMDOS HDD emu info (with <value>, show opcodes)" },
1.1       root      822:        { true, "memdump",   DebugInfo_CpuMemDump, NULL, "Dump CPU memory from given <address>" },
                    823:        { false,"osheader",  DebugInfo_OSHeader,   NULL, "Show TOS OS header information" },
                    824:        { true, "regaddr",   DebugInfo_RegAddr, DebugInfo_RegAddrArgs, "Show <disasm|memdump> from CPU/DSP address pointed by <register>" },
1.1.1.2 ! root      825:        { true, "registers", DebugInfo_CpuRegister,NULL, "Show CPU registers values" },
        !           826:        { false,"vdi",       VDI_Info,             NULL, "Show VDI vector contents (with <value>, show opcodes)" },
        !           827:        { false,"videl",     DebugInfo_Videl,      NULL, "Show Falcon Videl HW registers values" },
        !           828:        { false,"video",     DebugInfo_Video,      NULL, "Show Video related values" }
1.1       root      829: };
                    830: 
1.1.1.2 ! root      831: static int LockedFunction = 4; /* index for the "default" function */
1.1       root      832: static Uint32 LockedArgument;
                    833: 
                    834: /**
                    835:  * Show selected debugger session information
                    836:  * (when debugger is (again) entered)
                    837:  */
                    838: void DebugInfo_ShowSessionInfo(void)
                    839: {
                    840:        infotable[LockedFunction].func(LockedArgument);
                    841: }
                    842: 
                    843: 
                    844: /**
                    845:  * Readline match callback for info subcommand name completion.
                    846:  * STATE = 0 -> different text from previous one.
                    847:  * Return next match or NULL if no matches.
                    848:  */
                    849: static char *DebugInfo_Match(const char *text, int state, bool lock)
                    850: {
                    851:        static int i, len;
                    852:        const char *name;
                    853:        
                    854:        if (!state) {
                    855:                /* first match */
                    856:                len = strlen(text);
                    857:                i = 0;
                    858:        }
                    859:        /* next match */
                    860:        while (i++ < ARRAYSIZE(infotable)) {
                    861:                if (!lock && infotable[i-1].lock) {
                    862:                        continue;
                    863:                }
                    864:                name = infotable[i-1].name;
                    865:                if (strncmp(name, text, len) == 0)
                    866:                        return (strdup(name));
                    867:        }
                    868:        return NULL;
                    869: }
                    870: char *DebugInfo_MatchLock(const char *text, int state)
                    871: {
                    872:        return DebugInfo_Match(text, state, true);
                    873: }
                    874: char *DebugInfo_MatchInfo(const char *text, int state)
                    875: {
                    876:        return DebugInfo_Match(text, state, false);
                    877: }
                    878: 
                    879: 
                    880: /**
                    881:  * Show requested command information.
                    882:  */
                    883: int DebugInfo_Command(int nArgc, char *psArgs[])
                    884: {
                    885:        Uint32 value;
                    886:        const char *cmd;
                    887:        bool ok, lock;
                    888:        int i, sub;
                    889: 
                    890:        sub = -1;
                    891:        if (nArgc > 1) {
                    892:                cmd = psArgs[1];                
                    893:                /* which subcommand? */
                    894:                for (i = 0; i < ARRAYSIZE(infotable); i++) {
                    895:                        if (strcmp(cmd, infotable[i].name) == 0) {
                    896:                                sub = i;
                    897:                                break;
                    898:                        }
                    899:                }
                    900:        }
                    901: 
                    902:        if (infotable[sub].args) {
                    903:                /* value needs callback specific conversion */
                    904:                value = infotable[sub].args(nArgc-2, psArgs+2);
                    905:                ok = !!value;
                    906:        } else {
                    907:                if (nArgc > 2) {
                    908:                        /* value is normal number */
                    909:                        ok = Eval_Number(psArgs[2], &value);
                    910:                } else {
                    911:                        value = 0;
                    912:                        ok = true;
                    913:                }
                    914:        }
                    915: 
                    916:        lock = (strcmp(psArgs[0], "lock") == 0);
                    917:        
                    918:        if (sub < 0 || !ok) {
                    919:                /* no subcommand or something wrong with value, show info */
                    920:                fprintf(stderr, "%s subcommands are:\n", psArgs[0]);
                    921:                for (i = 0; i < ARRAYSIZE(infotable); i++) {
                    922:                        if (!lock && infotable[i].lock) {
                    923:                                continue;
                    924:                        }
                    925:                        fprintf(stderr, "- %s: %s\n",
                    926:                                infotable[i].name, infotable[i].info);
                    927:                }
                    928:                return DEBUGGER_CMDDONE;
                    929:        }
                    930: 
                    931:        if (lock) {
                    932:                /* lock given subcommand and value */
                    933:                LockedFunction = sub;
                    934:                LockedArgument = value;
                    935:                fprintf(stderr, "Locked %s output.\n", psArgs[1]);
                    936:        } else {
                    937:                /* do actual work */
                    938:                infotable[sub].func(value);
                    939:        }
                    940:        return DEBUGGER_CMDDONE;
                    941: }

unix.superglobalmegacorp.com

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