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

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

unix.superglobalmegacorp.com

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