Annotation of hatari/tests/debugger/test-breakcond.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Code to test Hatari conditional breakpoints in src/debug/breakcond.c
        !             3:  */
        !             4: #include "main.h"
        !             5: #include "dsp.h"
        !             6: #include "debugcpu.h"
        !             7: #include "breakcond.h"
        !             8: #include "stMemory.h"
        !             9: #include "newcpu.h"
        !            10: 
        !            11: #define BITMASK(x)      ((1<<(x))-1)
        !            12: 
        !            13: /* BreakCond_Command() command strings */
        !            14: #define CMD_LIST NULL
        !            15: #define CMD_REMOVE_ALL "all"
        !            16: 
        !            17: 
        !            18: static bool SetCpuRegister(const char *regname, Uint32 value)
        !            19: {
        !            20:        Uint32 *addr;
        !            21:        
        !            22:        switch (DebugCpu_GetRegisterAddress(regname, &addr)) {
        !            23:        case 32:
        !            24:                *addr = value;
        !            25:                break;
        !            26:        case 16:
        !            27:                *(Uint16*)addr = value;
        !            28:                break;
        !            29:        default:
        !            30:                fprintf(stderr, "SETUP ERROR: Register '%s' to set (to %x) is unrecognized!\n", regname, value);
        !            31:                return false;
        !            32:        }
        !            33:        return true;
        !            34: }
        !            35: 
        !            36: #if 0
        !            37: static bool SetDspRegister(const char *regname, Uint32 value)
        !            38: {
        !            39:        Uint32 *addr, mask;
        !            40: 
        !            41:        switch (DSP_GetRegisterAddress(regname, &addr, &mask)) {
        !            42:        case 32:
        !            43:                *addr = value & mask;
        !            44:                break;
        !            45:        case 16:
        !            46:                *(Uint16*)addr = value & mask;
        !            47:                break;
        !            48:        default:
        !            49:                return false;
        !            50:        }
        !            51:        return true;
        !            52: }
        !            53: #endif
        !            54: 
        !            55: int main(int argc, const char *argv[])
        !            56: {
        !            57:        const char *parser_fail[] = {
        !            58:                /* syntax & register name errors */
        !            59:                "",
        !            60:                " = ",
        !            61:                " a0 d0 ",
        !            62:                "gggg=a0",
        !            63:                "=a=b=",
        !            64:                "a0=d0=20",
        !            65:                "a0=d || 0=20",
        !            66:                "a0=d & 0=20",
        !            67:                ".w&3=2",
        !            68:                "d0 = %200",
        !            69:                "d0 = \"ICE!BAR",
        !            70:                "pc > $200 :foobar",
        !            71:                "foo().w=bar()",
        !            72:                "(a0.w=d0.l)",
        !            73:                "(a0&3)=20",
        !            74:                "20 = (a0.w)",
        !            75:                "()&=d0",
        !            76:                "d0=().w",
        !            77:                "255 & 3 = (d0) & && 2 = 2",
        !            78:                /* missing options file */
        !            79:                "pc>pc :file no-such-file",             
        !            80:                /* size and mask mismatches with numbers */
        !            81:                "d0.w = $ffff0",
        !            82:                "(a0).b & 3 < 100",
        !            83:                /* more than BC_MAX_CONDITIONS_PER_BREAKPOINT conditions */
        !            84:                "1=1 && 2=2 && 3=3 && 4=4 && 5=5",
        !            85:                NULL
        !            86:        };
        !            87:        const char *parser_pass[] = {
        !            88:                /* comparisons with normal numbers + indrect addressing */
        !            89:                " ($200).w > 200 ",
        !            90:                " ($200).w < 200 ",
        !            91:                " (200).w = $200 ",
        !            92:                " (200).w ! $200 ",
        !            93:                /* indirect addressing with registers */
        !            94:                "(a0)=(d0)",
        !            95:                "(d0).w=(a0).b",
        !            96:                /* sizes + multiple conditions + spacing */
        !            97:                "(a0).w&3=(d0)&&d0=1",
        !            98:                " ( a 0 ) . w  &  1 = ( d 0 ) & 1 &&  d 0 = 3 ",
        !            99:                "a0=1 && (d0)&2=(a0).w && ($00ff00).w&1=1",
        !           100:                " ($ff820a).b = 2",
        !           101:                /* variables */
        !           102:                "hbl > 0 && vbl < 2000 && linecycles = 508",
        !           103:                /* options */
        !           104:                "($200).w ! ($200).w :trace",
        !           105:                "($200).w > ($200).w :4 :lock",
        !           106:                "pc>pc :file data/test.ini :once",
        !           107:                NULL
        !           108:        };
        !           109:        /* address breakpoint + expression evalution with register */
        !           110:        char addr_pass[] = "pc + ($200*16/2 & 0xffff)";
        !           111: 
        !           112:        const char *match_tests[] = {
        !           113:                "a0 = d0",
        !           114:                "( $200 ) . b > 200", /* byte access to avoid endianess */
        !           115:                "pc < $50000 && pc > $60000",
        !           116:                "pc > $50000 && pc < $54000",
        !           117: #define FAILING_BC_TEST_MATCHES 4
        !           118:                "pc > $50000 && pc < $60000",
        !           119:                "( $200 ) . b > ( 200 ) . b",
        !           120:                "d0 = d1",
        !           121:                "a0 = pc",
        !           122:                NULL
        !           123:        };
        !           124:        const char *test;
        !           125:        char testidx[2] = "1";
        !           126:        int i, j, tests = 0, errors = 0;
        !           127:        int remaining_matches;
        !           128:        bool use_dsp;
        !           129: 
        !           130:        /* first automated tests... */
        !           131:        use_dsp = false;
        !           132:        fprintf(stderr, "\nShould FAIL for CPU:\n");
        !           133:        for (i = 0; (test = parser_fail[i]); i++) {
        !           134:                fprintf(stderr, "-----------------\n- parsing '%s'\n", test);
        !           135:                if (BreakCond_Command(test, use_dsp)) {
        !           136:                        fprintf(stderr, "***ERROR***: should have failed\n");
        !           137:                        errors++;
        !           138:                }
        !           139:        }
        !           140:        tests += i;
        !           141:        fprintf(stderr, "-----------------\n\n");
        !           142:        BreakCond_Command(CMD_LIST, use_dsp);
        !           143:        
        !           144:        fprintf(stderr, "\nShould PASS for CPU:\n");
        !           145:        for (i = 0; (test = parser_pass[i]); i++) {
        !           146:                fprintf(stderr, "-----------------\n- parsing '%s'\n", test);
        !           147:                if (!BreakCond_Command(test, use_dsp)) {
        !           148:                        fprintf(stderr, "***ERROR***: should have passed\n");
        !           149:                        errors++;
        !           150:                }
        !           151:        }
        !           152:        tests += i;
        !           153:        fprintf(stderr, "\nAddress PASS test for CPU:\n");
        !           154:        if (!BreakAddr_Command(addr_pass, use_dsp)) {
        !           155:                fprintf(stderr, "***ERROR***: should have passed\n");
        !           156:                errors++;
        !           157:        }
        !           158:        tests += 1;
        !           159: 
        !           160:        fprintf(stderr, "-----------------\n\n");
        !           161:        BreakCond_Command(CMD_LIST, use_dsp);
        !           162:        fprintf(stderr, "\n");
        !           163:        BreakCond_Command(CMD_REMOVE_ALL, use_dsp);
        !           164:        BreakCond_Command(CMD_LIST, use_dsp);
        !           165:        fprintf(stderr, "-----------------\n");
        !           166: 
        !           167:        /* add conditions */
        !           168:        fprintf(stderr, "\nLast one(s) should match, first one(s) shouldn't:\n");
        !           169:        for (i = 0; (test = match_tests[i]); i++) {
        !           170:                fprintf(stderr, "-----------------\n- parsing '%s'\n", test);
        !           171:                if (!BreakCond_Command(test, use_dsp)) {
        !           172:                        fprintf(stderr, "***ERROR***: should have passed\n");
        !           173:                        errors++;
        !           174:                }
        !           175:        }
        !           176:        tests += i;
        !           177:        BreakCond_Command(CMD_LIST, use_dsp);
        !           178:        fprintf(stderr, "\n");
        !           179:        
        !           180:        /* set up registers etc */
        !           181: 
        !           182:        /* fail indirect equality checks with zerod regs */
        !           183:        memset(STRam, 0, sizeof(STRam));
        !           184:        STRam[0] = 1;
        !           185:        /* !match: "( $200 ) > 200"
        !           186:         *  match: "( $200 ) . w > ( 200 ) . b"
        !           187:         */
        !           188:        STRam[0x200] = 100;
        !           189:        STRam[200] = 0x20;
        !           190:        /*  match: "d0 = d1" */
        !           191:        SetCpuRegister("d0", 4);
        !           192:        SetCpuRegister("d1", 4);
        !           193:        /* !match: "pc < $50000  &&  pc > $60000"
        !           194:         * !match: "pc < $50000  &&  pc > $54000"
        !           195:         *  match: "pc > $50000  &&  pc < $60000"
        !           196:         */
        !           197:        regs.pc = 0x58000;
        !           198:        /* !match: "d0 = a0"
        !           199:         *  match: "pc = a0"
        !           200:         */
        !           201:        SetCpuRegister("a0", 0x58000);
        !           202:        
        !           203:        /* check matches */
        !           204:        while ((i = BreakCond_MatchCpu())) {
        !           205:                fprintf(stderr, "Removing matching CPU breakpoint %d...\n", i);
        !           206:                for (j = 0; (test = match_tests[j]); j++) {
        !           207:                        if (BreakCond_MatchCpuExpression(i, test)) {
        !           208:                                break;
        !           209:                        }
        !           210:                }
        !           211:                if (test) {
        !           212:                        if (j < FAILING_BC_TEST_MATCHES) {
        !           213:                                fprintf(stderr, "ERROR: breakpoint should not have matched!\n");
        !           214:                                errors++;
        !           215:                        }
        !           216:                } else {
        !           217:                        fprintf(stderr, "WARNING: canonized breakpoint form didn't match\n");
        !           218:                        errors++;
        !           219:                }
        !           220:                testidx[0] = '0' + i;
        !           221:                BreakCond_Command(testidx, use_dsp); /* remove given */
        !           222:        }
        !           223:        remaining_matches = BreakCond_BreakPointCount(use_dsp);
        !           224:        if (remaining_matches != FAILING_BC_TEST_MATCHES) {
        !           225:                fprintf(stderr, "ERROR: wrong number of breakpoints left (%d instead of %d)!\n",
        !           226:                        remaining_matches, FAILING_BC_TEST_MATCHES);
        !           227:                errors++;
        !           228:        }
        !           229: 
        !           230:        fprintf(stderr, "\nOther breakpoints didn't match, removing the rest...\n");
        !           231:        BreakCond_Command(CMD_REMOVE_ALL, use_dsp);
        !           232:        BreakCond_Command(CMD_LIST, use_dsp);
        !           233:        fprintf(stderr, "-----------------\n");
        !           234: 
        !           235:        /* ...last parse cmd line args as DSP breakpoints */
        !           236:        if (argc > 1) {
        !           237:                use_dsp = true;
        !           238:                fprintf(stderr, "\nCommand line DSP breakpoints:\n");
        !           239:                for (argv++; --argc > 0; argv++) {
        !           240:                        fprintf(stderr, "-----------------\n- parsing '%s'\n", *argv);
        !           241:                        BreakCond_Command(*argv, use_dsp);
        !           242:                }
        !           243:                fprintf(stderr, "-----------------\n\n");
        !           244:                BreakCond_Command("", use_dsp); /* list */
        !           245: 
        !           246:                while ((i = BreakCond_MatchDsp())) {
        !           247:                        fprintf(stderr, "Removing matching DSP breakpoint.\n");
        !           248:                        testidx[0] = '0' + i;
        !           249:                        BreakCond_Command(testidx, use_dsp); /* remove given */
        !           250:                }
        !           251: 
        !           252:                BreakCond_Command(CMD_REMOVE_ALL, use_dsp);
        !           253:                BreakCond_Command(CMD_LIST, use_dsp);
        !           254:                fprintf(stderr, "-----------------\n");
        !           255:        }
        !           256:        if (errors) {
        !           257:                fprintf(stderr, "\n***Detected %d ERRORs in %d automated tests!***\n\n",
        !           258:                        errors, tests);
        !           259:        } else {
        !           260:                fprintf(stderr, "\nFinished without any errors!\n\n");
        !           261:        }
        !           262:        return errors;
        !           263: }

unix.superglobalmegacorp.com

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