Annotation of researchv9/jtools/src/pi/m68kcore.c, revision 1.1.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.