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

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"
                     22: #include "ioMem.h"
                     23: #include "m68000.h"
                     24: #include "stMemory.h"
                     25: #include "tos.h"
                     26: #include "video.h"
                     27: 
                     28: 
                     29: /* ------------------------------------------------------------------
                     30:  * TOS information
                     31:  */
                     32: #define OS_SYSBASE 0x4F2
                     33: #define OS_HEADER_SIZE 0x30
                     34: 
                     35: #define COOKIE_JAR 0x5A0
                     36: 
                     37: #define BASEPAGE_SIZE 0x100
                     38: 
                     39: #define GEM_MAGIC 0x87654321
                     40: #define GEM_MUPB_SIZE 0xC
                     41: 
                     42: #define RESET_MAGIC 0x31415926
                     43: #define RESET_VALID 0x426
                     44: #define RESET_VECTOR 0x42A
                     45: 
                     46: #define COUNTRY_SPAIN 4
                     47: 
                     48: /**
                     49:  * DebugInfo_GetSysbase: set osversion to given argument.
                     50:  * return sysbase address on success and zero on failure.
                     51:  */
                     52: static Uint32 DebugInfo_GetSysbase(Uint16 *osversion)
                     53: {
                     54:        Uint32 sysbase = STMemory_ReadLong(OS_SYSBASE);
                     55: 
                     56:        if (!STMemory_ValidArea(sysbase, OS_HEADER_SIZE)) {
                     57:                fprintf(stderr, "Invalid TOS base address!\n");
                     58:                return 0;
                     59:        }
                     60:        if (sysbase != TosAddress || sysbase != STMemory_ReadLong(sysbase+0x08)) {
                     61:                fprintf(stderr, "Sysbase and os_beg address in OS header mismatch!\n");
                     62:                return 0;
                     63:        }
                     64:        *osversion = STMemory_ReadWord(sysbase+0x02);
                     65:        return sysbase;
                     66: }
                     67: 
                     68: /**
                     69:  * DebugInfo_CurrentBasepage: get currently running TOS program basepage
                     70:  */
                     71: static Uint32 DebugInfo_CurrentBasepage(void)
                     72: {
                     73:        Uint32 basepage, sysbase;
                     74:        Uint16 osversion, osconf;
                     75: 
                     76:        sysbase = DebugInfo_GetSysbase(&osversion);
                     77:        if (!sysbase) {
                     78:                return 0;
                     79:        }
                     80:        if (osversion >= 0x0102) {
                     81:                basepage = STMemory_ReadLong(sysbase+0x28);
                     82:        } else {
                     83:                osconf = STMemory_ReadWord(sysbase+0x1C);
                     84:                if((osconf>>1) == COUNTRY_SPAIN) {
                     85:                        basepage = 0x873C;
                     86:                } else {
                     87:                        basepage = 0x602C;
                     88:                }
                     89:        }
                     90:        if (STMemory_ValidArea(basepage, 4)) {
                     91:                return STMemory_ReadLong(basepage);
                     92:        }
                     93:        fprintf(stderr, "Pointer 0x%06x to basepage address is invalid!\n", basepage);
                     94:        return 0;
                     95: }
                     96: 
                     97: /**
                     98:  * DebugInfo_Basepage: show TOS process basepage information
                     99:  * at given address.
                    100:  */
                    101: static void DebugInfo_Basepage(Uint32 basepage)
                    102: {
                    103:        Uint8 cmdlen;
                    104:        Uint32 env;
                    105: 
                    106:        if (!basepage) {
                    107:                /* default to current process basepage */
                    108:                basepage = DebugInfo_CurrentBasepage();
                    109:                if (!basepage) {
                    110:                        return;
                    111:                }
                    112:        }
                    113:        fprintf(stderr, "Process basepage information:\n");
                    114:        if (!STMemory_ValidArea(basepage, BASEPAGE_SIZE) ||
                    115:            STMemory_ReadLong(basepage) != basepage) {
                    116:                fprintf(stderr, "- address 0x%06x is invalid!\n", basepage);
                    117:                return;
                    118:        }
                    119:        fprintf(stderr, "- TPA start      : 0x%06x\n", STMemory_ReadLong(basepage));
                    120:        fprintf(stderr, "- TPA end +1     : 0x%06x\n", STMemory_ReadLong(basepage+0x04));
                    121:        fprintf(stderr, "- Text segment   : 0x%06x\n", STMemory_ReadLong(basepage+0x08));
                    122:        fprintf(stderr, "- Text size      : 0x%x\n",   STMemory_ReadLong(basepage+0x0C));
                    123:        fprintf(stderr, "- Data segment   : 0x%06x\n", STMemory_ReadLong(basepage+0x10));
                    124:        fprintf(stderr, "- Data size      : 0x%x\n",   STMemory_ReadLong(basepage+0x14));
                    125:        fprintf(stderr, "- BSS segment    : 0x%06x\n", STMemory_ReadLong(basepage+0x18));
                    126:        fprintf(stderr, "- BSS size       : 0x%x\n",   STMemory_ReadLong(basepage+0x1C));
                    127:        fprintf(stderr, "- Process DTA    : 0x%06x\n", STMemory_ReadLong(basepage+0x20));
                    128:        fprintf(stderr, "- Parent basepage: 0x%06x\n", STMemory_ReadLong(basepage+0x24));
                    129: 
                    130:        env = STMemory_ReadLong(basepage+0x2C);
                    131:        fprintf(stderr, "- Environment    : 0x%06x\n", env);
                    132:        if (STMemory_ValidArea(env, 4096)) {
                    133:                Uint32 end = env + 4096;
                    134:                while (env < end && *(STRam+env)) {
                    135:                        fprintf(stderr, "'%s'\n", STRam+env);
                    136:                        env += strlen((const char *)(STRam+env)) + 1;
                    137:                }
                    138:        }
                    139:        cmdlen = STMemory_ReadByte(basepage+0x80);
                    140:        fprintf(stderr, "- Command argslen: %d\n", cmdlen);
                    141:        if (cmdlen) {
                    142:                int offset = 0;
                    143:                while (offset < cmdlen) {
                    144:                        fprintf(stderr, " '%s'", STRam+basepage+0x81+offset);
                    145:                        offset += strlen((const char *)(STRam+basepage+0x81+offset)) + 1;
                    146:                }
                    147:                fprintf(stderr, "\n");
                    148:        }
                    149: }
                    150: 
                    151: /**
                    152:  * DebugInfo_OSHeader: display TOS OS Header
                    153:  */
                    154: static void DebugInfo_OSHeader(Uint32 dummy)
                    155: {
                    156:        Uint32 sysbase, gemblock, basepage;
                    157:        Uint16 osversion, osconf;
                    158: 
                    159:        sysbase = DebugInfo_GetSysbase(&osversion);
                    160:        if (!sysbase) {
                    161:                return;
                    162:        }
                    163:        fprintf(stderr, "OS base addr : 0x%06x\n", sysbase);
                    164:        fprintf(stderr, "OS RAM end+1 : 0x%06x\n", STMemory_ReadLong(sysbase+0x0C));
                    165:        fprintf(stderr, "TOS version  : 0x%x\n", osversion);
                    166: 
                    167:        fprintf(stderr, "Reset handler: 0x%06x\n", STMemory_ReadLong(sysbase+0x04));
                    168:        fprintf(stderr, "Reset vector : 0x%06x\n", STMemory_ReadLong(RESET_VECTOR));
                    169:        fprintf(stderr, "Reset valid  : 0x%x (valid=0x%x)\n", STMemory_ReadLong(RESET_VALID), RESET_MAGIC);
                    170: 
                    171:        gemblock = STMemory_ReadLong(sysbase+0x14);
                    172:        fprintf(stderr, "GEM Memory Usage Parameter Block:\n");
                    173:        if (STMemory_ValidArea(gemblock, GEM_MUPB_SIZE)) {
                    174:                fprintf(stderr, "- Block addr : 0x%06x\n", gemblock);
                    175:                fprintf(stderr, "- GEM magic  : 0x%x (valid=0x%x)\n", STMemory_ReadLong(gemblock), GEM_MAGIC);
                    176:                fprintf(stderr, "- GEM entry  : 0x%06x\n", STMemory_ReadLong(gemblock+4));
                    177:                fprintf(stderr, "- GEM end    : 0x%06x\n", STMemory_ReadLong(gemblock+8));
                    178:        } else {
                    179:                fprintf(stderr, "- is at INVALID 0x%06x address.\n", gemblock);
                    180:        }
                    181: 
                    182:        fprintf(stderr, "OS date      : 0x%x\n", STMemory_ReadLong(sysbase+0x14));
                    183:        fprintf(stderr, "OS DOS date  : 0x%x\n", STMemory_ReadLong(sysbase+0x1E));
                    184: 
                    185:        osconf = STMemory_ReadWord(sysbase+0x1C);
                    186:        fprintf(stderr, "OS Conf bits : lang=%d, %s\n", osconf>>1, osconf&1 ? "PAL":"NTSC");
                    187:        fprintf(stderr, "Cookie Jar   : 0x%06x\n", STMemory_ReadLong(COOKIE_JAR));
                    188: 
                    189:        /* last 3 OS header fields are only available as of TOS 1.02 */
                    190:        if (osversion >= 0x0102) {
                    191:                fprintf(stderr, "Memory pool  : 0x%06x\n", STMemory_ReadLong(sysbase+0x20));
                    192:                fprintf(stderr, "Kbshift addr : 0x%06x\n", STMemory_ReadLong(sysbase+0x24));
                    193:        } else {
                    194:                /* TODO: GEMDOS memory pool address for TOS 1.0? */
                    195:                fprintf(stderr, "Kbshift addr : 0x000E1B\n");
                    196:        }
                    197:        basepage = DebugInfo_CurrentBasepage();
                    198:        if (basepage) {
                    199:                fprintf(stderr, "Basepage     : 0x%06x\n", basepage);
                    200:        }
                    201: }
                    202: 
                    203: 
                    204: /* ------------------------------------------------------------------
                    205:  * Falcon HW information
                    206:  */
                    207: 
                    208: /**
                    209:  * DebugInfo_Videl : display the Videl registers values.
                    210:  */
                    211: static void DebugInfo_Videl(Uint32 dummy)
                    212: {
                    213:        if (ConfigureParams.System.nMachineType != MACHINE_FALCON) {
                    214:                fprintf(stderr, "Not Falcon - no Videl!\n");
                    215:                return;
                    216:        }
                    217: 
                    218:        fprintf(stderr, "$FF8006 : monitor type                     : %02x\n", IoMem_ReadByte(0xff8006));
                    219:        fprintf(stderr, "$FF820E : offset to next line              : %04x\n", IoMem_ReadWord(0xff820e));
                    220:        fprintf(stderr, "$FF8210 : VWRAP - line width               : %04x\n", IoMem_ReadWord(0xff8210));
                    221:        fprintf(stderr, "$FF8260 : ST shift mode                    : %02x\n", IoMem_ReadByte(0xff8260));
                    222:        fprintf(stderr, "$FF8265 : Horizontal scroll register       : %02x\n", IoMem_ReadByte(0xff8265));
                    223:        fprintf(stderr, "$FF8266 : Falcon shift mode                : %04x\n", IoMem_ReadWord(0xff8266));
                    224:        fprintf(stderr, "\n");
                    225:        fprintf(stderr, "$FF8280 : HHC - Horizontal Hold Counter    : %04x\n", IoMem_ReadWord(0xff8280));
                    226:        fprintf(stderr, "$FF8282 : HHT - Horizontal Hold Timer      : %04x\n", IoMem_ReadWord(0xff8282));
                    227:        fprintf(stderr, "$FF8284 : HBB - Horizontal Border Begin    : %04x\n", IoMem_ReadWord(0xff8284));
                    228:        fprintf(stderr, "$FF8286 : HBE - Horizontal Border End      : %04x\n", IoMem_ReadWord(0xff8286));
                    229:        fprintf(stderr, "$FF8288 : HDB - Horizontal Display Begin   : %04x\n", IoMem_ReadWord(0xff8288));
                    230:        fprintf(stderr, "$FF828A : HDE - Horizontal Display End     : %04x\n", IoMem_ReadWord(0xff828a));
                    231:        fprintf(stderr, "$FF828C : HSS - Horizontal SS              : %04x\n", IoMem_ReadWord(0xff828c));
                    232:        fprintf(stderr, "$FF828E : HFS - Horizontal FS              : %04x\n", IoMem_ReadWord(0xff828e));
                    233:        fprintf(stderr, "$FF8290 : HEE - Horizontal EE              : %04x\n", IoMem_ReadWord(0xff8290));
                    234:        fprintf(stderr, "\n");
                    235:        fprintf(stderr, "$FF82A0 : VFC - Vertical Frequency Counter : %04x\n", IoMem_ReadWord(0xff82a0));
                    236:        fprintf(stderr, "$FF82A2 : VFT - Vertical Frequency Timer   : %04x\n", IoMem_ReadWord(0xff82a2));
                    237:        fprintf(stderr, "$FF82A4 : VBB - Vertical Border Begin      : %04x\n", IoMem_ReadWord(0xff82a4));
                    238:        fprintf(stderr, "$FF82A6 : VBE - Vertical Border End        : %04x\n", IoMem_ReadWord(0xff82a6));
                    239:        fprintf(stderr, "$FF82A8 : VDB - Vertical Display Begin     : %04x\n", IoMem_ReadWord(0xff82a8));
                    240:        fprintf(stderr, "$FF82AA : VDE - Vertical Display End       : %04x\n", IoMem_ReadWord(0xff82aa));
                    241:        fprintf(stderr, "$FF82AC : VSS - Vertical SS                : %04x\n", IoMem_ReadWord(0xff82ac));
                    242:        fprintf(stderr, "\n");
                    243:        fprintf(stderr, "$FF82C0 : VCO - Video control              : %04x\n", IoMem_ReadWord(0xff82c0));
                    244:        fprintf(stderr, "$FF82C2 : VMD - Video mode                 : %04x\n", IoMem_ReadWord(0xff82c2));
                    245:        fprintf(stderr, "\n");
                    246: }
                    247: 
                    248: /**
                    249:  * DebugInfo_Crossbar : display the Crossbar registers values.
                    250:  */
                    251: static void DebugInfo_Crossbar(Uint32 dummy)
                    252: {
                    253:        char matrixDMA[5], matrixDAC[5], matrixDSP[5], matrixEXT[5];
                    254:        char frqDMA[11], frqDAC[11], frqDSP[11], frqEXT[11];
                    255:        char dataSize[15];
                    256:        
                    257:        if (ConfigureParams.System.nMachineType != MACHINE_FALCON) {
                    258:                fprintf(stderr, "Not Falcon - no Crossbar!\n");
                    259:                return;
                    260:        }
                    261: 
                    262:        fprintf(stderr, "$FF8900 : Sound DMA control                     : %02x\n", IoMem_ReadByte(0xff8900));
                    263:        fprintf(stderr, "$FF8901 : Sound DMA control                     : %02x\n", IoMem_ReadByte(0xff8901));
                    264:        fprintf(stderr, "$FF8903 : Frame Start High                      : %02x\n", IoMem_ReadByte(0xff8903));
                    265:        fprintf(stderr, "$FF8905 : Frame Start middle                    : %02x\n", IoMem_ReadByte(0xff8905));
                    266:        fprintf(stderr, "$FF8907 : Frame Start low                       : %02x\n", IoMem_ReadByte(0xff8907));
                    267:        fprintf(stderr, "$FF8909 : Frame Count High                      : %02x\n", IoMem_ReadByte(0xff8909));
                    268:        fprintf(stderr, "$FF890B : Frame Count middle                    : %02x\n", IoMem_ReadByte(0xff890b));
                    269:        fprintf(stderr, "$FF890D : Frame Count low                       : %02x\n", IoMem_ReadByte(0xff890d));
                    270:        fprintf(stderr, "$FF890f : Frame End High                        : %02x\n", IoMem_ReadByte(0xff890f));
                    271:        fprintf(stderr, "$FF8911 : Frame End middle                      : %02x\n", IoMem_ReadByte(0xff8911));
                    272:        fprintf(stderr, "$FF8913 : Frame End low                         : %02x\n", IoMem_ReadByte(0xff8913));
                    273:        fprintf(stderr, "\n");
                    274:        fprintf(stderr, "$FF8920 : Sound Mode Control                    : %02x\n", IoMem_ReadByte(0xff8920));
                    275:        fprintf(stderr, "$FF8921 : Sound Mode Control                    : %02x\n", IoMem_ReadByte(0xff8921));
                    276:        fprintf(stderr, "$FF8930 : DMA Crossbar Input Select Controller  : %04x\n", IoMem_ReadWord(0xff8930));
                    277:        fprintf(stderr, "$FF8932 : DMA Crossbar Output Select Controller : %04x\n", IoMem_ReadWord(0xff8932));
                    278:        fprintf(stderr, "\n");
                    279:        fprintf(stderr, "$FF8934 : External Sync Frequency Divider       : %02x\n", IoMem_ReadByte(0xff8934));
                    280:        fprintf(stderr, "$FF8935 : Internal Sync Frequency Divider       : %02x\n", IoMem_ReadByte(0xff8935));
                    281:        fprintf(stderr, "$FF8936 : Record Track select                   : %02x\n", IoMem_ReadByte(0xff8936));
                    282:        fprintf(stderr, "$FF8937 : Codec Input Source                    : %02x\n", IoMem_ReadByte(0xff8937));
                    283:        fprintf(stderr, "$FF8938 : Codec ADC Input                       : %02x\n", IoMem_ReadByte(0xff8938));
                    284:        fprintf(stderr, "$FF8939 : Gain Settings Per Channel             : %02x\n", IoMem_ReadByte(0xff8939));
                    285:        fprintf(stderr, "$FF893A : Attenuation Settings Per Channel      : %02x\n", IoMem_ReadByte(0xff893a));
                    286:        fprintf(stderr, "$FF893C : Codec Status                          : %04x\n", IoMem_ReadWord(0xff893c));
                    287:        fprintf(stderr, "$FF8940 : GPIO Data Direction                   : %04x\n", IoMem_ReadWord(0xff8940));
                    288:        fprintf(stderr, "$FF8942 : GPIO Data                             : %04x\n", IoMem_ReadWord(0xff8942));
                    289:        fprintf(stderr, "\n");
                    290:        
                    291:        /* DAC connexion */
                    292:        switch ((IoMem_ReadWord(0xff8932) >> 13) & 3) {
                    293:                case 0 : strcpy(matrixDAC, "OOXO"); break;
                    294:                case 1 : strcpy(matrixDAC, "OXOO"); break;
                    295:                case 2 : strcpy(matrixDAC, "XOOO"); break;
                    296:                case 3 : strcpy(matrixDAC, "OOOX"); break;
                    297:        }
                    298:                
                    299:        /* DMA connexion */
                    300:        switch ((IoMem_ReadWord(0xff8932) >> 1) & 3) {
                    301:                case 0 : strcpy(matrixDMA, "OOXO"); break;
                    302:                case 1 : strcpy(matrixDMA, "OXOO"); break;
                    303:                case 2 : strcpy(matrixDMA, "XOOO"); break;
                    304:                case 3 : strcpy(matrixDMA, "OOOX"); break;
                    305:        }
                    306: 
                    307:        /* DSP connexion */
                    308:        switch ((IoMem_ReadWord(0xff8932) >> 5) & 3) {
                    309:                case 0 : strcpy(matrixDSP, "OOXO"); break;
                    310:                case 1 : strcpy(matrixDSP, "OXOO"); break;
                    311:                case 2 : strcpy(matrixDSP, "XOOO"); break;
                    312:                case 3 : strcpy(matrixDSP, "OOOX"); break;
                    313:        }
                    314: 
                    315:        /* External input connexion */
                    316:        switch ((IoMem_ReadWord(0xff8932) >> 9) & 3) {
                    317:                case 0 : strcpy(matrixEXT, "OOXO"); break;
                    318:                case 1 : strcpy(matrixEXT, "OXOO"); break;
                    319:                case 2 : strcpy(matrixEXT, "XOOO"); break;
                    320:                case 3 : strcpy(matrixEXT, "OOOX"); break;
                    321:        }
                    322: 
                    323:        /* HandShake mode test */
                    324:        if ((IoMem_ReadWord(0xff8932) & 7) == 2) {
                    325:                matrixDMA[1] = 'H';
                    326:        }
                    327: 
                    328:        /* HandShake mode test */
                    329:        if ((IoMem_ReadWord(0xff8932) & 0xf) == 2) {
                    330:                matrixDSP[2] = 'H';
                    331:        }
                    332: 
                    333:        /* DSP Frequency */
                    334:        if ((IoMem_ReadByte(0xff8935) & 0xf) == 0) {
                    335:                strcpy(frqDSP, "(STe Freq)");
                    336:        }else {
                    337:                switch ((IoMem_ReadWord(0xff8930) >> 5) & 0x3) {
                    338:                        case 0: strcpy(frqDSP, " (25 Mhz) "); break;
                    339:                        case 1: strcpy(frqDSP, "(External)"); break;
                    340:                        case 2: strcpy(frqDSP, " (32 Mhz) "); break;
                    341:                        default:  strcpy(frqDSP, "undefined "); break;break;
                    342:                }
                    343:        }
                    344: 
                    345:        /* DMA Frequency */
                    346:        if ((IoMem_ReadByte(0xff8935) & 0xf) == 0) {
                    347:                strcpy(frqDMA, "(STe Freq)");
                    348:        }else {
                    349:                switch ((IoMem_ReadWord(0xff8930) >> 1) & 0x3) {
                    350:                        case 0: strcpy(frqDMA, " (25 Mhz) "); break;
                    351:                        case 1: strcpy(frqDMA, "(External)"); break;
                    352:                        case 2: strcpy(frqDMA, " (32 Mhz) "); break;
                    353:                        default:  strcpy(frqDMA, "undefined "); break;break;
                    354:                }
                    355:        }
                    356: 
                    357:        /* External Frequency */
                    358:        if ((IoMem_ReadByte(0xff8935) & 0xf) == 0) {
                    359:                strcpy(frqEXT, "(STe Freq)");
                    360:        }else {
                    361:                switch ((IoMem_ReadWord(0xff8930) >> 9) & 0x3) {
                    362:                        case 0: strcpy(frqEXT, " (25 Mhz) "); break;
                    363:                        case 1: strcpy(frqEXT, "(External)"); break;
                    364:                        case 2: strcpy(frqEXT, " (32 Mhz) "); break;
                    365:                        default:  strcpy(frqEXT, "undefined "); break;break;
                    366:                }
                    367:        }
                    368: 
                    369:        /* DAC Frequency */
                    370:        if ((IoMem_ReadByte(0xff8935) & 0xf) == 0) {
                    371:                strcpy(frqDAC, "(STe Freq)");
                    372:        }else {
                    373:                strcpy(frqDAC, " (25 Mhz) ");
                    374:        }
                    375: 
                    376:        /* data size */
                    377:        switch ((IoMem_ReadByte(0xff8921) >> 6) & 0x3) {
                    378:                case 0: strcpy (dataSize, "8 bits stereo"); break;
                    379:                case 1: strcpy (dataSize, "16 bits stereo"); break;
                    380:                case 2: strcpy (dataSize, "8 bits mono"); break;
                    381:                default: strcpy (dataSize, "undefined"); break;
                    382:        }
                    383: 
                    384:        /* Display the crossbar Matrix */
                    385:        fprintf(stderr, "           INPUT\n");
                    386:        fprintf(stderr, "External Imp  ---%c------%c------%c------%c\n", matrixDAC[0], matrixDMA[0], matrixDSP[0], matrixEXT[0]);
                    387:        fprintf(stderr, "%s       |      |      |      |    O = no connexion\n", frqEXT);
                    388:        fprintf(stderr, "                 |      |      |      |    X = connexion\n");
                    389:        fprintf(stderr, "Dsp Transmit  ---%c------%c------%c------%c    H = Handshake connexion\n", matrixDAC[1], matrixDMA[1], matrixDSP[1], matrixEXT[1]);
                    390:        fprintf(stderr, "%s       |      |      |      |\n", frqDSP);
                    391:        fprintf(stderr, "                 |      |      |      |    %s\n", dataSize);
                    392:        fprintf(stderr, "DMA PlayBack  ---%c------%c------%c------%c\n", matrixDAC[2], matrixDMA[2], matrixDSP[2], matrixEXT[2]);
                    393:        fprintf(stderr, "%s       |      |      |      |\n", frqDMA);
                    394:        fprintf(stderr, "                 |      |      |      |\n");
                    395:        fprintf(stderr, "ADC           ---%c------%c------%c------%c\n", matrixDAC[3], matrixDMA[3], matrixDSP[3], matrixEXT[3]);
                    396:        fprintf(stderr, "%s       |      |      |      |\n", frqDAC);
                    397:        fprintf(stderr, "                DAC    DMA    DSP   External     OUTPUT\n");
                    398:        fprintf(stderr, "                     Record  Record   Out\n");
                    399:        fprintf(stderr, "\n");
                    400: }
                    401: 
                    402: 
                    403: /* ------------------------------------------------------------------
                    404:  * CPU and DSP information wrappers
                    405:  */
                    406: 
                    407: /**
                    408:  * Helper to call debugcpu.c and debugdsp.c debugger commands
                    409:  */
                    410: static void DebugInfo_CallCommand(int (*func)(int, char* []), const char *command, Uint32 arg)
                    411: {
                    412:        char cmdbuffer[16], argbuffer[12];
                    413:        char *argv[] = { cmdbuffer, NULL };
                    414:        int argc = 1;
                    415: 
                    416:        assert(strlen(command) < sizeof(cmdbuffer));
                    417:        strcpy(cmdbuffer, command);
                    418:        if (arg) {
                    419:                sprintf(argbuffer, "$%x", arg);
                    420:                argv[argc++] = argbuffer;
                    421:        }
                    422:        func(argc, argv);
                    423: }
                    424: 
                    425: static void DebugInfo_CpuRegister(Uint32 arg)
                    426: {
                    427:        DebugInfo_CallCommand(DebugCpu_Register, "register", arg);
                    428: }
                    429: static void DebugInfo_CpuDisAsm(Uint32 arg)
                    430: {
                    431:        DebugInfo_CallCommand(DebugCpu_DisAsm, "disasm", arg);
                    432: }
                    433: static void DebugInfo_CpuMemDump(Uint32 arg)
                    434: {
                    435:        DebugInfo_CallCommand(DebugCpu_MemDump, "memdump", arg);
                    436: }
                    437: 
                    438: #if ENABLE_DSP_EMU
                    439: 
                    440: static void DebugInfo_DspRegister(Uint32 arg)
                    441: {
                    442:        DebugInfo_CallCommand(DebugDsp_Register, "dspreg", arg);
                    443: }
                    444: static void DebugInfo_DspDisAsm(Uint32 arg)
                    445: {
                    446:        DebugInfo_CallCommand(DebugDsp_DisAsm, "dspdisasm", arg);
                    447: }
                    448: 
                    449: static void DebugInfo_DspMemDump(Uint32 arg)
                    450: {
                    451:        char cmdbuf[] = "dspmemdump";
                    452:        char addrbuf[6], spacebuf[2] = "X";
                    453:        char *argv[] = { cmdbuf, spacebuf, addrbuf };
                    454:        spacebuf[0] = (arg>>16)&0xff;
                    455:        sprintf(addrbuf, "$%x", (Uint16)(arg&0xffff));
                    456:        DebugDsp_MemDump(3, argv);
                    457: }
                    458: 
                    459: /**
                    460:  * Convert arguments to Uint32 arg suitable for DSP memdump callback
                    461:  */
                    462: static Uint32 DebugInfo_DspMemArgs(int argc, char *argv[])
                    463: {
                    464:        Uint32 value;
                    465:        char space;
                    466:        if (argc != 2) {
                    467:                return 0;
                    468:        }
                    469:        space = toupper(argv[0][0]);
                    470:        if ((space != 'X' && space != 'Y' && space != 'P') || argv[0][1]) {
                    471:                fprintf(stderr, "ERROR: invalid DSP address space '%s'!\n", argv[0]);
                    472:                return 0;
                    473:        }
                    474:        if (!Eval_Number(argv[1], &value) || value > 0xffff) {
                    475:                fprintf(stderr, "ERROR: invalid DSP address '%s'!\n", argv[1]);
                    476:                return 0;
                    477:        }
                    478:        return ((Uint32)space<<16) | value;
                    479: }
                    480: 
                    481: #endif  /* ENABLE_DSP_EMU */
                    482: 
                    483: 
                    484: static void DebugInfo_RegAddr(Uint32 arg)
                    485: {
                    486:        bool forDsp;
                    487:        char regname[3];
                    488:        Uint32 *regvalue, mask;
                    489:        char cmdbuf[12], addrbuf[6];
                    490:        char *argv[] = { cmdbuf, addrbuf };
                    491:        
                    492:        regname[0] = (arg>>24)&0xff;
                    493:        regname[1] = (arg>>16)&0xff;
                    494:        regname[2] = '\0';
                    495: 
                    496:        if (DebugCpu_GetRegisterAddress(regname, &regvalue)) {
                    497:                mask = 0xffffffff;
                    498:                forDsp = false;
                    499:        } else {
                    500:                if (!DSP_GetRegisterAddress(regname, &regvalue, &mask)) {
                    501:                        fprintf(stderr, "ERROR: invalid address/data register '%s'!\n", regname);
                    502:                        return;
                    503:                }
                    504:                forDsp = true;
                    505:        }
                    506:                sprintf(addrbuf, "$%x", *regvalue & mask);
                    507: 
                    508:        if ((arg & 0xff) == 'D') {
                    509:                strcpy(cmdbuf, "disasm");
                    510:                if (forDsp) {
                    511: #if ENABLE_DSP_EMU
                    512:                        DebugDsp_DisAsm(2, argv);
                    513: #endif
                    514:                } else {
                    515:                        DebugCpu_DisAsm(2, argv);
                    516:                }
                    517:        } else {
                    518:                strcpy(cmdbuf, "memdump");
                    519:                if (forDsp) {
                    520: #if ENABLE_DSP_EMU
                    521:                        DebugDsp_MemDump(2, argv);
                    522: #endif
                    523:                } else {
                    524:                        DebugCpu_MemDump(2, argv);
                    525:                }
                    526:        }
                    527: }
                    528: 
                    529: /**
                    530:  * Convert arguments to Uint32 arg suitable for RegAddr callback
                    531:  */
                    532: static Uint32 DebugInfo_RegAddrArgs(int argc, char *argv[])
                    533: {
                    534:        Uint32 value, *regaddr;
                    535:        if (argc != 2) {
                    536:                return 0;
                    537:        }
                    538: 
                    539:        if (strcmp(argv[0], "disasm") == 0) {
                    540:                value = 'D';
                    541:        } else if (strcmp(argv[0], "memdump") == 0) {
                    542:                value = 'M';
                    543:        } else {
                    544:                fprintf(stderr, "ERROR: regaddr operation can be only 'disasm' or 'memdump', not '%s'!\n", argv[0]);
                    545:                return 0;
                    546:        }
                    547: 
                    548:        if (strlen(argv[1]) != 2 ||
                    549:            (!DebugCpu_GetRegisterAddress(argv[1], &regaddr) &&
                    550:             (toupper(argv[1][0]) != 'R' || !isdigit(argv[1][1]) || argv[1][2]))) {
                    551:                /* not CPU register or Rx DSP register */
                    552:                fprintf(stderr, "ERROR: invalid address/data register '%s'!\n", argv[1]);
                    553:                return 0;
                    554:        }
                    555:        
                    556:        value |= argv[1][0] << 24;
                    557:        value |= argv[1][1] << 16;
                    558:        value &= 0xffff00ff;
                    559:        return value;
                    560: }
                    561: 
                    562: 
                    563: /* ------------------------------------------------------------------
                    564:  * Debugger & readline TAB completion integration
                    565:  */
                    566: 
                    567: /**
                    568:  * Default information on entering the debugger
                    569:  */
                    570: static void DebugInfo_Default(Uint32 dummy)
                    571: {
                    572:        int hbl, fcycles, lcycles;
                    573:        Video_GetPosition(&fcycles, &hbl, &lcycles);
                    574:        fprintf(stderr, "\nCPU=$%x, VBL=%d, FrameCycles=%d, HBL=%d, LineCycles=%d, DSP=",
                    575:                M68000_GetPC(), nVBLs, fcycles, hbl, lcycles);
                    576:        if (bDspEnabled)
                    577:                fprintf(stderr, "$%x\n", DSP_GetPC());
                    578:        else
                    579:                fprintf(stderr, "N/A\n");
                    580: }
                    581: 
                    582: static const struct {
                    583:        /* whether callback is used only for locking */
                    584:        bool lock;
                    585:        const char *name;
                    586:        void (*func)(Uint32 arg);
                    587:        /* convert args in argv into single Uint32 for func */
                    588:        Uint32 (*args)(int argc, char *argv[]);
                    589:        const char *info;
                    590: } infotable[] = {
                    591:        { false,"basepage",  DebugInfo_Basepage,   NULL, "Show program basepage info at given <address>" },
                    592:        { false,"crossbar",  DebugInfo_Crossbar,   NULL, "Show Falcon crossbar HW register values" },
                    593:        { true, "default",   DebugInfo_Default,    NULL, "Show default debugger entry information" },
                    594:        { true, "disasm",    DebugInfo_CpuDisAsm,  NULL, "Disasm CPU from PC or given <address>" },
                    595: #if ENABLE_DSP_EMU
                    596:        { true, "dspdisasm", DebugInfo_DspDisAsm,  NULL, "Disasm DSP from given <address>" },
                    597:        { true, "dspmemdump",DebugInfo_DspMemDump, DebugInfo_DspMemArgs, "Dump DSP memory from given <space> <address>" },
                    598:        { true, "dspregs",   DebugInfo_DspRegister,NULL, "Show DSP register values" },
                    599: #endif
                    600:        { true, "memdump",   DebugInfo_CpuMemDump, NULL, "Dump CPU memory from given <address>" },
                    601:        { false,"osheader",  DebugInfo_OSHeader,   NULL, "Show TOS OS header information" },
                    602:        { true, "regaddr",   DebugInfo_RegAddr, DebugInfo_RegAddrArgs, "Show <disasm|memdump> from CPU/DSP address pointed by <register>" },
                    603:        { true, "registers", DebugInfo_CpuRegister,NULL, "Show CPU register values" },
                    604:        { false,"videl",     DebugInfo_Videl,      NULL, "Show Falcon Videl HW register values" }
                    605: };
                    606: 
                    607: static int LockedFunction = 2; /* index for the "default" function */
                    608: static Uint32 LockedArgument;
                    609: 
                    610: /**
                    611:  * Show selected debugger session information
                    612:  * (when debugger is (again) entered)
                    613:  */
                    614: void DebugInfo_ShowSessionInfo(void)
                    615: {
                    616:        infotable[LockedFunction].func(LockedArgument);
                    617: }
                    618: 
                    619: 
                    620: /**
                    621:  * Readline match callback for info subcommand name completion.
                    622:  * STATE = 0 -> different text from previous one.
                    623:  * Return next match or NULL if no matches.
                    624:  */
                    625: static char *DebugInfo_Match(const char *text, int state, bool lock)
                    626: {
                    627:        static int i, len;
                    628:        const char *name;
                    629:        
                    630:        if (!state) {
                    631:                /* first match */
                    632:                len = strlen(text);
                    633:                i = 0;
                    634:        }
                    635:        /* next match */
                    636:        while (i++ < ARRAYSIZE(infotable)) {
                    637:                if (!lock && infotable[i-1].lock) {
                    638:                        continue;
                    639:                }
                    640:                name = infotable[i-1].name;
                    641:                if (strncmp(name, text, len) == 0)
                    642:                        return (strdup(name));
                    643:        }
                    644:        return NULL;
                    645: }
                    646: char *DebugInfo_MatchLock(const char *text, int state)
                    647: {
                    648:        return DebugInfo_Match(text, state, true);
                    649: }
                    650: char *DebugInfo_MatchInfo(const char *text, int state)
                    651: {
                    652:        return DebugInfo_Match(text, state, false);
                    653: }
                    654: 
                    655: 
                    656: /**
                    657:  * Show requested command information.
                    658:  */
                    659: int DebugInfo_Command(int nArgc, char *psArgs[])
                    660: {
                    661:        Uint32 value;
                    662:        const char *cmd;
                    663:        bool ok, lock;
                    664:        int i, sub;
                    665: 
                    666:        sub = -1;
                    667:        if (nArgc > 1) {
                    668:                cmd = psArgs[1];                
                    669:                /* which subcommand? */
                    670:                for (i = 0; i < ARRAYSIZE(infotable); i++) {
                    671:                        if (strcmp(cmd, infotable[i].name) == 0) {
                    672:                                sub = i;
                    673:                                break;
                    674:                        }
                    675:                }
                    676:        }
                    677: 
                    678:        if (infotable[sub].args) {
                    679:                /* value needs callback specific conversion */
                    680:                value = infotable[sub].args(nArgc-2, psArgs+2);
                    681:                ok = !!value;
                    682:        } else {
                    683:                if (nArgc > 2) {
                    684:                        /* value is normal number */
                    685:                        ok = Eval_Number(psArgs[2], &value);
                    686:                } else {
                    687:                        value = 0;
                    688:                        ok = true;
                    689:                }
                    690:        }
                    691: 
                    692:        lock = (strcmp(psArgs[0], "lock") == 0);
                    693:        
                    694:        if (sub < 0 || !ok) {
                    695:                /* no subcommand or something wrong with value, show info */
                    696:                fprintf(stderr, "%s subcommands are:\n", psArgs[0]);
                    697:                for (i = 0; i < ARRAYSIZE(infotable); i++) {
                    698:                        if (!lock && infotable[i].lock) {
                    699:                                continue;
                    700:                        }
                    701:                        fprintf(stderr, "- %s: %s\n",
                    702:                                infotable[i].name, infotable[i].info);
                    703:                }
                    704:                return DEBUGGER_CMDDONE;
                    705:        }
                    706: 
                    707:        if (lock) {
                    708:                /* lock given subcommand and value */
                    709:                LockedFunction = sub;
                    710:                LockedArgument = value;
                    711:                fprintf(stderr, "Locked %s output.\n", psArgs[1]);
                    712:        } else {
                    713:                /* do actual work */
                    714:                infotable[sub].func(value);
                    715:        }
                    716:        return DEBUGGER_CMDDONE;
                    717: }

unix.superglobalmegacorp.com

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