Annotation of researchv9/jtools/src/pi/m68kcore.c, revision 1.1

1.1     ! root        1: #include "process.pub"
        !             2: #include "frame.pri"
        !             3: #include "symtab.pri"
        !             4: #include "symbol.h"
        !             5: #include "m68kcore.h"
        !             6: #include "asm.pri"
        !             7: #include "format.pub"
        !             8: #include "bpts.pri"
        !             9: #include "master.pri"
        !            10: SRCFILE("m68kcore.c")
        !            11: 
        !            12: char *M68kCore::read(long l,char *b,int n)     { return readwrite(l,b,n,0); }
        !            13: char *M68kCore::write(long l,char *b,int n)    { return readwrite(l,b,0,n); }
        !            14: char *M68kCore::pokedbl(long l,double d,int n) { return write(l,(char*)&d,n);}
        !            15: int M68kCore::REG_AP()                         { return 0; }
        !            16: int M68kCore::REG_FP()                         { return 14; }
        !            17: int M68kCore::REG_SP()                         { return 15; }
        !            18: int M68kCore::REG_PS()                         { return 16; }
        !            19: int M68kCore::REG_PC()                         { return 17; }
        !            20: char *M68kCore::readwrite(long, char*,int,int) { return "readwrite"; }
        !            21: int M68kCore::instack(long, long)              { return 1; }
        !            22: int M68kCore::fpvalid(long)                    { return 1; }
        !            23: Behavs M68kCore::behavetype()                  { return 0; }
        !            24: char *M68kCore::dostep(long, long, int)                { return "dostep"; }
        !            25: long M68kCore::scratchaddr()                   { return 0; }
        !            26: int M68kCore::nregs()                          { return 18; }
        !            27: long M68kCore::regaddr()                       { return 0; }
        !            28: 
        !            29: char *M68kCore::poke(long l,long d,int n)
        !            30: {
        !            31:        switch (n) {
        !            32:        case 1:
        !            33:                return write(l, 3 + (char*)&d,n);
        !            34:        case 2:
        !            35:                return write(l, 2 + (char*)&d,n);
        !            36:        case 4:
        !            37:                return write(l,(char*)&d,n);
        !            38:        default:
        !            39:                return "M68kCore poke error";
        !            40:        }
        !            41: }
        !            42: 
        !            43: char *M68kCore::liftbpt(Trap *t)       
        !            44: {
        !            45:        if( behavs() == ERRORED ) return 0;
        !            46:        return poke(t->stmt->range.lo, t->saved, 2);
        !            47: }
        !            48: 
        !            49: #define REGBIT(r) (1 << r)
        !            50: long M68kCore::saved(Frame *f, int r, int)     /* ignore size */
        !            51: {
        !            52:        if( r > 15 )
        !            53:                return 0;
        !            54:        if( !(f->regsave & REGBIT(r)) )
        !            55:                return 0;
        !            56:        long loc = f->regbase;
        !            57:        while( --r >= 0 )
        !            58:                if( f->regsave & REGBIT(r) ) loc += 4;
        !            59:        return loc;
        !            60: }
        !            61: 
        !            62: Asm *M68kCore::newAsm()        { return new M68kAsm(this); }
        !            63: 
        !            64: char *M68kCore::regname(int r)
        !            65: {
        !            66:        static char *regnames[] = { "d0", "d1", "d2", "d3", "d4", "d5",
        !            67:                                   "d6", "d7", "a0", "a1", "a2", "a3",
        !            68:                                   "a4", "a5", "fp", "sp", "ps", "pc",
        !            69:                                   "usp", "isp", "vbr", "sfc", "dfc",
        !            70:                                   "msp", "cacr", "caar" };
        !            71:        if (r < nregs())
        !            72:                return regnames[r];
        !            73:        else
        !            74:                return 0;
        !            75: }
        !            76: 
        !            77: long M68kCore::regloc(int r, int sz)
        !            78: {
        !            79:        if (r >= 0 && r < nregs()) {
        !            80:                long ret = 4 * r + regaddr();
        !            81:                if (sz && sz < 4)
        !            82:                        ret += 4 - sz;
        !            83:                return ret;
        !            84:        }
        !            85:        return 0;
        !            86: }
        !            87: 
        !            88: 
        !            89: #define CYCLE 4
        !            90: Cslfd *M68kCore::peek(long loc, Cslfd *fail)
        !            91: {
        !            92:        static i;
        !            93:        static Cslfd *c;
        !            94:        UCslfd u;
        !            95: 
        !            96:        if( read(loc, (char*)&u, 8) )
        !            97:                return Core::peek(loc, fail);
        !            98:        if( !c ) c = new Cslfd[CYCLE];
        !            99:        Cslfd *p = c+(i++,i%=CYCLE);
        !           100:        p->chr = u.chr;
        !           101:        p->sht = u.sht;
        !           102:        p->lng = u.lng;
        !           103:        p->flterr = 0;
        !           104:        p->flt = u.flt;
        !           105:        p->dbl = u.dbl;
        !           106:        return p;
        !           107: }
        !           108: 
        !           109: char *M68kCore::peekstring(long loc, char *fail)
        !           110: {
        !           111:        static char buf[256];
        !           112:        char *error = read(loc, buf, 250);
        !           113:        if( error )
        !           114:                return fail ? fail : strcpy(buf,error);
        !           115:        return buf;
        !           116: }
        !           117: 
        !           118: CallStk *M68kCore::callstack() // do we have to peek everything twice?
        !           119: {
        !           120:        trace( "%d.callstack()", this );        OK(0);
        !           121:        long size;
        !           122:        long _fp = fp();
        !           123:        if( !fpvalid(_fp))
        !           124:                return (CallStk *)0;
        !           125:        for( size = 1; size<1000; ++size ){
        !           126:                long __fp = peek(_fp)->lng;
        !           127:                if( !instack(__fp, _fp) )
        !           128:                        break;
        !           129:                _fp = __fp;
        !           130:        }
        !           131:        CallStk *c = new CallStk(size, this);
        !           132:        _fp = fp();
        !           133:        long _pc = pc();
        !           134:        for( long i = 0; i < size; ++i ){
        !           135:                c->fpf[i].fp = _fp;
        !           136:                c->fpf[i].func = (Func*) _symtab->loctosym(U_FUNC, _pc);
        !           137:                _pc = peek(_fp+4)->lng;
        !           138:                _fp = peek(_fp)->lng;
        !           139:        }
        !           140:        return c;
        !           141: }
        !           142: 
        !           143: const short LINKA6=0x4E56, ADDLSP=0xDFFC, MOVEMLSP=0x48D7;
        !           144: Frame M68kCore::frameabove(long _fp)
        !           145: {
        !           146:        Frame f(this);
        !           147:        if( _fp ){
        !           148:                f.pc = peek(_fp+4)->lng;
        !           149:                f.fp = peek(_fp)->lng;
        !           150:        } else {
        !           151:                f.pc = pc();
        !           152:                f.fp = fp();
        !           153:        }
        !           154:        f.ap = f.fp;
        !           155:        int callpc = peek(f.fp+4)->lng;
        !           156:        int inst = peek(callpc)->sht;
        !           157:        f.regbase = f.fp;
        !           158:        Func *funcp = (Func*)_symtab->loctosym(U_FUNC, f.pc);
        !           159:        if (funcp) {
        !           160:                int faddr = funcp->range.lo;
        !           161:                if (peek(faddr)->sht == LINKA6) {
        !           162:                        f.regbase += peek(faddr+2)->sht;
        !           163:                        faddr += 4;
        !           164:                }
        !           165:                if (peek(faddr)->sht == ADDLSP) {
        !           166:                        f.regbase += peek(faddr+2)->lng;
        !           167:                        faddr += 6;
        !           168:                }
        !           169:                if (peek(faddr)->sht == MOVEMLSP)
        !           170:                        f.regsave = peek(faddr+2)->sht;
        !           171:        }
        !           172:        return f;
        !           173: }
        !           174: 
        !           175: const short M68K_TRAP0=0x4E40, M68K_RTS = 0x4E75, M68K_UNLNKA6 = 0x4E5E;
        !           176: char *M68kCore::popcallstack()
        !           177: {
        !           178:        long regaddr, savepc;
        !           179:        char *error = 0;
        !           180:        int i;
        !           181:        short saveinst;
        !           182:        Cslfd *c;
        !           183: 
        !           184:        if( behavetype() == ACTIVE )
        !           185:                return "pop callstack: process not stopped";
        !           186:        savepc = pc();
        !           187:        if( peek(savepc-2)->sht == M68K_TRAP0 )
        !           188:                return "pop callstack: process in system call";
        !           189:        c = peek(savepc, 0);
        !           190:        if( !c ) return "cannot pop callstack";
        !           191:        saveinst = c->sht;
        !           192:        // Must be careful if we are in the middle of the call sequence
        !           193:        switch (saveinst) {
        !           194:        case M68K_RTS:
        !           195:                return step();
        !           196:        case LINKA6:
        !           197:                goto rts;
        !           198:        case MOVEMLSP:
        !           199:                goto unlink;
        !           200:        }
        !           201:        // Sometimes the space is added after the link
        !           202:        if( peek(savepc-2)->sht == LINKA6 )
        !           203:                goto rts;
        !           204:        // Restore the registers, except the frame pointer and sp
        !           205:        { // This is here because C++ bitches about gotos if it isn't
        !           206:        Frame f = frameabove(0);
        !           207:        for (i = 0; i < 14; i++)
        !           208:                if (regaddr = saved(&f, i, 4))
        !           209:                        regpoke(i, peek(regaddr)->lng);
        !           210:        }
        !           211:        // Pop the frame
        !           212: unlink:        if( !error ) error = poke(savepc, M68K_UNLNKA6, 2);
        !           213:        if( !error ) error = step();
        !           214:        if( !error ) regpoke(REG_PC(), savepc);
        !           215:        // Return from the subroutine
        !           216: rts:   if( !error ) error = poke(savepc, M68K_RTS, 2);
        !           217:        if( !error ) error = step();
        !           218:        // Restore the instruction
        !           219:        poke(savepc, saveinst, 2);
        !           220:        return error;
        !           221: }
        !           222: 
        !           223: char *M68kCore::step(long lo, long hi)
        !           224: {
        !           225:        return dostep(lo,hi,1);
        !           226: }
        !           227: 
        !           228: const short M68K_BSR = 0x6100, M68K_JSR = 0x4e80;
        !           229: const short M68K_BSR_MSK = 0xff00, M68K_JSR_MSK = 0xffc0;
        !           230: char *M68kCore::stepoverM68KJSB()
        !           231: {
        !           232:        char *error = 0;
        !           233:        static Trap *t;
        !           234:        short inst;
        !           235:        long fp0, offset;
        !           236: 
        !           237:        if(!t)
        !           238:                t = new Trap(new Stmt(0,0,0),0);
        !           239:        inst = peek(pc())->sht;
        !           240:        /*
        !           241:         * Determine where to put the breakpoint depending on the
        !           242:         * addressing mode of the instruction.
        !           243:         */
        !           244:        if ((inst & M68K_BSR_MSK) == M68K_BSR) {
        !           245:                inst &= 0xff;
        !           246:                if (inst == 0)
        !           247:                        offset = 4;
        !           248:                else if (inst == 0xff)
        !           249:                        offset = 6;
        !           250:                else
        !           251:                        offset = 2;
        !           252:        } else {                        /* Its a JSR */
        !           253:                short reg, mode;
        !           254:                reg = inst & 07;
        !           255:                mode = (inst >> 3) & 0x7;
        !           256:                if (mode == 7) {
        !           257:                        if (reg == 1)
        !           258:                                offset = 6;
        !           259:                        else if (reg == 0 || reg == 2)
        !           260:                                offset = 4;
        !           261:                        else
        !           262:                                goto indexed;
        !           263:                } else if (mode == 2)
        !           264:                        offset = 2;
        !           265:                else if (mode == 5)
        !           266:                        offset = 4;
        !           267:                else {
        !           268: indexed:
        !           269:                        inst = peek(pc()+2)->sht;
        !           270:                        offset = 4;
        !           271:                        /* Full format extension */
        !           272:                        if (inst & 0x0100) {
        !           273:                                /* Base Displacement */
        !           274:                                if (inst & 0x0020) {
        !           275:                                        if (inst & 0x0010)
        !           276:                                                offset += 4;
        !           277:                                        else
        !           278:                                                offset += 2;
        !           279:                                }
        !           280:                                /* Outer Displacement */
        !           281:                                if (inst & 0x0002) {
        !           282:                                        if (inst & 0x0001)
        !           283:                                                offset += 4;
        !           284:                                        else
        !           285:                                                offset += 2;
        !           286:                                }
        !           287:                        }
        !           288:                }
        !           289: 
        !           290:        }
        !           291:        t->stmt->range.lo = pc()+offset;
        !           292:        fp0 = fp();
        !           293:        if(error = laybpt(t))
        !           294:                return error;
        !           295:        for(;;) {
        !           296:                error = dostep(0,0,0);
        !           297:                if (error || fp() >= fp0)
        !           298:                        break;
        !           299:                if( error = liftbpt(t) ) return error;
        !           300:                if( error = dostep(0,0,1) ) return error;
        !           301:                if( error = laybpt(t) ) return error;
        !           302:        }
        !           303:        if( !error )
        !           304:                error = liftbpt(t);
        !           305:        else
        !           306:                liftbpt(t);
        !           307:        return error;
        !           308: }
        !           309: 
        !           310: int M68kCore::isM68KJSB(int inst)
        !           311: {
        !           312:        return (inst & M68K_BSR_MSK) == M68K_BSR ||
        !           313:               (inst & M68K_JSR_MSK) == M68K_JSR;
        !           314: }
        !           315: 
        !           316: char *M68kCore::stepprolog()
        !           317: {
        !           318:        Func *f = (Func*)_symtab->loctosym(U_FUNC, pc());
        !           319:        if (f) {
        !           320:                // Only step again if we are in the function prolog
        !           321:                Stmt *s = f->stmt(pc());
        !           322:                if (s && s->range.lo == f->range.lo)
        !           323:                        process()->stmtstep(1);
        !           324:        }
        !           325:        return 0;
        !           326: }
        !           327: 
        !           328: char *M68kCore::docall(long addr, int numarg)
        !           329: {
        !           330:        const int CALL_SIZE=12, JSR=0x4eb9, ADDSP=0xdffc;
        !           331:        char save[CALL_SIZE], *error;
        !           332:        int i;
        !           333: 
        !           334:        if( behavetype() == ACTIVE )
        !           335:                return "process not stopped";
        !           336:        if( !online() )
        !           337:                return "cannot restart dump";
        !           338:        int callstart = scratchaddr();
        !           339:        for( i = 0; i < CALL_SIZE; ++i )
        !           340:                save[i] = peek(callstart+i)->chr;
        !           341:        if( ( error = poke(callstart+0, JSR, 2) )
        !           342:         || ( error = poke(callstart+2, addr, 4) )
        !           343:         || ( error = poke(callstart+6, ADDSP, 2) )
        !           344:         || ( error = poke(callstart+8, numarg * 4, 4) ) )
        !           345:                return error;
        !           346:        if( ( error = regpoke(REG_PC(), callstart) )
        !           347:         || ( error = step( callstart, callstart+CALL_SIZE) ) )
        !           348:                return error;
        !           349:        for( i = 0; i < CALL_SIZE; ++i )
        !           350:                if( error = poke(callstart+i, save[i], 1 ) )
        !           351:                        return error;
        !           352:        return 0;
        !           353: }
        !           354: 
        !           355: long M68kCore::apforcall(int argbytes)
        !           356: {
        !           357:        regpoke(REG_SP(), sp() - argbytes);
        !           358:        return sp() - 8;
        !           359: }
        !           360: 
        !           361: long M68kCore::returnregloc()
        !           362: {
        !           363:        return regloc(0);
        !           364: }
        !           365: 
        !           366: Context* M68kCore::newContext()
        !           367: {
        !           368:        M68kContext *cc = new M68kContext;
        !           369:        cc->error = 0;
        !           370:        cc->core = this;
        !           371:        if( behavetype() == ACTIVE )
        !           372:                cc->error = "context save: process not stopped";
        !           373:        if( !cc->error )
        !           374:                cc->error = read(regaddr(),(char*)cc->regs,sizeof(cc->regs));
        !           375:        return cc;
        !           376: }
        !           377: 
        !           378: void M68kContext::restore()
        !           379: {
        !           380:        error = core->write(core->regaddr(), (char*)regs, sizeof(regs));
        !           381: }

unix.superglobalmegacorp.com

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