Annotation of uae/cpu.cc, revision 1.1

1.1     ! root        1:  /* 
        !             2:   * UAE - The Unusable Amiga Emulator
        !             3:   * 
        !             4:   * MC68000 emulation v0.5
        !             5:   *
        !             6:   * v0.0: 950227
        !             7:   *       instruction decoding, emulate all instructions except MOVEM and
        !             8:   *       things like MOVE SR,EA or RESET
        !             9:   *       debugging functions: disasm, dumpstate
        !            10:   * v0.1: 950228 
        !            11:   *       exceptions, almost all instructions, bug fixes
        !            12:   * v0.2: 950305 
        !            13:   *       more bug fixes in interrupt code. STOP implemented. Bugs in
        !            14:   *       GenerateDecTab() fixed.
        !            15:   * v0.3: 950306
        !            16:   *       bug fixes: ROR shouldn't set X flag. SWAP didn't set any flags.
        !            17:   *       GenerateDecTab() created wrong sizes for all shift instructions
        !            18:   * v0.4: 950309
        !            19:   *       yet another bug in the shifting instructions part of GenerateDecTab
        !            20:   * v0.5: 930311
        !            21:   *       lots of bug fixes. Sign extension is probably correct now.
        !            22:   *       Multiplication corrected. None of these bugs affected the Kickstart.
        !            23:   *
        !            24:   * (c) 1995 Bernd Schmidt
        !            25:   * 
        !            26:   */
        !            27: 
        !            28: #include <iostream.h>
        !            29: #include <iomanip.h>
        !            30: #include <assert.h>
        !            31: #include <string.h>
        !            32: 
        !            33: #include "amiga.h"
        !            34: #include "memory.h"
        !            35: #include "custom.h"
        !            36: #include "cpu.h"
        !            37: 
        !            38: enum amodes {
        !            39:   Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r, 
        !            40:   absw, absl, PC16, PC8r, imm, imm3, ill2, ill3 
        !            41: };
        !            42: 
        !            43: class addr_mode {
        !            44:  public:
        !            45:   amodes mode;
        !            46:   UBYTE reg;
        !            47:   addr_mode(int=0,int=0);
        !            48: };
        !            49: 
        !            50: addr_mode::addr_mode(int m,int r)
        !            51: {
        !            52:   assert ((r & 7) == r);
        !            53:   assert ((m & 7) == m);
        !            54: 
        !            55:   if (m == 7) mode = (amodes)(absw + r);
        !            56:   else mode = (amodes)m;
        !            57:   reg = r;
        !            58: }
        !            59: 
        !            60: enum eatypes {
        !            61:   RegD, RegA, Addr, EAIM
        !            62: };
        !            63: 
        !            64: struct effadr {
        !            65:  public:
        !            66:   ULONG addr;
        !            67:   eatypes type;
        !            68:   ULONG szmask;
        !            69: };
        !            70: 
        !            71: struct instr_params {
        !            72:   addr_mode src,dest;
        !            73:   ULONG mask;
        !            74:   UWORD clogs;
        !            75: };
        !            76: 
        !            77: typedef void instr_result;
        !            78: typedef instr_result (*instr_func)(const instr_params &);
        !            79: 
        !            80: struct I_dec_tab_entry {
        !            81:   instr_func execfunc;
        !            82:   instr_params params;
        !            83:   I_dec_tab_entry() { execfunc = NULL; }
        !            84: }; 
        !            85: 
        !            86: static I_dec_tab_entry instr_dectab[65536]; 
        !            87: 
        !            88: static void GenerateDecTab();
        !            89: 
        !            90: void MC68000_init()
        !            91: {
        !            92:     GenerateDecTab();
        !            93: };
        !            94: 
        !            95: typedef int flagtype; // faster than char ?
        !            96: 
        !            97: static struct {
        !            98:   ULONG d[8];
        !            99:   CPTR  a[8],usp;
        !           100:   UWORD sr;
        !           101:   flagtype t,s,x,n,z,v,c,stopped;
        !           102:   int intmask;
        !           103:   ULONG pc;
        !           104: } regs;
        !           105: 
        !           106: static ULONG sizemask(const int sz)
        !           107: {
        !           108:   switch(sz){
        !           109:   case 0: return 0xff;
        !           110:   case 1: return 0xffff;
        !           111:   case 2: return 0xffffffff;
        !           112:   default: abort();
        !           113:   }
        !           114: }
        !           115: 
        !           116: static inline int mask2len(const ULONG mask)
        !           117: {
        !           118:   if (mask == 0xff) return 1;
        !           119:   if (mask == 0xffff) return 2;
        !           120:   return 4;
        !           121: }
        !           122: 
        !           123: static inline int mask2shift(const ULONG mask)
        !           124: {
        !           125:   if (mask == 0xff) return 7;
        !           126:   if (mask == 0xffff) return 15;
        !           127:   return 31;
        !           128: }
        !           129: 
        !           130: static inline ULONG ExtendWord(const ULONG v)
        !           131: {
        !           132:   return (LONG)(WORD)(v);
        !           133: }
        !           134: 
        !           135: static inline ULONG ExtendByte(const ULONG v)
        !           136: {
        !           137:   return (LONG)(BYTE)(v);
        !           138: }
        !           139: 
        !           140: static inline ULONG Extend(const ULONG v,const ULONG mask)
        !           141: {
        !           142:   switch(mask){
        !           143:   case 0xff: 
        !           144:     return (LONG)(BYTE)v;
        !           145:   case 0xffff:
        !           146:     return (LONG)(WORD)v;
        !           147:   default:
        !           148:     return v;
        !           149:   }
        !           150: }
        !           151: 
        !           152: static inline UWORD nextiword()
        !           153: {
        !           154:   UWORD r = mem.get_word(regs.pc);
        !           155:   regs.pc += 2;
        !           156:   return r;
        !           157: }
        !           158: 
        !           159: static inline ULONG nextilong()
        !           160: {
        !           161:   ULONG r = (mem.get_word(regs.pc) << 16) + mem.get_word(regs.pc+2);
        !           162:   regs.pc += 4;
        !           163:   return r;
        !           164: }
        !           165: 
        !           166: static effadr GetEA(const addr_mode &a, const ULONG mask)
        !           167: {
        !           168:   effadr ea;
        !           169:   UWORD dp;
        !           170:   BYTE disp8;
        !           171:   int r;
        !           172:   ULONG dispreg;
        !           173: 
        !           174:   ea.szmask = mask;
        !           175:   switch(a.mode){
        !           176:   case Dreg:
        !           177:     ea.addr = a.reg; ea.type = RegD; break;
        !           178:   case Areg:
        !           179:     ea.addr = a.reg; ea.type = RegA; break;
        !           180:   case Aind:
        !           181:     ea.addr = regs.a[a.reg]; ea.type = Addr; break;
        !           182:   case Aipi:
        !           183:     ea.addr = regs.a[a.reg]; regs.a[a.reg] += mask2len(mask);
        !           184:     ea.type = Addr; break;
        !           185:   case Apdi:
        !           186:     ea.addr = regs.a[a.reg] -= mask2len(mask); ea.type = Addr; break;
        !           187:   case Ad16:
        !           188:     ea.addr = regs.a[a.reg] + (WORD)nextiword(); // cast for signed rel. values
        !           189:     ea.type = Addr; break;
        !           190:   case Ad8r:
        !           191:     dp = nextiword();
        !           192:     disp8 = dp & 0xFF;
        !           193:     r = (dp & 0x7000) >> 12;
        !           194:     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
        !           195: 
        !           196:     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
        !           197:     ea.addr = regs.a[a.reg] + disp8 + dispreg;
        !           198:     ea.type = Addr; break;
        !           199:   case PC16:
        !           200:     ea.addr = regs.pc;
        !           201:     ea.addr += (WORD)nextiword(); // cast for signed rel. values
        !           202:     ea.type = Addr; break;
        !           203:   case PC8r:
        !           204:     ea.addr = regs.pc;
        !           205:     dp = nextiword();
        !           206:     disp8 = dp & 0xFF;
        !           207:     r = (dp & 0x7000) >> 12;
        !           208:     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
        !           209: 
        !           210:     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
        !           211:     ea.addr += disp8 + dispreg;
        !           212:     ea.type = Addr; break;
        !           213:   case absw:
        !           214:     ea.type = Addr;
        !           215:     ea.addr = nextiword();
        !           216:     break;
        !           217:   case absl:
        !           218:     ea.type = Addr;
        !           219:     ea.addr = nextilong();
        !           220:     break;
        !           221:   case imm:
        !           222:     switch(mask){
        !           223:     case 0xff:
        !           224:       ea.addr = ExtendByte(nextiword()); ea.type = EAIM; break;
        !           225:     case 0xffff:
        !           226:       ea.addr = ExtendWord(nextiword()); ea.type = EAIM; break;
        !           227:     case 0xffffffff:
        !           228:       ea.addr = nextilong(); ea.type = EAIM; break;
        !           229:     }
        !           230:     break;
        !           231:   case imm3:
        !           232:     ea.addr = a.reg; ea.type = EAIM; break;
        !           233:   default:
        !           234:     abort(); // FIXME
        !           235:   }
        !           236:   return ea;
        !           237: }
        !           238: 
        !           239: static effadr MGetEA(const addr_mode &a, const ULONG mask)
        !           240: {
        !           241:   effadr ea;
        !           242:   UWORD dp;
        !           243:   BYTE disp8;
        !           244:   int r;
        !           245:   ULONG dispreg;
        !           246: 
        !           247:   ea.szmask = mask;
        !           248:   switch(a.mode){
        !           249:   case Aind: case Aipi: case Apdi:
        !           250:     ea.addr = regs.a[a.reg]; ea.type = Addr; break;
        !           251:   case Ad16:
        !           252:     ea.addr = regs.a[a.reg] + (WORD)nextiword(); // cast for signed rel. values
        !           253:     ea.type = Addr; break;
        !           254:   case Ad8r:
        !           255:     dp = nextiword();
        !           256:     disp8 = dp & 0xFF;
        !           257:     r = (dp & 0x7000) >> 12;
        !           258:     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
        !           259: 
        !           260:     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
        !           261:     ea.addr = regs.a[a.reg] + disp8 + dispreg;
        !           262:     ea.type = Addr; break;
        !           263:   case PC16:
        !           264:     ea.addr = regs.pc;
        !           265:     ea.addr += (WORD)nextiword(); // cast for signed rel. values
        !           266:     ea.type = Addr; break;
        !           267:   case PC8r:
        !           268:     ea.addr = regs.pc;
        !           269:     dp = nextiword();
        !           270:     disp8 = dp & 0xFF;
        !           271:     r = (dp & 0x7000) >> 12;
        !           272:     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
        !           273: 
        !           274:     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
        !           275:     ea.addr += disp8 + dispreg;
        !           276:     ea.type = Addr; break;
        !           277:   case absw:
        !           278:     ea.type = Addr;
        !           279:     ea.addr = nextiword();
        !           280:     break;
        !           281:   case absl:
        !           282:     ea.type = Addr;
        !           283:     ea.addr = nextilong();
        !           284:     break;
        !           285:   default:
        !           286:     abort(); // FIXME
        !           287:   }
        !           288:   return ea;
        !           289: }
        !           290: 
        !           291: static void MCompleteEAFromRL(effadr &ea, const addr_mode &a, ULONG mask, UWORD bitmask)
        !           292: {
        !           293:   int bitcnt = 0;
        !           294:   for(int i=0;i<16;i++) {
        !           295:     bitcnt += bitmask & 1;
        !           296:     bitmask >>= 1;
        !           297:   }
        !           298:   switch(a.mode){
        !           299:   case Aipi: 
        !           300:     abort(); break;
        !           301:   case Apdi:
        !           302:     ea.addr = regs.a[a.reg] -= bitcnt * mask2len(mask); break;
        !           303:   default: break;
        !           304:   }
        !           305: }
        !           306: 
        !           307: static void MCompleteEAToRL(effadr &ea, const addr_mode &a, ULONG mask, UWORD bitmask)
        !           308: {
        !           309:   int bitcnt = 0;
        !           310:   for(int i=0;i<16;i++) {
        !           311:     bitcnt += bitmask & 1;
        !           312:     bitmask >>= 1;
        !           313:   }
        !           314:   switch(a.mode){
        !           315:   case Aipi: 
        !           316:     regs.a[a.reg] = ea.addr; break;
        !           317:   case Apdi:
        !           318:     abort(); break;
        !           319:   default: break;
        !           320:   }
        !           321: }
        !           322: 
        !           323: static ULONG RetrieveEA(const effadr &ea)
        !           324: {
        !           325:   switch(ea.type){
        !           326:   case Addr:
        !           327:     return ea.addr;
        !           328:   default:
        !           329:     abort(); // FIXME
        !           330:   }
        !           331: }
        !           332: 
        !           333: static ULONG GetFromEA(const effadr &ea)
        !           334: {
        !           335:   switch(ea.type) {
        !           336:   case RegD:
        !           337:     return Extend(regs.d[ea.addr],ea.szmask);
        !           338:   case RegA:
        !           339:     return Extend(regs.a[ea.addr],ea.szmask);
        !           340:   case Addr:
        !           341:     switch(ea.szmask){
        !           342:     case 0xff:
        !           343:       return ExtendByte(mem.get_byte(ea.addr));
        !           344:     case 0xffff:
        !           345:       return ExtendWord(mem.get_word(ea.addr));
        !           346:     default: // long
        !           347:       return (mem.get_word(ea.addr) << 16) + mem.get_word(ea.addr+2);
        !           348:     }
        !           349:   case EAIM:
        !           350:     return ea.addr;
        !           351:   }
        !           352: }
        !           353: 
        !           354: static void StoreToEA(const effadr &ea, const ULONG value)
        !           355: {
        !           356:   switch(ea.type){
        !           357:   case RegD:
        !           358:     regs.d[ea.addr] &= ~ea.szmask; regs.d[ea.addr] |= (value & ea.szmask);
        !           359:     break;
        !           360:   case RegA:
        !           361:     regs.a[ea.addr] = value;
        !           362:  //   if (ea.szmask == 0xffff) regs.a[ea.addr] = ExtendWord(regs.a[ea.addr]);
        !           363:     break;
        !           364:   case Addr:
        !           365:     switch(ea.szmask){
        !           366:     case 0xff:
        !           367:       mem.put_byte(ea.addr,value);
        !           368:       break;
        !           369:     case 0xffff:
        !           370:       mem.put_word(ea.addr,value);
        !           371:       break;
        !           372:     default: // long
        !           373:       mem.put_word(ea.addr,value >> 16); 
        !           374:       mem.put_word(ea.addr+2, value & 0xffff);
        !           375:     }
        !           376:     break;
        !           377:   default:
        !           378:     cout << hex << regs.pc;
        !           379:     abort(); // FIXME
        !           380:   }
        !           381: }
        !           382: 
        !           383: static effadr ShowEA(addr_mode a,ULONG mask)
        !           384: {
        !           385:   effadr ea;
        !           386:   UWORD dp;
        !           387:   BYTE disp8;
        !           388:   WORD disp16;
        !           389:   int r;
        !           390:   ULONG dispreg;
        !           391: 
        !           392:   cout << setw(1) << setfill('0');
        !           393:   ea.szmask = mask;
        !           394:   switch(a.mode){
        !           395:   case Dreg:
        !           396:     ea.addr = a.reg; ea.type = RegD; 
        !           397:     cout << "D" << (int)a.reg;
        !           398:     break;
        !           399:   case Areg:
        !           400:     ea.addr = a.reg; ea.type = RegA;
        !           401:     cout << "A" << (int)a.reg;
        !           402:     break;
        !           403:   case Aind:
        !           404:     ea.addr = regs.a[a.reg]; ea.type = Addr; 
        !           405:     cout << "(A" << (int)a.reg << ")";
        !           406:     break;
        !           407:   case Aipi:
        !           408:     ea.addr = regs.a[a.reg]; 
        !           409:     ea.type = Addr; 
        !           410:     cout << "(A" << (int)a.reg << ")+";
        !           411:     break;
        !           412:   case Apdi:
        !           413:     ea.addr = regs.a[a.reg] - mask2len(mask); ea.type = Addr; 
        !           414:     cout << "-(A" << (int)a.reg << ")";
        !           415:     break;
        !           416:   case Ad16:
        !           417:     disp16 = nextiword();
        !           418:     ea.addr = regs.a[a.reg] + (WORD)disp16;
        !           419:     ea.type = Addr; 
        !           420:     cout << "(A" << (int)a.reg << ",$" << hex << setw(8) << disp16 << ") == $" 
        !           421:       << ea.addr << dec;
        !           422:     break;
        !           423:   case Ad8r:
        !           424:     dp = nextiword();
        !           425:     disp8 = dp & 0xFF;
        !           426:     r = (dp & 0x7000) >> 12;
        !           427:     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
        !           428: 
        !           429:     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
        !           430:     ea.addr = regs.a[a.reg] + disp8 + dispreg;
        !           431:     ea.type = Addr;
        !           432:     cout << "(A" << (int)a.reg << "," << ((dp & 0x8000) ? "A" : "D") << (int)r
        !           433:       << ",$" << hex << (int)disp8 << ") == $" << ea.addr
        !           434:       << dec;
        !           435:     break;
        !           436:   case PC16:
        !           437:     ea.addr = regs.pc;
        !           438:     disp16 = nextiword();
        !           439:     ea.addr += (WORD)disp16; // cast for signed rel. values
        !           440:     ea.type = Addr; 
        !           441:     cout << "(PC" << ",$" << hex << setw(8) << disp16 << ") == $" << ea.addr 
        !           442:       << dec;
        !           443:     break;
        !           444:   case PC8r:
        !           445:     ea.addr = regs.pc;
        !           446:     dp = nextiword();
        !           447:     disp8 = dp & 0xFF;
        !           448:     r = (dp & 0x7000) >> 12;
        !           449:     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
        !           450: 
        !           451:     if (!(dp & 0x800)) dispreg = ExtendWord(dispreg);
        !           452:     ea.addr += disp8 + dispreg;
        !           453:     ea.type = Addr; 
        !           454:     cout << "(PC" << "," << ((dp & 0x8000) ? "A" : "D") << (int)r
        !           455:       << ",$" << hex << (int)disp8 << ") == $" << ea.addr
        !           456:       << dec;
        !           457:     break;
        !           458:   case absw:
        !           459:     ea.type = Addr;
        !           460:     ea.addr = nextiword();
        !           461:     cout << "$" << hex << ea.addr << dec;
        !           462:     break;
        !           463:   case absl:
        !           464:     ea.type = Addr;
        !           465:     ea.addr = nextilong();
        !           466:     cout << "$" << hex << ea.addr << dec;
        !           467:     break;
        !           468:   case imm:
        !           469:     switch(mask){
        !           470:     case 0xff:
        !           471:       ea.addr = nextiword() & 0xff; ea.type = EAIM; break;
        !           472:     case 0xffff:
        !           473:       ea.addr = nextiword(); ea.type = EAIM; break;
        !           474:     case 0xffffffff:
        !           475:       ea.addr = nextilong(); ea.type = EAIM; break;
        !           476:     }
        !           477:     cout << "#$" << hex << ea.addr << dec;
        !           478:     break;
        !           479:   case imm3:
        !           480:     ea.addr = a.reg; ea.type = EAIM;
        !           481:     cout << "#$" << hex << ea.addr << dec;
        !           482:     break;
        !           483:   default:
        !           484:     abort(); // FIXME
        !           485:   }
        !           486:   return ea;
        !           487: }
        !           488: 
        !           489: static inline void setflags_add(const ULONG src, const ULONG oldv, 
        !           490:                                 const ULONG newv)
        !           491: {
        !           492:   int s = src >> 31;
        !           493:   int o = oldv >> 31;
        !           494:   int n = newv >> 31;
        !           495: 
        !           496:   regs.z = newv == 0;
        !           497:   regs.c = regs.x = (s && o) || (!n && (o || s));
        !           498:   regs.n = n;
        !           499:   regs.v = ((s && o && !n) || (!s && !o && n));
        !           500: }
        !           501: 
        !           502: static inline void setflags_sub(const ULONG src, const ULONG oldv,
        !           503:                                 const ULONG newv)
        !           504: {
        !           505:   int s = src >> 31;
        !           506:   int o = oldv >> 31;
        !           507:   int n = newv >> 31;
        !           508: 
        !           509:   regs.z = newv == 0;
        !           510:   regs.c = regs.x = (s && !o) || (n && (!o || s));
        !           511:   regs.n = n;
        !           512:   regs.v = ((!s && o && !n) || (s && !o && n));
        !           513: }
        !           514: 
        !           515: static inline void setflags_cmp(const ULONG src, const ULONG oldv, 
        !           516:                                const ULONG newv)
        !           517: {
        !           518:   int sh = 31; //mask2shift(mask);
        !           519:   int s = (src >> sh); // & 1;
        !           520:   int o = (oldv >> sh); // & 1;
        !           521:   int n = newv >> sh;
        !           522: 
        !           523:   regs.z = newv == 0;
        !           524:   regs.c = (s && !o) || (n && (!o || s));
        !           525:   regs.n = n;
        !           526:   regs.v = ((!s && o && !n) || (s && !o && n));
        !           527: }
        !           528: 
        !           529: static inline void setflags_logical(ULONG newv, const ULONG mask)
        !           530: {
        !           531:   newv &= mask;
        !           532:   regs.z = newv == 0;
        !           533:   regs.n = newv >> mask2shift(mask);
        !           534:   regs.v = regs.c = 0;
        !           535: }
        !           536: 
        !           537: static bool cctrue(const int cc)
        !           538: {
        !           539:   switch(cc){
        !           540:   case 0: return true;                         // T
        !           541:   case 1: return false;                        // F
        !           542:   case 2: return !regs.c && !regs.z;           // HI
        !           543:   case 3: return regs.c || regs.z;             // LS
        !           544:   case 4: return !regs.c;                      // CC
        !           545:   case 5: return regs.c;                       // CS
        !           546:   case 6: return !regs.z;                      // NE
        !           547:   case 7: return regs.z;                       // EQ
        !           548:   case 8: return !regs.v;                      // VC
        !           549:   case 9: return regs.v;                       // VV
        !           550:   case 10:return !regs.n;                      // PL
        !           551:   case 11:return regs.n;                       // MI
        !           552:   case 12:return regs.n == regs.v;             // GE
        !           553:   case 13:return regs.n != regs.v;             // LT
        !           554:   case 14:return !regs.z && (regs.n == regs.v);// GT
        !           555:   case 15:return regs.z || (regs.n != regs.v); // LE
        !           556:   }
        !           557:   abort();
        !           558:   return 0;
        !           559: }
        !           560: 
        !           561: static void SuperState()
        !           562: {
        !           563:   if (!regs.s){
        !           564:     regs.s = 1; 
        !           565:     regs.t = 0;
        !           566:     CPTR temp = regs.usp;
        !           567:     regs.usp = regs.a[7];
        !           568:     regs.a[7] = temp;
        !           569:   }
        !           570: }
        !           571: 
        !           572: static void UserState()
        !           573: {
        !           574:   if (regs.s){
        !           575:     regs.s = 0; 
        !           576:  //   regs.t = 0;
        !           577:     CPTR temp = regs.usp;
        !           578:     regs.usp = regs.a[7];
        !           579:     regs.a[7] = temp;
        !           580:   }
        !           581: }
        !           582: 
        !           583: static void MakeSR()
        !           584: {
        !           585:   regs.sr = (regs.t << 15) | (regs.s << 13) | (regs.intmask << 8)
        !           586:     | (regs.x << 4) | (regs.n << 3) | (regs.z << 2) | (regs.v << 1) 
        !           587:       |  regs.c;
        !           588: }
        !           589: 
        !           590: static void MakeFromSR()
        !           591: {
        !           592:   int olds = regs.s;
        !           593: 
        !           594:   regs.t = (regs.sr >> 15) & 1;
        !           595:   regs.s = (regs.sr >> 13) & 1;
        !           596:   regs.intmask = (regs.sr >> 8) & 7;
        !           597:   regs.x = (regs.sr >> 4) & 1;
        !           598:   regs.n = (regs.sr >> 3) & 1;
        !           599:   regs.z = (regs.sr >> 2) & 1;
        !           600:   regs.v = (regs.sr >> 1) & 1;
        !           601:   regs.c = regs.sr & 1;
        !           602:   if (olds != regs.s) {
        !           603:     cout << "Mode switch!\n";
        !           604:     regs.s = olds; 
        !           605:     if (regs.s) UserState(); else SuperState();
        !           606:   }
        !           607: }
        !           608: 
        !           609: static void Exception(int nr, int newimask=-1)
        !           610: {
        !           611:   MakeSR();
        !           612:   SuperState();
        !           613:   if (newimask != -1) regs.intmask = newimask;
        !           614:   addr_mode pda7(Apdi,7);
        !           615:   effadr lea = GetEA(pda7,0xffffffff);
        !           616:   effadr wea = GetEA(pda7,0xffff);
        !           617:   StoreToEA(wea,regs.sr);
        !           618:   StoreToEA(lea,regs.pc);
        !           619:   regs.pc = (mem.get_word(4*nr) << 16) + mem.get_word(4*nr+2);
        !           620: }
        !           621: 
        !           622: static void Interrupt(int nr)
        !           623: {
        !           624:   assert(nr < 8 && nr >= 0);
        !           625:  //  regs.intmask = nr;
        !           626:   Exception(nr+24,nr);
        !           627: }
        !           628: 
        !           629:  /*
        !           630:   * instruction emulations
        !           631:   */
        !           632: 
        !           633: static instr_result INST_ILLG(const instr_params &)
        !           634: {
        !           635:   regs.pc -= 2;
        !           636:   
        !           637:   Exception(4);
        !           638: }
        !           639: 
        !           640: static instr_result INST_NIMP(const instr_params &p)
        !           641: {
        !           642:   cout << "unimplemented (020 ??) instruction: " 
        !           643:     << mem.get_word(regs.pc-2) << "\n";
        !           644:   INST_ILLG(p);
        !           645: }
        !           646: 
        !           647: static instr_result INST_OR(const instr_params &p)
        !           648: {
        !           649:   effadr src = GetEA(p.src, p.mask);
        !           650:   ULONG srcv = GetFromEA(src);
        !           651:   effadr dst = GetEA(p.dest, p.mask);
        !           652:   ULONG dstv = GetFromEA(dst);
        !           653:   dstv |= srcv;
        !           654:   setflags_logical(dstv, p.mask);
        !           655:   StoreToEA(dst,dstv);
        !           656: }
        !           657: 
        !           658: static instr_result INST_AND(const instr_params &p)
        !           659: {
        !           660:   effadr src = GetEA(p.src, p.mask);
        !           661:   ULONG srcv = GetFromEA(src);
        !           662:   effadr dst = GetEA(p.dest, p.mask);
        !           663:   ULONG dstv = GetFromEA(dst);
        !           664:   dstv &= srcv;
        !           665:   setflags_logical(dstv, p.mask);
        !           666:   StoreToEA(dst,dstv);
        !           667: }
        !           668: 
        !           669: static instr_result INST_EOR(const instr_params &p)
        !           670: {
        !           671:   effadr src = GetEA(p.src, p.mask);
        !           672:   ULONG srcv = GetFromEA(src);
        !           673:   effadr dst = GetEA(p.dest, p.mask);
        !           674:   ULONG dstv = GetFromEA(dst);
        !           675:   dstv ^= srcv;
        !           676:   setflags_logical(dstv, p.mask);
        !           677:   StoreToEA(dst,dstv);
        !           678: }
        !           679: 
        !           680: static instr_result INST_CMP(const instr_params &p)
        !           681: {
        !           682:   effadr src = GetEA(p.src, p.mask);
        !           683:   ULONG srcv = GetFromEA(src);
        !           684:   effadr dst = GetEA(p.dest, p.mask);
        !           685:   ULONG dstv = GetFromEA(dst);
        !           686:   ULONG newv = dstv - srcv;
        !           687:   setflags_cmp(srcv, dstv, newv);
        !           688: }
        !           689: 
        !           690: static instr_result INST_ADD(const instr_params &p)
        !           691: {
        !           692:   effadr src = GetEA(p.src, p.mask);
        !           693:   ULONG srcv = GetFromEA(src);
        !           694:   effadr dst = GetEA(p.dest, p.mask);
        !           695:   ULONG dstv = GetFromEA(dst);
        !           696:   ULONG newv = dstv + srcv;
        !           697:   setflags_add(srcv, dstv, newv);
        !           698:   StoreToEA(dst,newv);
        !           699: }
        !           700: 
        !           701: static instr_result INST_SUB(const instr_params &p)
        !           702: {
        !           703:   effadr src = GetEA(p.src, p.mask);
        !           704:   ULONG srcv = GetFromEA(src);
        !           705:   effadr dst = GetEA(p.dest, p.mask);
        !           706:   ULONG dstv = GetFromEA(dst);
        !           707:   ULONG newv = dstv - srcv;
        !           708:   setflags_sub(srcv, dstv, newv);
        !           709:   StoreToEA(dst,newv);
        !           710: }
        !           711: 
        !           712: static instr_result INST_ADDX(const instr_params &p)
        !           713: {
        !           714:   effadr src = GetEA(p.src, p.mask);
        !           715:   ULONG srcv = GetFromEA(src);
        !           716:   effadr dst = GetEA(p.dest, p.mask);
        !           717:   ULONG dstv = GetFromEA(dst);
        !           718:   ULONG newv = dstv + srcv + regs.x;
        !           719:   setflags_add(srcv, dstv, newv);
        !           720:   StoreToEA(dst,newv);
        !           721: }
        !           722: 
        !           723: static instr_result INST_SUBX(const instr_params &p)
        !           724: {
        !           725:   effadr src = GetEA(p.src, p.mask);
        !           726:   ULONG srcv = GetFromEA(src);
        !           727:   effadr dst = GetEA(p.dest, p.mask);
        !           728:   ULONG dstv = GetFromEA(dst);
        !           729:   ULONG newv = dstv - srcv - regs.x;
        !           730:   setflags_sub(srcv, dstv, newv);
        !           731:   StoreToEA(dst,newv);
        !           732: }
        !           733: 
        !           734: static instr_result INST_ADDA(const instr_params &p)
        !           735: {
        !           736:   effadr src = GetEA(p.src, p.mask);
        !           737:   ULONG srcv = GetFromEA(src);
        !           738:   effadr dst = GetEA(p.dest, 0xffffffff);
        !           739:   ULONG dstv = GetFromEA(dst);
        !           740: //  if (src.szmask == 0xffff) srcv = ExtendWord(srcv);
        !           741:   StoreToEA(dst,dstv + srcv);
        !           742: }
        !           743: 
        !           744: static instr_result INST_SUBA(const instr_params &p)
        !           745: {
        !           746:   effadr src = GetEA(p.src, p.mask);
        !           747:   ULONG srcv = GetFromEA(src);
        !           748:   effadr dst = GetEA(p.dest, 0xffffffff);
        !           749:   ULONG dstv = GetFromEA(dst);
        !           750: //  if (src.szmask == 0xffff) srcv = ExtendWord(srcv);
        !           751:   StoreToEA(dst,dstv - srcv);
        !           752: }
        !           753: 
        !           754: static instr_result INST_CMPA(const instr_params &p)
        !           755: {
        !           756:   effadr src = GetEA(p.src, p.mask);
        !           757:   ULONG srcv = GetFromEA(src);
        !           758:   effadr dst = GetEA(p.dest, 0xffffffff);
        !           759:   ULONG dstv = GetFromEA(dst);
        !           760:   ULONG newv = dstv - srcv;
        !           761:   setflags_cmp(srcv, dstv, newv);
        !           762: }
        !           763: 
        !           764: static instr_result INST_CHK(const instr_params &p)
        !           765: {
        !           766:   cout << "CHK occurred\n";
        !           767:   INST_ILLG(p); // FIXME
        !           768: }
        !           769: 
        !           770: static instr_result INST_EXGL(const instr_params &p)
        !           771: {
        !           772:   effadr src = GetEA(p.src, p.mask);
        !           773:   ULONG srcv = GetFromEA(src);
        !           774:   effadr dst = GetEA(p.dest, p.mask);
        !           775:   ULONG dstv = GetFromEA(dst);
        !           776:   StoreToEA(dst,srcv);
        !           777:   StoreToEA(src,dstv);  
        !           778: }
        !           779: 
        !           780: static instr_result INST_LEA(const instr_params &p)
        !           781: {
        !           782:   effadr src = GetEA(p.src, p.mask);
        !           783:   effadr dst = GetEA(p.dest, p.mask);
        !           784:   StoreToEA(dst,RetrieveEA(src));
        !           785: }
        !           786: 
        !           787: static instr_result INST_MOVE(const instr_params &p)
        !           788: {
        !           789:   effadr src = GetEA(p.src, p.mask);
        !           790:   ULONG srcv = GetFromEA(src);
        !           791:   effadr dst = GetEA(p.dest, p.mask);
        !           792:   setflags_logical(srcv,p.mask);
        !           793:   StoreToEA(dst,srcv);
        !           794: }
        !           795: 
        !           796: static instr_result INST_MOVEQ(const instr_params &p)
        !           797: {
        !           798:   effadr src = GetEA(p.src, p.mask);
        !           799:   effadr dst = GetEA(p.dest, p.mask);
        !           800:   ULONG srcv = ExtendByte(GetFromEA(src));
        !           801:   setflags_logical(srcv,p.mask);
        !           802:   StoreToEA(dst,srcv);
        !           803: }
        !           804: 
        !           805: static instr_result INST_MOVEA(const instr_params &p)
        !           806: {
        !           807:   effadr src = GetEA(p.src, p.mask);
        !           808:   ULONG srcv = GetFromEA(src);
        !           809:   effadr dst = GetEA(p.dest, p.mask);
        !           810:   StoreToEA(dst,srcv);
        !           811: }
        !           812: 
        !           813: static instr_result INST_BTST(const instr_params &p)
        !           814: {
        !           815:   effadr src = GetEA(p.src, p.mask);
        !           816:   ULONG srcv = GetFromEA(src);
        !           817:   effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
        !           818:   ULONG dstv = GetFromEA(dst);
        !           819:   if (p.dest.mode == Dreg) {
        !           820:     srcv &= 31;
        !           821:   } else {
        !           822:     srcv &= 7; 
        !           823:   }
        !           824:   regs.z = !(dstv & (1 << srcv));
        !           825: }
        !           826: 
        !           827: static instr_result INST_BCLR(const instr_params &p)
        !           828: {
        !           829:   effadr src = GetEA(p.src, p.mask);
        !           830:   ULONG srcv = GetFromEA(src);
        !           831:   effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
        !           832:   ULONG dstv = GetFromEA(dst);
        !           833:   if (p.dest.mode == Dreg) {
        !           834:     srcv &= 31;
        !           835:   } else {
        !           836:     srcv &= 7; 
        !           837:   }
        !           838:   regs.z = !(dstv & (1 << srcv));
        !           839:   StoreToEA(dst,dstv & ~(1 << srcv));
        !           840: }
        !           841: 
        !           842: static instr_result INST_BSET(const instr_params &p)
        !           843: {
        !           844:   effadr src = GetEA(p.src, p.mask);
        !           845:   ULONG srcv = GetFromEA(src);
        !           846:   effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
        !           847:   ULONG dstv = GetFromEA(dst);
        !           848:   if (p.dest.mode == Dreg) {
        !           849:     srcv &= 31; 
        !           850:   } else {
        !           851:     srcv &= 7; 
        !           852:   }
        !           853:   regs.z = !(dstv & (1 << srcv));
        !           854:   StoreToEA(dst,dstv | (1 << srcv));
        !           855: }
        !           856: 
        !           857: static instr_result INST_BCHG(const instr_params &p)
        !           858: {
        !           859:   effadr src = GetEA(p.src, p.mask);
        !           860:   ULONG srcv = GetFromEA(src);
        !           861:   effadr dst = GetEA(p.dest, p.dest.mode == Dreg ? 0xffffffff : 0xff);
        !           862:   ULONG dstv = GetFromEA(dst);
        !           863:   if (p.dest.mode == Dreg) {
        !           864:     srcv &= 31; 
        !           865:   } else {
        !           866:     srcv &= 7; 
        !           867:   }
        !           868:   regs.z = !(dstv & (1 << srcv));
        !           869:   StoreToEA(dst,dstv ^ (1 << srcv));
        !           870: }
        !           871: 
        !           872: static instr_result INST_NEG(const instr_params &p)
        !           873: {
        !           874:   effadr ea = GetEA(p.src, p.mask);
        !           875:   ULONG val = GetFromEA(ea);
        !           876:   ULONG newv = -val;
        !           877:   setflags_sub(val, 0, newv);
        !           878:   StoreToEA(ea,newv);
        !           879: }
        !           880: 
        !           881: static instr_result INST_NEGX(const instr_params &p)
        !           882: {
        !           883:   effadr ea = GetEA(p.src, p.mask);
        !           884:   ULONG val = GetFromEA(ea);
        !           885:   ULONG newv = -val-regs.x;
        !           886:   setflags_sub(val, 0, newv);
        !           887:   StoreToEA(ea,newv);
        !           888: }
        !           889: 
        !           890: static instr_result INST_NOT(const instr_params &p)
        !           891: {
        !           892:   effadr ea = GetEA(p.src, p.mask);
        !           893:   ULONG val = GetFromEA(ea);
        !           894:   ULONG newv = ~val;
        !           895:   setflags_logical(newv,p.mask);
        !           896:   StoreToEA(ea,newv);
        !           897: }
        !           898: 
        !           899: static instr_result INST_CLR(const instr_params &p)
        !           900: {
        !           901:   effadr ea = GetEA(p.src, p.mask);
        !           902:   ULONG val = GetFromEA(ea);        // not a bug, a feature!
        !           903:   ULONG newv = 0;
        !           904:   setflags_logical(newv,p.mask);
        !           905:   StoreToEA(ea,newv);
        !           906: }
        !           907: 
        !           908: static instr_result INST_TST(const instr_params &p)
        !           909: {
        !           910:   effadr ea = GetEA(p.src, p.mask);
        !           911:   ULONG val = GetFromEA(ea);
        !           912:   setflags_logical(val,p.mask);
        !           913: }
        !           914: 
        !           915: static instr_result INST_SWAP(const instr_params &p)
        !           916: {
        !           917:   effadr ea = GetEA(p.src, p.mask);
        !           918:   ULONG val = GetFromEA(ea);
        !           919:   val = (val >> 16) | (val << 16);
        !           920:   StoreToEA(ea, val);
        !           921:   setflags_logical(val,p.mask);
        !           922: }
        !           923: 
        !           924: static instr_result INST_EXTW(const instr_params &p)
        !           925: {
        !           926:   effadr ea = GetEA(p.src, p.mask);
        !           927:   ULONG val = GetFromEA(ea);
        !           928:   StoreToEA(ea, ExtendByte(val));
        !           929: }
        !           930: 
        !           931: static instr_result INST_EXTL(const instr_params &p)
        !           932: {
        !           933:   effadr ea = GetEA(p.src, p.mask);
        !           934:   ULONG val = GetFromEA(ea);
        !           935:   StoreToEA(ea, ExtendWord(val));
        !           936: }
        !           937: 
        !           938: static instr_result INST_Scc(const instr_params &p)
        !           939: {
        !           940:   effadr ea = GetEA(p.src, p.mask);
        !           941:   StoreToEA(ea,cctrue(p.dest.reg) ? 0xff : 0);
        !           942: }
        !           943: 
        !           944: static instr_result INST_ABCD(const instr_params &p)
        !           945: {
        !           946:   abort(); // FIXME
        !           947: }
        !           948: 
        !           949: static instr_result INST_SBCD(const instr_params &p)
        !           950: {
        !           951:   abort(); // FIXME
        !           952: }
        !           953: 
        !           954: static instr_result INST_NBCD(const instr_params &p)
        !           955: {
        !           956:   abort(); // FIXME
        !           957: }
        !           958: 
        !           959: static instr_result INST_NOP(const instr_params &)
        !           960: {
        !           961:   // :-D
        !           962: }
        !           963: 
        !           964: static instr_result INST_RESET(const instr_params &)
        !           965: {
        !           966:   customreset();
        !           967: }
        !           968: 
        !           969: static instr_result INST_STOP(const instr_params &p)
        !           970: {
        !           971:   if ((p.mask != 0xff) && !regs.s) {
        !           972:     regs.pc -= 2;
        !           973:     Exception(8);
        !           974:   } else {
        !           975:     effadr ea = GetEA(p.src, p.mask);
        !           976:     regs.sr = GetFromEA(ea);
        !           977:     MakeFromSR();
        !           978:     regs.stopped = 1;
        !           979:   }
        !           980: }
        !           981: 
        !           982: static instr_result INST_TRAPV(const instr_params &)
        !           983: {
        !           984:   if (regs.v) Exception(7);
        !           985: }
        !           986: 
        !           987: static instr_result INST_TRAP(const instr_params &p)
        !           988: {
        !           989:   UWORD val = GetFromEA(GetEA(p.src,p.mask));
        !           990:   Exception(val+32);
        !           991: }
        !           992: 
        !           993: static instr_result INST_BSRB(const instr_params &p)
        !           994: {
        !           995:   effadr ea = GetEA(p.src, p.mask);
        !           996:   BYTE offset = GetFromEA(ea);
        !           997:   addr_mode pda7(Apdi,7);
        !           998:   effadr stackp = GetEA(pda7,0xffffffff);
        !           999:   StoreToEA(stackp,regs.pc);
        !          1000:   regs.pc += offset;
        !          1001: }
        !          1002: 
        !          1003: static instr_result INST_BccB(const instr_params &p)
        !          1004: {
        !          1005:   if (cctrue(p.dest.reg)){
        !          1006:     effadr ea = GetEA(p.src, p.mask);
        !          1007:     BYTE offset = GetFromEA(ea);
        !          1008:     regs.pc += offset;
        !          1009:   }
        !          1010: }
        !          1011: 
        !          1012: static instr_result INST_BSRW(const instr_params &p)
        !          1013: {
        !          1014:   effadr ea = GetEA(p.src, p.mask);
        !          1015:   WORD offset = GetFromEA(ea);
        !          1016:   addr_mode pda7(Apdi,7);
        !          1017:   effadr stackp = GetEA(pda7,0xffffffff);
        !          1018:   StoreToEA(stackp,regs.pc);
        !          1019:   regs.pc += offset - 2;
        !          1020: }
        !          1021: 
        !          1022: static instr_result INST_BccW(const instr_params &p)
        !          1023: {
        !          1024:   effadr ea = GetEA(p.src, p.mask);
        !          1025:   WORD offset = GetFromEA(ea);
        !          1026:   if (cctrue(p.dest.reg)){
        !          1027:     regs.pc += offset - 2;
        !          1028:   }
        !          1029: }
        !          1030: 
        !          1031: static instr_result INST_DBcc(const instr_params &p)
        !          1032: {
        !          1033:   WORD offset = nextiword();
        !          1034: 
        !          1035:   if (!cctrue(p.dest.reg)){
        !          1036:     effadr ea = GetEA(p.src, p.mask); // safe inside if, can only be Dreg
        !          1037:     ULONG dr = GetFromEA(ea);
        !          1038:     if (dr--){
        !          1039:       regs.pc += offset - 2;
        !          1040:     }
        !          1041:     StoreToEA(ea,dr);
        !          1042:   }
        !          1043: }
        !          1044: 
        !          1045: static instr_result INST_JMP(const instr_params &p)
        !          1046: {
        !          1047:   effadr ea = GetEA(p.src, p.mask);
        !          1048:   regs.pc = RetrieveEA(ea);
        !          1049: }
        !          1050: 
        !          1051: static instr_result INST_JSR(const instr_params &p)
        !          1052: {
        !          1053:   effadr ea = GetEA(p.src, p.mask);
        !          1054: 
        !          1055:   addr_mode pda7(Apdi,7);
        !          1056:   effadr stackp = GetEA(pda7,0xffffffff);
        !          1057:   StoreToEA(stackp, regs.pc);
        !          1058: 
        !          1059:   regs.pc = RetrieveEA(ea);
        !          1060: }
        !          1061: 
        !          1062: static instr_result INST_RTE(const instr_params &)
        !          1063: {
        !          1064:   addr_mode a7pi(Aipi,7);
        !          1065:   effadr stackp = GetEA(a7pi,0xffff);
        !          1066:   regs.sr = GetFromEA(stackp);
        !          1067:   stackp = GetEA(a7pi,0xffffffff);
        !          1068:   regs.pc = GetFromEA(stackp);
        !          1069:   MakeFromSR();
        !          1070: }
        !          1071: 
        !          1072: static instr_result INST_RTD(const instr_params &p)
        !          1073: {
        !          1074:   INST_NIMP(p); // FIXME
        !          1075: }
        !          1076: 
        !          1077: static instr_result INST_RTS(const instr_params &)
        !          1078: {
        !          1079:   addr_mode a7pi(Aipi,7);
        !          1080:   effadr stackp = GetEA(a7pi,0xffffffff);
        !          1081:   regs.pc = GetFromEA(stackp);
        !          1082: }
        !          1083: 
        !          1084: static instr_result INST_RTR(const instr_params &)
        !          1085: {
        !          1086:   MakeSR();
        !          1087:   regs.sr &= 0xff00;
        !          1088:   addr_mode a7pi(Aipi,7);
        !          1089:   effadr stackp = GetEA(a7pi,0xffff);
        !          1090:   regs.sr |= GetFromEA(stackp) & 0xff;
        !          1091:   stackp = GetEA(a7pi,0xffffffff);
        !          1092:   regs.pc = GetFromEA(stackp);
        !          1093:   MakeFromSR();
        !          1094: }
        !          1095: 
        !          1096: static instr_result INST_LINK(const instr_params &p)
        !          1097: {
        !          1098:   addr_mode pda7(Apdi,7);
        !          1099:   effadr stackp = GetEA(pda7,0xffffffff);
        !          1100:   effadr ar = GetEA(p.src, 0xffffffff);
        !          1101:   StoreToEA(stackp, GetFromEA(ar));
        !          1102:   StoreToEA(ar, regs.a[7]);
        !          1103:   effadr ea = GetEA(p.dest, p.mask);
        !          1104:   ULONG offset = GetFromEA(ea);
        !          1105: //  if (p.mask = 0xffff) offset = ExtendWord(offset);
        !          1106:   regs.a[7] += offset;
        !          1107: }
        !          1108: 
        !          1109: static instr_result INST_UNLK(const instr_params &p)
        !          1110: {
        !          1111:   effadr ar = GetEA(p.src, 0xffffffff);
        !          1112:   regs.a[7] = GetFromEA(ar);
        !          1113: 
        !          1114:   addr_mode a7pi(Aipi,7);
        !          1115:   effadr stackp = GetEA(a7pi,0xffffffff);
        !          1116:   StoreToEA(ar, GetFromEA(stackp));
        !          1117: }
        !          1118: 
        !          1119: static instr_result INST_MULU(const instr_params &p)
        !          1120: {
        !          1121:   effadr src = GetEA(p.src, p.mask);
        !          1122:   UWORD srcv = GetFromEA(src);
        !          1123:   effadr dst = GetEA(p.dest, p.mask);
        !          1124:   UWORD dstv = GetFromEA(dst);
        !          1125:   ULONG newv = (ULONG)dstv * (ULONG)srcv;
        !          1126:   setflags_logical(newv, 0xffffffff);
        !          1127:   dst.szmask = 0xffffffff;
        !          1128:   StoreToEA(dst,newv);
        !          1129: }
        !          1130: 
        !          1131: static instr_result INST_MULS(const instr_params &p)
        !          1132: {
        !          1133:   effadr src = GetEA(p.src, p.mask);
        !          1134:   WORD srcv = GetFromEA(src);
        !          1135:   effadr dst = GetEA(p.dest, p.mask);
        !          1136:   WORD dstv = GetFromEA(dst);
        !          1137:   ULONG newv = (LONG)dstv * (LONG)srcv;
        !          1138:   setflags_logical(newv, 0xffffffff);
        !          1139:   dst.szmask = 0xffffffff;
        !          1140:   StoreToEA(dst,newv);
        !          1141: }
        !          1142: 
        !          1143: static instr_result INST_DIVU(const instr_params &p)
        !          1144: {
        !          1145:   effadr src = GetEA(p.src, 0xffff);
        !          1146:   UWORD srcv = GetFromEA(src);
        !          1147:   effadr dst = GetEA(p.dest, 0xffffffff);
        !          1148:   ULONG dstv = GetFromEA(dst);
        !          1149:   if (srcv == 0){
        !          1150:     // FOO !
        !          1151:   } else {
        !          1152:     ULONG newv = dstv / srcv;
        !          1153:     UWORD rem = dstv % srcv;
        !          1154:     setflags_logical(newv, 0xffff);
        !          1155:     regs.v = newv > 0xffff;
        !          1156:     newv = (newv & 0xffff) | (rem << 16);
        !          1157:     StoreToEA(dst,newv);
        !          1158:   }
        !          1159: }
        !          1160: 
        !          1161: static instr_result INST_DIVS(const instr_params &p)
        !          1162: {
        !          1163:   effadr src = GetEA(p.src, 0xffff);
        !          1164:   WORD srcv = GetFromEA(src);
        !          1165:   effadr dst = GetEA(p.dest, 0xffffffff);
        !          1166:   LONG dstv = GetFromEA(dst);
        !          1167:   if (srcv == 0){
        !          1168:     // FOO !
        !          1169:   } else {
        !          1170:     LONG newv = dstv / srcv;
        !          1171:     UWORD rem = dstv % srcv;
        !          1172:     if ((rem & 0x8000) != (newv & 0x8000)) rem = -rem;
        !          1173:     setflags_logical(newv, 0xffff);
        !          1174:     regs.v = (newv & 0xffff0000) && (newv & 0xffff0000) != 0xffff0000;
        !          1175:     newv = (newv & 0xffff) | (rem << 16);
        !          1176:     StoreToEA(dst,newv);
        !          1177:   }
        !          1178: }
        !          1179: 
        !          1180: static instr_result INST_ASL(const instr_params &p)
        !          1181: {
        !          1182:   effadr src = GetEA(p.src, p.mask);
        !          1183:   effadr dst = GetEA(p.dest, p.mask);
        !          1184:   ULONG cnt = GetFromEA(src) & 31;
        !          1185:   ULONG data = GetFromEA(dst) & p.mask;
        !          1186: 
        !          1187:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1188:   ULONG sign = data & cmask;
        !          1189:   regs.v = 0;
        !          1190:   for (;cnt;--cnt){
        !          1191:     regs.c = regs.x = (data & cmask) != 0;
        !          1192:     data <<= 1;
        !          1193:     if ((data & cmask) != sign) regs.v = 1; 
        !          1194:   }
        !          1195:   regs.n = (data & cmask) != 0;
        !          1196:   regs.z = (data & p.mask) == 0;
        !          1197:   StoreToEA(dst,data);
        !          1198: }
        !          1199: 
        !          1200: static instr_result INST_ASR(const instr_params &p)
        !          1201: {
        !          1202:   effadr src = GetEA(p.src, p.mask);
        !          1203:   effadr dst = GetEA(p.dest, p.mask);
        !          1204:   ULONG cnt = GetFromEA(src) & 31;
        !          1205:   ULONG data = GetFromEA(dst) & p.mask;
        !          1206: 
        !          1207:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1208:   ULONG sign = data & cmask;
        !          1209:   regs.v = 0;
        !          1210:   for (;cnt;--cnt){
        !          1211:     regs.c = regs.x = data & 1;
        !          1212:     data = (data >> 1) | sign;
        !          1213:   }
        !          1214:   regs.n = sign != 0;
        !          1215:   regs.z = (data & p.mask) == 0;
        !          1216:   StoreToEA(dst,data);
        !          1217: }
        !          1218: 
        !          1219: static instr_result INST_LSR(const instr_params &p)
        !          1220: {
        !          1221:   effadr src = GetEA(p.src, p.mask);
        !          1222:   effadr dst = GetEA(p.dest, p.mask);
        !          1223:   ULONG cnt = GetFromEA(src) & 31;
        !          1224:   ULONG data = GetFromEA(dst) & p.mask; 
        !          1225: 
        !          1226:   int carry = 0;
        !          1227:   for (;cnt;--cnt){
        !          1228:     carry = data & 1;
        !          1229:     data >>= 1;
        !          1230:   }
        !          1231:   setflags_logical(data,p.mask);
        !          1232:   regs.c = regs.x = carry;
        !          1233:   StoreToEA(dst,data);
        !          1234: }
        !          1235: 
        !          1236: static instr_result INST_LSL(const instr_params &p)
        !          1237: {
        !          1238:   effadr src = GetEA(p.src, p.mask);
        !          1239:   effadr dst = GetEA(p.dest, p.mask);
        !          1240:   ULONG cnt = GetFromEA(src) & 31;
        !          1241:   ULONG data = GetFromEA(dst) & p.mask;
        !          1242: 
        !          1243:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1244:   ULONG carry = 0;
        !          1245: 
        !          1246:   for (;cnt;--cnt){
        !          1247:     carry = data & cmask;
        !          1248:     data <<= 1;
        !          1249:   }
        !          1250:   setflags_logical(data,p.mask);
        !          1251:   regs.c = regs.x = carry != 0;
        !          1252:   StoreToEA(dst,data);
        !          1253: }
        !          1254: 
        !          1255: static instr_result INST_ROR(const instr_params &p)
        !          1256: {
        !          1257:   effadr src = GetEA(p.src, p.mask);
        !          1258:   effadr dst = GetEA(p.dest, p.mask);
        !          1259:   ULONG cnt = GetFromEA(src) & 31;
        !          1260:   ULONG data = GetFromEA(dst) & p.mask;
        !          1261: 
        !          1262:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1263:   int carry = 0;
        !          1264:   for (;cnt;--cnt){
        !          1265:     carry = data & 1;
        !          1266:     data >>= 1;
        !          1267:     if (carry) data |= cmask;
        !          1268:   }
        !          1269:   setflags_logical(data,p.mask);
        !          1270:   regs.c = carry;
        !          1271:   StoreToEA(dst,data);
        !          1272: }
        !          1273: 
        !          1274: static instr_result INST_ROL(const instr_params &p)
        !          1275: {
        !          1276:   effadr src = GetEA(p.src, p.mask);
        !          1277:   effadr dst = GetEA(p.dest, p.mask);
        !          1278:   ULONG cnt = GetFromEA(src) & 31;
        !          1279:   ULONG data = GetFromEA(dst) & p.mask;
        !          1280: 
        !          1281:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1282:   ULONG carry = 0;
        !          1283: 
        !          1284:   for (;cnt;--cnt){
        !          1285:     carry = data & cmask;
        !          1286:     data <<= 1;
        !          1287:     if (carry) data |= 1;
        !          1288:   }
        !          1289:   setflags_logical(data,p.mask);
        !          1290:   regs.c = carry != 0;
        !          1291:   StoreToEA(dst,data);
        !          1292: }
        !          1293: 
        !          1294: static instr_result INST_ROXR(const instr_params &p)
        !          1295: {
        !          1296:   effadr src = GetEA(p.src, p.mask);
        !          1297:   effadr dst = GetEA(p.dest, p.mask);
        !          1298:   ULONG cnt = GetFromEA(src) & 31;
        !          1299:   ULONG data = GetFromEA(dst) & p.mask;
        !          1300: 
        !          1301:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1302:   int carry = 0;
        !          1303:   for (;cnt;--cnt){
        !          1304:     carry = data & 1;
        !          1305:     data >>= 1;
        !          1306:     if (regs.x) data |= cmask;
        !          1307:     regs.x = carry;
        !          1308:   }
        !          1309:   setflags_logical(data,p.mask);
        !          1310:   regs.c = regs.x = carry;
        !          1311:   StoreToEA(dst,data);
        !          1312: }
        !          1313: 
        !          1314: static instr_result INST_ROXL(const instr_params &p)
        !          1315: {
        !          1316:   effadr src = GetEA(p.src, p.mask);
        !          1317:   effadr dst = GetEA(p.dest, p.mask);
        !          1318:   ULONG cnt = GetFromEA(src) & 31;
        !          1319:   ULONG data = GetFromEA(dst) & p.mask;
        !          1320: 
        !          1321:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1322:   int carry = 0;
        !          1323: 
        !          1324:   for (;cnt;--cnt){
        !          1325:     carry = data & cmask;
        !          1326:     data <<= 1;
        !          1327:     if (regs.x) data |= 1;
        !          1328:     regs.x = carry != 0;
        !          1329:   }
        !          1330:   setflags_logical(data,p.mask);
        !          1331:   regs.c = regs.x = carry != 0;
        !          1332:   StoreToEA(dst,data);
        !          1333: }
        !          1334: 
        !          1335: static instr_result INST_ASL1(const instr_params &p)
        !          1336: {
        !          1337:   effadr dst = GetEA(p.dest, p.mask);
        !          1338:   ULONG data = GetFromEA(dst) & p.mask;
        !          1339: 
        !          1340:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1341:   ULONG sign = data & cmask;
        !          1342:   regs.v = 0;
        !          1343:   regs.c = regs.x = sign != 0;
        !          1344:   data <<= 1;
        !          1345:   if ((data & cmask) != sign) regs.v = 1; 
        !          1346:   regs.n = (data & cmask) != 0;
        !          1347:   regs.z = (data & p.mask) == 0;
        !          1348:   StoreToEA(dst,data);
        !          1349: }
        !          1350: 
        !          1351: static instr_result INST_ASR1(const instr_params &p)
        !          1352: {
        !          1353:   effadr dst = GetEA(p.dest, p.mask);
        !          1354:   ULONG data = GetFromEA(dst) & p.mask;
        !          1355: 
        !          1356:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1357:   ULONG sign = data & cmask;
        !          1358:   regs.v = 0;
        !          1359:   regs.c = regs.x = data & 1;
        !          1360:   data = (data >> 1) | sign;
        !          1361:   regs.n = sign != 0;
        !          1362:   regs.z = (data & p.mask) == 0;
        !          1363:   StoreToEA(dst,data);
        !          1364: }
        !          1365: 
        !          1366: static instr_result INST_LSR1(const instr_params &p)
        !          1367: {
        !          1368:   effadr dst = GetEA(p.dest, p.mask);
        !          1369:   ULONG data = GetFromEA(dst) & p.mask;
        !          1370:   int carry = data & 1;
        !          1371:   data >>= 1;
        !          1372:   setflags_logical(data, p.mask);
        !          1373:   regs.c = regs.x = carry;
        !          1374:   StoreToEA(dst,data);
        !          1375: }
        !          1376: 
        !          1377: static instr_result INST_LSL1(const instr_params &p)
        !          1378: {
        !          1379:   effadr dst = GetEA(p.dest, p.mask);
        !          1380:   ULONG data = GetFromEA(dst) & p.mask;
        !          1381: 
        !          1382:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1383:   ULONG carry = data & cmask;
        !          1384:   data <<= 1;
        !          1385:   setflags_logical(data,p.mask);
        !          1386:   regs.c = regs.x = carry != 0;
        !          1387:   StoreToEA(dst,data);
        !          1388: }
        !          1389: 
        !          1390: static instr_result INST_ROR1(const instr_params &p)
        !          1391: {
        !          1392:   effadr dst = GetEA(p.dest, p.mask);
        !          1393:   ULONG data = GetFromEA(dst) & p.mask;
        !          1394: 
        !          1395:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1396:   int carry = data & 1;
        !          1397:   data >>= 1;
        !          1398:   if (carry) data |= cmask;
        !          1399:   setflags_logical(data,p.mask);
        !          1400:   regs.c = carry;
        !          1401:   StoreToEA(dst,data);
        !          1402: }
        !          1403: 
        !          1404: static instr_result INST_ROL1(const instr_params &p)
        !          1405: {
        !          1406:   effadr dst = GetEA(p.dest, p.mask);
        !          1407:   ULONG data = GetFromEA(dst) & p.mask;
        !          1408: 
        !          1409:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1410:   ULONG carry = data & cmask;
        !          1411: 
        !          1412:   data <<= 1;
        !          1413:   if (carry) data |= 1;
        !          1414:   setflags_logical(data,p.mask);
        !          1415:   regs.c = carry != 0;
        !          1416:   StoreToEA(dst,data);
        !          1417: }
        !          1418: 
        !          1419: static instr_result INST_ROXR1(const instr_params &p)
        !          1420: {
        !          1421:   effadr dst = GetEA(p.dest, p.mask);
        !          1422:   ULONG data = GetFromEA(dst) & p.mask;
        !          1423: 
        !          1424:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1425:   int carry = data & 1;
        !          1426:   data >>= 1;
        !          1427:   if (regs.x) data |= cmask;
        !          1428: //  regs.x = carry;
        !          1429:   setflags_logical(data,p.mask);
        !          1430:   regs.c = regs.x = carry;
        !          1431:   StoreToEA(dst,data);
        !          1432: }
        !          1433: 
        !          1434: static instr_result INST_ROXL1(const instr_params &p)
        !          1435: {
        !          1436:   effadr dst = GetEA(p.dest, p.mask);
        !          1437:   ULONG data = GetFromEA(dst) & p.mask;
        !          1438: 
        !          1439:   ULONG cmask = 1 << mask2shift(p.mask);
        !          1440:   ULONG carry = data & cmask;
        !          1441: 
        !          1442:   data <<= 1;
        !          1443:   if (regs.x) data |= 1;
        !          1444: //  regs.x = carry != 0;
        !          1445:   
        !          1446:   setflags_logical(data,p.mask);
        !          1447:   regs.c = regs.x = carry != 0;
        !          1448:   StoreToEA(dst,data);
        !          1449: }
        !          1450: 
        !          1451: static instr_result INST_MOVECCREA(const instr_params &p)
        !          1452: {
        !          1453:   INST_NIMP(p); // FIXME
        !          1454: }
        !          1455: 
        !          1456: static instr_result INST_MOVESREA(const instr_params &p)
        !          1457: {
        !          1458:   effadr ea = GetEA(p.src, p.mask);
        !          1459:   MakeSR();
        !          1460:   StoreToEA(ea,regs.sr);
        !          1461: }
        !          1462: 
        !          1463: static instr_result INST_MOVEEACCR(const instr_params &p)
        !          1464: {
        !          1465:   MakeSR();
        !          1466:   regs.sr &= 0xFF00;
        !          1467:   effadr ea = GetEA(p.src, p.mask);
        !          1468:   regs.sr |= GetFromEA(ea) & 0xFF;
        !          1469:   MakeFromSR();
        !          1470: }
        !          1471: 
        !          1472: static instr_result INST_MOVEEASR(const instr_params &p)
        !          1473: {
        !          1474:   if ((p.mask != 0xff) && !regs.s) {
        !          1475:     regs.pc -= 2;
        !          1476:     Exception(8);
        !          1477:   } else {
        !          1478:     effadr ea = GetEA(p.src, p.mask);
        !          1479:     regs.sr = GetFromEA(ea);
        !          1480:     MakeFromSR();
        !          1481:   }
        !          1482: }
        !          1483: 
        !          1484: static instr_result INST_ORSR(const instr_params &p)
        !          1485: {
        !          1486:   if ((p.mask != 0xff) && !regs.s) {
        !          1487:     regs.pc -= 2;
        !          1488:     Exception(8);
        !          1489:   } else {
        !          1490:     MakeSR();
        !          1491:     effadr ea = GetEA(p.src, p.mask);
        !          1492:     regs.sr |= GetFromEA(ea);
        !          1493:     MakeFromSR();
        !          1494:   }
        !          1495: }
        !          1496: 
        !          1497: static instr_result INST_EORSR(const instr_params &p)
        !          1498: {
        !          1499:   if ((p.mask != 0xff) && !regs.s) {
        !          1500:     regs.pc -= 2;
        !          1501:     Exception(8);
        !          1502:   } else {
        !          1503:     MakeSR();
        !          1504:     effadr ea = GetEA(p.src, p.mask);
        !          1505:     regs.sr ^= GetFromEA(ea);
        !          1506:     MakeFromSR();
        !          1507:   }
        !          1508: }
        !          1509: 
        !          1510: static instr_result INST_ANDSR(const instr_params &p)
        !          1511: {
        !          1512:   if ((p.mask != 0xff) && !regs.s) {
        !          1513:     regs.pc -= 2;
        !          1514:     Exception(8);
        !          1515:   } else {
        !          1516:     MakeSR();
        !          1517:     effadr ea = GetEA(p.src, p.mask);
        !          1518:     regs.sr &= GetFromEA(ea);
        !          1519:     MakeFromSR();
        !          1520:   }
        !          1521: }
        !          1522: 
        !          1523: static instr_result INST_MOVEMEARL(const instr_params &p)
        !          1524: {
        !          1525:   int i;
        !          1526:   UWORD bitmask = nextiword();
        !          1527:   effadr ea = MGetEA(p.src, p.mask);
        !          1528:   for(i=0; i<8; i++) {
        !          1529:     if (bitmask & (1 << i)) {
        !          1530:       regs.d[i] = (regs.d[i] & ~p.mask) | (GetFromEA(ea) & p.mask);
        !          1531:       ea.addr += mask2len(p.mask);
        !          1532:     }
        !          1533:   }
        !          1534:   for(i=0; i<8; i++) {
        !          1535:     if (bitmask & (1 << (i + 8))) {
        !          1536:       regs.a[i] = Extend(GetFromEA(ea),p.mask);
        !          1537:       ea.addr += mask2len(p.mask);
        !          1538:     }
        !          1539:   }
        !          1540:   MCompleteEAToRL(ea, p.src, p.mask, bitmask);
        !          1541: }
        !          1542: 
        !          1543: static instr_result INST_MOVEMRLEA(const instr_params &p)
        !          1544: {
        !          1545:   int rd[8], ra[8], i, kludge;
        !          1546:   for(i=0;i<8;i++){
        !          1547:     rd[i] = regs.d[i]; ra[i] = regs.a[i];
        !          1548:   }
        !          1549:   UWORD bitmask = nextiword();
        !          1550:   effadr ea = MGetEA(p.src, p.mask);
        !          1551:   kludge = (p.src.mode == Apdi) ? 15 : 0;
        !          1552:   MCompleteEAFromRL(ea, p.src, p.mask, bitmask);
        !          1553:   for(i=0; i<8; i++) {
        !          1554:     if (bitmask & (1 << (i ^ kludge))) {
        !          1555:       StoreToEA(ea,rd[i]);
        !          1556:       ea.addr += mask2len(p.mask);
        !          1557:     }
        !          1558:   }
        !          1559:   for(i=0; i<8; i++) {
        !          1560:     if (bitmask & (1 << ((i + 8) ^ kludge))) {
        !          1561:       StoreToEA(ea,ra[i]);
        !          1562:       ea.addr += mask2len(p.mask);
        !          1563:     }
        !          1564:   }
        !          1565: }
        !          1566: 
        !          1567: static instr_result INST_MOVEAUSP(const instr_params &p)
        !          1568: {
        !          1569:   effadr ea = GetEA(p.src,0xffffffff);
        !          1570:   if (regs.s) {
        !          1571:     regs.usp = GetFromEA(ea);
        !          1572:   } else {
        !          1573:     regs.pc -= 2; Exception(8);
        !          1574:   }
        !          1575: }
        !          1576: 
        !          1577: static instr_result INST_MOVEUSPA(const instr_params &p)
        !          1578: {
        !          1579:   effadr ea = GetEA(p.src,0xffffffff);
        !          1580:   if (regs.s) {
        !          1581:     StoreToEA(ea,regs.usp);
        !          1582:   } else {
        !          1583:     regs.pc -= 2; Exception(8);
        !          1584:   }
        !          1585: }
        !          1586: 
        !          1587: static instr_result INST_LINEA(const instr_params &)
        !          1588: {
        !          1589:   regs.pc -= 2;
        !          1590:   
        !          1591:   Exception(10);
        !          1592: }
        !          1593: 
        !          1594: static instr_result INST_LINEF(const instr_params &)
        !          1595: {
        !          1596:   regs.pc -= 2;
        !          1597:   
        !          1598:   Exception(11);
        !          1599: }
        !          1600: 
        !          1601:  /*
        !          1602:   * debugging functions
        !          1603:   */
        !          1604: 
        !          1605: struct debug_entry {
        !          1606:   instr_func f;
        !          1607:   char *name;
        !          1608:   bool src,dest,spc;
        !          1609: };
        !          1610: 
        !          1611: static debug_entry debugtbl[] = {
        !          1612:   { &INST_OR,"OR",1,1,0 },
        !          1613:   { &INST_AND,"AND",1,1,0 },
        !          1614:   { &INST_EOR,"EOR",1,1,0 },
        !          1615:   { &INST_CMP,"CMP",1,1,0 },
        !          1616:   { &INST_ADD,"ADD",1,1,0 },
        !          1617:   { &INST_SUB,"SUB",1,1,0 },
        !          1618:   { &INST_ADDX,"ADDX",1,1,0 },
        !          1619:   { &INST_SUBX,"SUBX",1,1,0 },
        !          1620: 
        !          1621:   { &INST_ADDA,"ADDA",1,1,0 },
        !          1622:   { &INST_SUBA,"SUBA",1,1,0 },
        !          1623:   { &INST_CMPA,"CMPA",1,1,0 },
        !          1624: 
        !          1625:   { &INST_CHK,"CHK",1,1,0 },
        !          1626: 
        !          1627:   { &INST_EXGL,"EXG",1,1,0 },
        !          1628: 
        !          1629:   { &INST_LEA,"LEA",1,1,0 },
        !          1630:   { &INST_MOVE,"MOVE",1,1,0 },
        !          1631:   { &INST_MOVEA,"MOVEA",1,1,0 },
        !          1632:   { &INST_MOVEQ,"MOVEQ",1,1,0 },
        !          1633:   { &INST_BTST,"BTST",1,1,0 },
        !          1634:   { &INST_BCLR,"BCLR",1,1,0 },
        !          1635:   { &INST_BSET,"BSET",1,1,0 },
        !          1636:   { &INST_BCHG,"BCHG",1,1,0 },
        !          1637:   { &INST_NEG,"NEG",1,0,0 },
        !          1638:   { &INST_NEGX,"NEGX",1,0,0 },
        !          1639:   { &INST_NOT,"NOT",1,0,0 },
        !          1640:   { &INST_CLR,"CLR",1,0,0 },
        !          1641:   { &INST_TST,"TST",1,0,0 },
        !          1642:   { &INST_SWAP,"SWAP",1,0,0 },
        !          1643:   { &INST_EXTW,"EXT",1,0,0 },
        !          1644:   { &INST_EXTL,"EXT",1,0,0 },
        !          1645:   { &INST_Scc,"Scc",1,0,0 },
        !          1646:   { &INST_ABCD,"ABCD",1,1,0 },
        !          1647:   { &INST_SBCD,"SBCD",1,1,0 },
        !          1648:   { &INST_NBCD,"NBCD",1,1,0 },
        !          1649:   { &INST_NOP,"NOP",0,0,0 },
        !          1650:   { &INST_RESET,"RESET",0,0,0 },
        !          1651:   { &INST_STOP,"STOP",1,0,0 },
        !          1652:   { &INST_TRAPV,"TRAPV",1,0,0 },
        !          1653:   { &INST_TRAP,"TRAP",1,0,0 },
        !          1654:   { &INST_BSRB,"BSR",1,0,0 },
        !          1655:   { &INST_BccB,"Bcc",1,0,0 },
        !          1656:   { &INST_BSRW,"BSR",1,0,0 },
        !          1657:   { &INST_BccW,"Bcc",1,0,0 },
        !          1658:   { &INST_DBcc,"DBcc",1,0,10 },
        !          1659:   { &INST_JMP,"JMP",1,0,0 },
        !          1660:   { &INST_JSR,"JSR",1,0,0 },
        !          1661:   { &INST_RTE,"RTE",0,0,0 },
        !          1662:   { &INST_RTD,"RTD",0,0,0 },
        !          1663:   { &INST_RTS,"RTS",0,0,0 },
        !          1664:   { &INST_RTR,"RTR",0,0,0 },
        !          1665:   { &INST_LINK,"LINK",1,1,0 },
        !          1666:   { &INST_UNLK,"UNLK",1,0,0 },
        !          1667:   { &INST_MULU,"MULU",1,1,0 },
        !          1668:   { &INST_MULS,"MULS",1,1,0 },
        !          1669:   { &INST_DIVU, "DIVU",1,1,0 },
        !          1670:   { &INST_DIVS,"DIVS",1,1,0 },
        !          1671:   { &INST_ASR,"ASR",1,1,0 },
        !          1672:   { &INST_ASL,"ASL",1,1,0 },
        !          1673:   { &INST_LSR,"LSR",1,1,0 },
        !          1674:   { &INST_LSL,"LSL",1,1,0 },
        !          1675:   { &INST_ROR,"ROR",1,1,0 },
        !          1676:   { &INST_ROL,"ROL",1,1,0 },
        !          1677:   { &INST_ROXR,"ROXR",1,1,0 },
        !          1678:   { &INST_ROXL,"ROXL",1,1,0 },
        !          1679:   { &INST_ASR1,"ASR",1,0,0 },
        !          1680:   { &INST_ASL1,"ASL",1,0,0 },
        !          1681:   { &INST_LSR1,"LSR",1,0,0 },
        !          1682:   { &INST_LSL1,"LSL",1,0,0 },
        !          1683:   { &INST_ROR1,"ROR",1,0,0 },
        !          1684:   { &INST_ROL1,"ROL",1,0,0 },
        !          1685:   { &INST_ROXR1,"ROXR",1,0,0 },
        !          1686:   { &INST_ROXL1,"ROXL",1,0,0 },
        !          1687:   { &INST_MOVECCREA,"MOVE CCR,",1,0,0 },
        !          1688:   { &INST_MOVESREA,"MOVE SR,",1,0,0 },
        !          1689:   { &INST_MOVEEACCR,"MOVE2CCR",1,0,0 },
        !          1690:   { &INST_MOVEEASR,"MOVE2SR",1,0,0 },
        !          1691:   { &INST_MOVEMEARL,"MOVEM",1,0,9 },
        !          1692:   { &INST_MOVEMRLEA,"MOVEM",1,0,5 },
        !          1693:   { &INST_MOVEAUSP,"MOVE2USP",1,1,0 },
        !          1694:   { &INST_MOVEUSPA,"MOVE USP,",1,1,0 },
        !          1695: 
        !          1696:   { &INST_ORSR,"ORSR",1,0,0 },
        !          1697:   { &INST_ANDSR,"ANDSR",1,0,0 },
        !          1698:   { &INST_EORSR,"EORSR",1,0,0 },
        !          1699: 
        !          1700:   { &INST_LINEA,"LINEA",0,0,0 },
        !          1701:   { &INST_LINEF,"LINEF",0,0,0 },
        !          1702:   { &INST_ILLG,"ILLEGAL",0,0,0 },
        !          1703:   { &INST_NIMP,"NOT IMPLEMENTED",0,0,0 },
        !          1704:   { NULL,NULL,0,0,0 }
        !          1705: };
        !          1706: 
        !          1707: static char* ccnames[] =
        !          1708: { "T ","F ","HI","LS","CC","CS","NE","EQ",
        !          1709:   "VC","VS","PL","MI","GE","LT","GT","LE" };
        !          1710: 
        !          1711: void MC68000_reset()
        !          1712: {
        !          1713:   cout << "RESET!\n";
        !          1714:   regs.a[7] = (mem.get_word(0x00f80000) << 16) + mem.get_word(0xf80002);
        !          1715:   regs.pc = (mem.get_word(0x00f80004) << 16) + mem.get_word(0xf80006);
        !          1716:   regs.s = 1;
        !          1717:   regs.stopped = 0;
        !          1718:   instr_params p;
        !          1719:   INST_RESET(p);
        !          1720: }
        !          1721: 
        !          1722: void MC68000_step()
        !          1723: {
        !          1724:   if (!regs.stopped) {
        !          1725:     UWORD opcode = nextiword();
        !          1726:     I_dec_tab_entry &dtentry = instr_dectab[opcode];
        !          1727:     dtentry.execfunc(dtentry.params);
        !          1728:   }
        !          1729:   for(int i=0;i<4;i++) clockcycle();
        !          1730:   int intr = intlev();
        !          1731:   if (intr != -1 && intr > regs.intmask) {
        !          1732:     Interrupt(intr);
        !          1733:     regs.stopped = 0;
        !          1734:   }
        !          1735: }
        !          1736: 
        !          1737: void MC68000_skip(CPTR nextpc)
        !          1738: {
        !          1739:   do {
        !          1740:     MC68000_step();
        !          1741:   } while (nextpc != regs.pc);
        !          1742: }
        !          1743: 
        !          1744: void MC68000_disasm(CPTR addr,CPTR &nextpc,int cnt)
        !          1745: {
        !          1746: 
        !          1747:   CPTR pc = regs.pc;
        !          1748:   regs.pc = addr;
        !          1749:   for (;cnt--;){
        !          1750:     cout << hex << setfill('0');
        !          1751:     char instrname[20],*ccpt;
        !          1752:     int opwords;
        !          1753:     cout << setw(8) << regs.pc << ": ";
        !          1754:     for(opwords=0;opwords<5;opwords++){
        !          1755:       cout << setw(4) << mem.get_word(regs.pc + opwords*2) << " ";
        !          1756:     }
        !          1757:     cout << dec;
        !          1758: 
        !          1759:     UWORD opcode = nextiword();
        !          1760:     I_dec_tab_entry &dtentry = instr_dectab[opcode];
        !          1761:     debug_entry *dp;
        !          1762:     for (dp = debugtbl;dp->f && dp->f != dtentry.execfunc;dp++)
        !          1763:       {}
        !          1764: 
        !          1765:     if (!dp->f) {
        !          1766:       cout << "PANIC OPCODE " << opcode << " AT " << addr;
        !          1767:       abort();
        !          1768:     }
        !          1769:     strcpy(instrname,dp->name);
        !          1770:     ccpt = strstr(instrname,"cc");
        !          1771:     if (ccpt != 0) {
        !          1772:       strncpy(ccpt,ccnames[dtentry.params.dest.reg],2);
        !          1773:     }
        !          1774:     cout << instrname;
        !          1775:     switch(dtentry.params.mask){
        !          1776:     case 0xff: cout << ".B "; break;
        !          1777:     case 0xffff: cout << ".W "; break;
        !          1778:     case 0xffffffff: cout << ".L "; break;
        !          1779:     }
        !          1780:     UWORD special = 0;
        !          1781:     if (dp->spc & 1) {
        !          1782:       special = nextiword();
        !          1783:     }
        !          1784:     if (dp->spc & 4) {
        !          1785:       cout << "#$" << hex << setw(4) << special << ",";
        !          1786:     }
        !          1787:     if (dp->src) {
        !          1788:       ShowEA(dtentry.params.src,dtentry.params.mask);
        !          1789:     }
        !          1790:     if (dp->src && dp->dest) cout << ",";
        !          1791:     if (dp->dest) {
        !          1792:       ShowEA(dtentry.params.dest,dtentry.params.mask);
        !          1793:     }
        !          1794:     if (dp->spc & 2) {
        !          1795:       special = nextiword();
        !          1796:     }
        !          1797:     if (dp->spc & 8) {
        !          1798:       cout << ",#$" << hex << setw(4) << special;
        !          1799:     }
        !          1800:     if (ccpt != 0) {
        !          1801:       cout << ( (cctrue(dtentry.params.dest.reg)) ? " (TRUE)" : " (FALSE)");
        !          1802:     }
        !          1803:     cout << "\n";
        !          1804:   }
        !          1805:   nextpc = regs.pc;
        !          1806:   regs.pc = pc;
        !          1807: }
        !          1808: 
        !          1809: void MC68000_dumpstate(CPTR &nextpc)
        !          1810: {
        !          1811:   cout << hex << setfill('0');
        !          1812: 
        !          1813:   int i;
        !          1814:   for(i=0;i<8;i++){
        !          1815:     cout << "D" << setw(1) << i << ": " << setw(8) << regs.d[i] << " ";
        !          1816:     if ((i & 3) == 3) cout << "\n";
        !          1817:   }
        !          1818:   for(i=0;i<8;i++){
        !          1819:     cout << "A" << setw(1) << i << ": "  << setw(8) << regs.a[i] << " ";
        !          1820:     if ((i & 3) == 3) cout << "\n";
        !          1821:   }
        !          1822:   cout << setw(1);
        !          1823:   cout << "T=" << regs.t << " S=" << regs.s << " X=" << regs.x << " N=" 
        !          1824:     << regs.n << " Z=" << regs.z << " V=" << regs.v << " C=" << regs.c 
        !          1825:       << " IMASK=" << regs.intmask << "\n";
        !          1826:   MC68000_disasm(regs.pc,nextpc);
        !          1827:   cout << "next PC: " << setw(8) << hex << nextpc << "\n";
        !          1828: }
        !          1829: 
        !          1830:  /* 
        !          1831:   * GenerateDecTab() creates the instruction decode table.
        !          1832:   * FIXME: This should generate all legal instructions, but some illegal ones
        !          1833:   * will not be directed to INST_ILLG. On an accidental execution, a function
        !          1834:   * like GetEA() may call abort().
        !          1835:   *
        !          1836:   * This function is a monster and should probably be changed.
        !          1837:   */
        !          1838: 
        !          1839: static void GenerateDecTab()
        !          1840: {
        !          1841:   int offset;
        !          1842:   for(long int opcode=0;opcode<65536;opcode++){
        !          1843:     int r1 = (opcode & 0x0E00) >> 9;
        !          1844:     int m1 = (opcode & 0x01C0) >> 6;
        !          1845:     int m2 = (opcode & 0x0038) >> 3;
        !          1846:     int r2 = (opcode & 0x0007);
        !          1847:     int x  = (m1 & 4) >> 2;
        !          1848:     int sz = (m1 & 3);
        !          1849:     addr_mode am1(m1,r1),am2(m2,r2);
        !          1850:     I_dec_tab_entry entry;
        !          1851: 
        !          1852:     switch(opcode & 0xF000) {
        !          1853:     case 0x0000: 
        !          1854:       if (x) { 
        !          1855:        if (am2.mode == Dreg || am2.mode == Aind ||
        !          1856:            am2.mode == Aipi || am2.mode == Apdi ||
        !          1857:            am2.mode == Ad16 || am2.mode == Ad8r ||
        !          1858:            am2.mode == absw || am2.mode == absl) {
        !          1859:          switch(sz){ 
        !          1860:          case 0:
        !          1861:            entry.execfunc = &INST_BTST;
        !          1862:            break;
        !          1863:          case 1:
        !          1864:            entry.execfunc = &INST_BCHG;
        !          1865:            break;
        !          1866:          case 2:
        !          1867:            entry.execfunc = &INST_BCLR;
        !          1868:            break;
        !          1869:          case 3:
        !          1870:            entry.execfunc = &INST_BSET;
        !          1871:            break;
        !          1872:          }
        !          1873:          entry.params.mask = 0xffffffff;
        !          1874:          am1 = am2;
        !          1875:          am2.mode = Dreg; am2.reg = r1;
        !          1876:        } else {
        !          1877:          entry.execfunc = &INST_NIMP; // MOVEP
        !          1878:        }
        !          1879:       } else {
        !          1880:        am1.mode = imm;
        !          1881:        if (sz == 3) {
        !          1882:          switch(r1){
        !          1883:          case 0:
        !          1884:          case 1:
        !          1885:          case 2:
        !          1886:          case 6:
        !          1887:          case 7:
        !          1888:            entry.execfunc = &INST_ILLG;
        !          1889:            break;
        !          1890:          case 3:
        !          1891:            entry.execfunc = &INST_NIMP; // RTM
        !          1892:            break;
        !          1893:          case 4:
        !          1894:            entry.execfunc = &INST_BSET;
        !          1895:            am1 = am2;
        !          1896:            am2.mode = imm;
        !          1897:            entry.params.mask = 0xffff;
        !          1898:            break;
        !          1899:          case 5:
        !          1900:            entry.execfunc = &INST_NIMP; // CAS
        !          1901:            break;
        !          1902:          }
        !          1903:        } else {
        !          1904:          entry.params.mask = sizemask(sz);
        !          1905:          switch(r1){
        !          1906:          case 0:
        !          1907:            if (am2.mode == imm) 
        !          1908:              entry.execfunc = &INST_ORSR;
        !          1909:            else
        !          1910:              entry.execfunc = &INST_OR;
        !          1911:            break;
        !          1912:          case 1:
        !          1913:            if (am2.mode == imm) 
        !          1914:              entry.execfunc = &INST_ANDSR;
        !          1915:            else
        !          1916:              entry.execfunc = &INST_AND;
        !          1917:            break;
        !          1918:          case 2:
        !          1919:            entry.execfunc = &INST_SUB;
        !          1920:            break;
        !          1921:          case 3:
        !          1922:            entry.execfunc = &INST_ADD;
        !          1923:            break;
        !          1924:          case 4:
        !          1925:            switch(sz){
        !          1926:            case 0: entry.execfunc = &INST_BTST; break;
        !          1927:            case 1: entry.execfunc = &INST_BCHG; break;
        !          1928:            case 2: entry.execfunc = &INST_BCLR; break;
        !          1929:            }
        !          1930:            entry.params.mask = 0xffff;
        !          1931:            break;
        !          1932:          case 5:
        !          1933:            if (am2.mode == imm) 
        !          1934:              entry.execfunc = &INST_EORSR;
        !          1935:            else
        !          1936:              entry.execfunc = &INST_EOR;
        !          1937:            break;
        !          1938:          case 6:
        !          1939:            entry.execfunc = &INST_CMP;
        !          1940:            break;
        !          1941:          case 7:
        !          1942:            entry.execfunc = &INST_NIMP; // MOVES
        !          1943:            break;
        !          1944:          }
        !          1945:          am1 = am2; am2.mode = imm;
        !          1946:        }
        !          1947:       }
        !          1948:       break; 
        !          1949:     case 0x1000:
        !          1950:       switch(am1.mode) {
        !          1951:       case Areg: case imm: case imm3: case ill2: case ill3:
        !          1952:        entry.execfunc = &INST_ILLG; // MOVEA.B ???
        !          1953:        break;
        !          1954:       default:
        !          1955:        entry.execfunc = &INST_MOVE; // MOVE.B
        !          1956:        break;
        !          1957:       }
        !          1958:       entry.params.mask = 0xff;
        !          1959:       break; 
        !          1960:     case 0x2000:
        !          1961:       switch(am1.mode) {
        !          1962:       case Areg:
        !          1963:        entry.execfunc = &INST_MOVEA; // MOVEA.L
        !          1964:        break;
        !          1965:       case imm: case imm3: case ill2: case ill3:
        !          1966:        entry.execfunc = &INST_ILLG;
        !          1967:        break;
        !          1968:       default:
        !          1969:        entry.execfunc = &INST_MOVE; // MOVE.L
        !          1970:        break;
        !          1971:       }
        !          1972:       entry.params.mask = 0xffffffff; 
        !          1973:       break; 
        !          1974:     case 0x3000: 
        !          1975:       switch(am1.mode) {
        !          1976:       case Areg:
        !          1977:        entry.execfunc = &INST_MOVEA; // MOVEA.W
        !          1978:        break;
        !          1979:       case imm: case imm3: case ill2: case ill3:
        !          1980:        entry.execfunc = &INST_ILLG;
        !          1981:        break;
        !          1982:       default:
        !          1983:        entry.execfunc = &INST_MOVE; // MOVE.W
        !          1984:        break;
        !          1985:       }
        !          1986:       entry.params.mask = 0xffff;
        !          1987:       break; 
        !          1988:     case 0x4000: 
        !          1989:       if (x){
        !          1990:        switch(sz){
        !          1991:        case 0:
        !          1992:          entry.execfunc = &INST_CHK;
        !          1993:          entry.params.mask = 0xffffffff;
        !          1994:          am1.mode = Dreg; am1.reg = r1;
        !          1995:          break;
        !          1996:        case 1:
        !          1997:          entry.execfunc = &INST_ILLG;
        !          1998:          break;
        !          1999:        case 2:
        !          2000:          entry.execfunc = &INST_CHK;
        !          2001:          entry.params.mask = 0xffff;
        !          2002:          am1.mode = Dreg; am1.reg = r1;
        !          2003:          break;
        !          2004:        case 3:
        !          2005:          if (am2.mode == Dreg) {
        !          2006:            entry.execfunc = &INST_NIMP; // EXTB.L
        !          2007:          } else {
        !          2008:            entry.execfunc = &INST_LEA;
        !          2009:            entry.params.mask = 0xffffffff;
        !          2010:            am1.mode = Areg; am1.reg = r1;
        !          2011:          }
        !          2012:          break;
        !          2013:        }
        !          2014:       } else {
        !          2015:        switch(sz){
        !          2016:        case 0:
        !          2017:          switch(r1){
        !          2018:          case 0:
        !          2019:            entry.execfunc = &INST_NEG;
        !          2020:            entry.params.mask = 0xff;
        !          2021:            break;
        !          2022:          case 1:
        !          2023:            entry.execfunc = &INST_CLR;
        !          2024:            entry.params.mask = 0xff;
        !          2025:            break;
        !          2026:          case 2:
        !          2027:            entry.execfunc = &INST_NEG;
        !          2028:            entry.params.mask = 0xff;
        !          2029:            break;
        !          2030:          case 3:
        !          2031:            entry.execfunc = &INST_NOT;
        !          2032:            entry.params.mask = 0xff;
        !          2033:            break;
        !          2034:          case 4:
        !          2035:            if (am2.mode == Areg) {
        !          2036:              entry.execfunc = &INST_LINK; // this is from 020 upwards
        !          2037:              entry.params.mask = 0xffffffff;
        !          2038:              am1.mode = imm;
        !          2039:            } else {
        !          2040:              entry.execfunc = &INST_NBCD;
        !          2041:              entry.params.mask = 0xff;
        !          2042:            }
        !          2043:            break;
        !          2044:          case 5:
        !          2045:            entry.execfunc = &INST_TST;
        !          2046:            entry.params.mask = 0xff;
        !          2047:            break;
        !          2048:          case 6:
        !          2049:            entry.execfunc = &INST_NIMP; // MUL[US].L
        !          2050:            break;
        !          2051:          case 7:
        !          2052:            entry.execfunc = &INST_ILLG;
        !          2053:            break;
        !          2054:          }
        !          2055:          break;
        !          2056:        case 1:
        !          2057:          switch(r1){
        !          2058:          case 0:
        !          2059:            entry.execfunc = &INST_NEG;
        !          2060:            entry.params.mask = 0xffff;
        !          2061:            break;
        !          2062:          case 1:
        !          2063:            entry.execfunc = &INST_CLR;
        !          2064:            entry.params.mask = 0xffff;
        !          2065:            break;
        !          2066:          case 2:
        !          2067:            entry.execfunc = &INST_NEG;
        !          2068:            entry.params.mask = 0xffff;
        !          2069:            break;
        !          2070:          case 3:
        !          2071:            entry.execfunc = &INST_NOT;
        !          2072:            entry.params.mask = 0xffff;
        !          2073:            break;
        !          2074:          case 4:
        !          2075:            if (am2.mode == Dreg) {
        !          2076:              entry.execfunc = &INST_SWAP;
        !          2077:              entry.params.mask = 0xffffffff;
        !          2078:            } else {
        !          2079:              entry.execfunc = &INST_LEA; // PEA == LEA ea,-(A7)
        !          2080:              entry.params.mask = 0xffffffff;
        !          2081:              am1.mode = Apdi;
        !          2082:              am1.reg = 7;
        !          2083:            }
        !          2084:            break;
        !          2085:          case 5:
        !          2086:            entry.execfunc = &INST_TST;
        !          2087:            entry.params.mask = 0xffff;
        !          2088:            break;
        !          2089:          case 6:
        !          2090:            entry.execfunc = &INST_NIMP; // DIV[US]{L}.L
        !          2091:            break;
        !          2092:          case 7:
        !          2093:            switch(am2.mode){
        !          2094:            case Areg: case Dreg:
        !          2095:              entry.execfunc = &INST_TRAP;
        !          2096:              break;
        !          2097:            case Aind:
        !          2098:              entry.execfunc = &INST_LINK;
        !          2099:              am1.mode = imm;
        !          2100:              am2.mode = Areg;
        !          2101:              entry.params.mask = 0xffff;
        !          2102:              break;
        !          2103:            case Aipi:
        !          2104:              entry.execfunc = &INST_UNLK;
        !          2105:              am2.mode = Areg;
        !          2106:              break;
        !          2107:            case Apdi:
        !          2108:              entry.execfunc = &INST_MOVEAUSP;
        !          2109:              am2.mode = Areg;
        !          2110:              break;
        !          2111:            case Ad16:
        !          2112:              entry.execfunc = &INST_MOVEUSPA;
        !          2113:              am2.mode = Areg;
        !          2114:              break;
        !          2115:            case Ad8r:
        !          2116:              am2.mode = imm;
        !          2117:              switch(am2.reg){
        !          2118:              case 0: entry.execfunc = &INST_RESET; break;
        !          2119:              case 1: entry.execfunc = &INST_NOP; break;
        !          2120:              case 2: entry.execfunc = &INST_STOP; break;
        !          2121:              case 3: entry.execfunc = &INST_RTE; break;
        !          2122:              case 4: entry.execfunc = &INST_RTD; break;
        !          2123:              case 5: entry.execfunc = &INST_RTS; break;
        !          2124:              case 6: entry.execfunc = &INST_TRAPV; break;
        !          2125:              case 7: entry.execfunc = &INST_RTR; break;
        !          2126:              }
        !          2127:              break;
        !          2128:            case absw: case absl: case PC16: case PC8r: case imm:
        !          2129:            case imm3: case ill2: case ill3:
        !          2130:              entry.execfunc = &INST_ILLG;
        !          2131:              break;
        !          2132:            }
        !          2133:          }
        !          2134:          break;
        !          2135:        case 2:
        !          2136:          switch(r1){
        !          2137:          case 0:
        !          2138:            entry.execfunc = &INST_NEG;
        !          2139:            entry.params.mask = 0xffffffff;
        !          2140:            break;
        !          2141:          case 1:
        !          2142:            entry.execfunc = &INST_CLR;
        !          2143:            entry.params.mask = 0xffffffff;
        !          2144:            break;
        !          2145:          case 2:
        !          2146:            entry.execfunc = &INST_NEG;
        !          2147:            entry.params.mask = 0xffffffff;
        !          2148:            break;
        !          2149:          case 3:
        !          2150:            entry.execfunc = &INST_NOT;
        !          2151:            entry.params.mask = 0xffffffff;
        !          2152:            break;
        !          2153:          case 4:
        !          2154:            entry.params.mask = 0xffff;
        !          2155:            if (am2.mode == Dreg) {
        !          2156:              entry.execfunc = &INST_EXTW;
        !          2157:            } else {
        !          2158:              entry.execfunc = &INST_MOVEMRLEA;
        !          2159:            }
        !          2160:            break;
        !          2161:          case 5:
        !          2162:            entry.execfunc = &INST_TST;
        !          2163:            entry.params.mask = 0xffffffff;
        !          2164:            break;
        !          2165:          case 6:
        !          2166:            entry.params.mask =0xffff;
        !          2167:            entry.execfunc = &INST_MOVEMEARL;
        !          2168:            break;
        !          2169:          case 7:
        !          2170:            entry.params.mask =0xffffffff;
        !          2171:            if (am2.mode == imm) {
        !          2172:              entry.execfunc = &INST_ILLG;
        !          2173:            } else {
        !          2174:              entry.execfunc = &INST_JSR;
        !          2175:            }
        !          2176:            break;
        !          2177:          }
        !          2178:          break;
        !          2179:        case 3:
        !          2180:          entry.params.mask = 0xffff;
        !          2181:          switch(r1){
        !          2182:          case 0:
        !          2183:            entry.execfunc = &INST_MOVESREA;
        !          2184:            break;
        !          2185:          case 1:
        !          2186:            entry.execfunc = &INST_MOVECCREA;
        !          2187:            break;
        !          2188:          case 2:
        !          2189:            entry.execfunc = &INST_MOVEEACCR;
        !          2190:            break;
        !          2191:          case 3:
        !          2192:            entry.execfunc = &INST_MOVEEASR;
        !          2193:            break;
        !          2194:          case 4:
        !          2195:            entry.params.mask = 0xffffffff;
        !          2196:            if (am2.mode == Dreg) {
        !          2197:              entry.execfunc = &INST_EXTL;
        !          2198:            } else {
        !          2199:              entry.execfunc = &INST_MOVEMRLEA;
        !          2200:            }
        !          2201:            break;
        !          2202:          case 5:
        !          2203:            entry.execfunc = &INST_NIMP; // TAS.B
        !          2204:            break;
        !          2205:          case 6:
        !          2206:            entry.params.mask =0xffffffff;
        !          2207:            entry.execfunc = &INST_MOVEMEARL;
        !          2208:            break;
        !          2209:          case 7:
        !          2210:            entry.params.mask =0xffffffff;
        !          2211:            if (am2.mode == imm) {
        !          2212:              entry.execfunc = &INST_ILLG;
        !          2213:            } else {
        !          2214:              entry.execfunc = &INST_JMP;
        !          2215:            }
        !          2216:            break;
        !          2217:          }
        !          2218:          break;          
        !          2219:        }
        !          2220:       }
        !          2221:       break; 
        !          2222:     case 0x5000:
        !          2223:       switch(sz){
        !          2224:       case 0: case 1: case 2:
        !          2225:        entry.params.mask = sizemask(sz);
        !          2226:        if (x) {
        !          2227:          if (am2.mode == Areg) 
        !          2228:            entry.execfunc = &INST_SUBA/*Q*/;
        !          2229:          else
        !          2230:            entry.execfunc = &INST_SUB/*Q*/;
        !          2231: 
        !          2232:        } else {
        !          2233:          if (am2.mode == Areg)
        !          2234:            entry.execfunc = &INST_ADDA/*Q*/;
        !          2235:          else
        !          2236:            entry.execfunc = &INST_ADD/*Q*/;
        !          2237:        }
        !          2238:        am1 = am2; am2.mode = imm3; am2.reg = r1 ? r1 : 8;
        !          2239:        break;
        !          2240:       case 3:
        !          2241:        if (am2.mode == Areg) {
        !          2242:          entry.params.mask = 0xffff; 
        !          2243:          entry.execfunc = &INST_DBcc;
        !          2244:          am2.mode = Dreg;
        !          2245:        } else {
        !          2246:          entry.params.mask = 0xff;
        !          2247:          entry.execfunc = &INST_Scc;
        !          2248:        }
        !          2249:        am1.mode = imm3;
        !          2250:        am1.reg = (opcode & 0xf00) >> 8;
        !          2251:       }
        !          2252:       break; 
        !          2253:     case 0x6000:
        !          2254:       offset = opcode & 0xff;
        !          2255:       if (x == 1 && r1 == 0) {
        !          2256:        if (offset == 0) {
        !          2257:          entry.execfunc = &INST_BSRW;
        !          2258:          entry.params.mask = 0xffff;
        !          2259:          am2.mode = imm;
        !          2260:        } else {
        !          2261:          entry.execfunc = &INST_BSRB;
        !          2262:          entry.params.mask = 0xff;
        !          2263:          am2.mode = imm3; am2.reg = opcode & 0xff;
        !          2264:        }
        !          2265:       } else {
        !          2266:        if (offset == 0) {
        !          2267:          entry.execfunc = &INST_BccW;
        !          2268:          entry.params.mask = 0xffff;
        !          2269:          am2.mode = imm;
        !          2270:        } else {
        !          2271:          entry.execfunc = &INST_BccB;
        !          2272:          entry.params.mask = 0xff;
        !          2273:          am2.mode = imm3; am2.reg = opcode & 0xff;
        !          2274:        }
        !          2275:       }
        !          2276:       am1.reg = (opcode & 0xf00) >> 8;
        !          2277:       break;
        !          2278:     case 0x7000: 
        !          2279:       if (x) {
        !          2280:        entry.execfunc = &INST_ILLG;
        !          2281:       } else {
        !          2282:        entry.execfunc = &INST_MOVEQ;
        !          2283:        am1.mode = Dreg; am1.reg = r1; entry.params.mask = 0xffffffff;
        !          2284:        am2.mode = imm3; am2.reg = opcode & 0xff;
        !          2285:       }
        !          2286:       break; 
        !          2287:     case 0x8000: 
        !          2288:       if (x) {
        !          2289:        switch(sz) {
        !          2290:        case 0: case 1: case 2:
        !          2291:          entry.params.mask = sizemask(sz);
        !          2292:          switch (am2.mode) {
        !          2293:          case Dreg:
        !          2294:            if (sz != 0) {
        !          2295:              entry.execfunc = &INST_NIMP; // PACK, UNPK
        !          2296:            } else {
        !          2297:              entry.execfunc = &INST_SBCD;
        !          2298:              entry.params.mask = 0xff;
        !          2299:              am1.mode = Dreg;
        !          2300:              am1.reg = r1;
        !          2301:            }
        !          2302:            break;
        !          2303:          case Areg:
        !          2304:            if (sz != 0) {
        !          2305:              entry.execfunc = &INST_NIMP; // PACK, UNPK
        !          2306:            } else {
        !          2307:              entry.execfunc = &INST_SBCD;
        !          2308:              entry.params.mask = 0xff;
        !          2309:              am1.mode = am2.mode = Apdi;
        !          2310:              am1.reg = r1;
        !          2311:            }
        !          2312:            break;
        !          2313:          default:
        !          2314:            entry.execfunc = &INST_OR;
        !          2315:            am1 = am2; am2.mode = Dreg; am2.reg = r1;
        !          2316:            break;
        !          2317:          }
        !          2318:          break;
        !          2319:        case 3:
        !          2320:          entry.execfunc = &INST_DIVS;
        !          2321:          entry.params.mask = 0xffff;
        !          2322:          am1.mode = Dreg; am1.reg = r1;
        !          2323:          break;
        !          2324:        }
        !          2325:       } else {
        !          2326:         am1.mode = Dreg; am1.reg = r1;
        !          2327:        switch(sz) {
        !          2328:        case 0: case 1: case 2:
        !          2329:          entry.execfunc = &INST_OR;
        !          2330:          entry.params.mask = sizemask(sz);
        !          2331:          break;
        !          2332:        case 3:
        !          2333:          entry.execfunc = &INST_DIVU;
        !          2334:          entry.params.mask = 0xffff;
        !          2335:          break;
        !          2336:        }
        !          2337:       }
        !          2338:       break; 
        !          2339:     case 0x9000:
        !          2340:       if (sz == 3) {
        !          2341:        entry.execfunc = &INST_SUBA;
        !          2342:        entry.params.mask = x ? 0xffffffff : 0xffff;
        !          2343:        am1.mode = Areg; am1.reg = r1;
        !          2344:       } else {
        !          2345:        entry.execfunc = &INST_SUB;
        !          2346:        entry.params.mask = sizemask(sz);
        !          2347:        if (x) {
        !          2348:          switch(am2.mode) {
        !          2349:          case Dreg:
        !          2350:            entry.execfunc = &INST_SUBX;
        !          2351:            am1.mode = Dreg;
        !          2352:            am1.reg = r1;
        !          2353:            break;
        !          2354:          case Areg:
        !          2355:            entry.execfunc = &INST_SUBX;
        !          2356:            am1.mode = am2.mode = Apdi;
        !          2357:            am1.reg = r1;
        !          2358:            break;
        !          2359:          default:
        !          2360:            am1 = am2;
        !          2361:            am2.mode = Dreg;
        !          2362:            am2.reg = r1;
        !          2363:            break;
        !          2364:          }
        !          2365:        } else {
        !          2366:          am1.mode = Dreg;
        !          2367:          am1.reg = r1;
        !          2368:        }       
        !          2369:       }
        !          2370:       break; 
        !          2371:     case 0xA000: 
        !          2372:       entry.execfunc = &INST_LINEA;
        !          2373:       break; 
        !          2374:     case 0xB000:
        !          2375:       if (sz == 3) {
        !          2376:        entry.execfunc = &INST_CMPA;
        !          2377:        entry.params.mask = x ? 0xffffffff : 0xffff;
        !          2378:        am1.mode = Areg; am1.reg = r1;
        !          2379:       } else {
        !          2380:        entry.params.mask = sizemask(sz);
        !          2381:        am1.mode = Dreg; am1.reg = r1;
        !          2382:        if (x) {
        !          2383:          if (am2.mode == Areg){
        !          2384:            am1.mode = am2.mode = Aipi;
        !          2385:            am1.reg = r1;
        !          2386:            entry.execfunc = &INST_CMP/*M*/;
        !          2387:          } else {
        !          2388:            entry.execfunc = &INST_EOR;
        !          2389:            am1 = am2; am2.mode = Dreg; am2.reg = r1;
        !          2390:          }
        !          2391:        } else {
        !          2392:          entry.execfunc = &INST_CMP;
        !          2393:        }
        !          2394:       }
        !          2395:       break; 
        !          2396:     case 0xC000: 
        !          2397:       if (x) {
        !          2398:        switch(sz) {
        !          2399:        case 0: case 1: case 2:
        !          2400:          entry.params.mask = sizemask(sz);
        !          2401:          switch (am2.mode) {
        !          2402:          case Dreg:
        !          2403:            switch(sz) {
        !          2404:            case 2:
        !          2405:              entry.execfunc = &INST_ILLG;
        !          2406:              break;
        !          2407:            case 1:
        !          2408:              entry.execfunc = &INST_EXGL;
        !          2409:              entry.params.mask = 0xffffffff;
        !          2410:              am1 = am2;
        !          2411:              am2.mode = Dreg; am2.reg = r1;
        !          2412:              break;
        !          2413:            case 0:
        !          2414:              entry.execfunc = &INST_ABCD;
        !          2415:              entry.params.mask = 0xff;
        !          2416:              am1.mode = Dreg; am1.reg = r1;
        !          2417:              break;
        !          2418:            }
        !          2419:            break;
        !          2420:          case Areg:
        !          2421:            switch(sz) {
        !          2422:            case 2:
        !          2423:              entry.execfunc = &INST_EXGL;
        !          2424:              entry.params.mask = 0xffffffff;
        !          2425:              am1 = am2;
        !          2426:              am2.mode = Dreg; am2.reg = r1;
        !          2427:              break;
        !          2428:            case 1:
        !          2429:              entry.execfunc = &INST_EXGL;
        !          2430:              entry.params.mask = 0xffffffff;
        !          2431:              am1 = am2;
        !          2432:              am2.mode = Areg; am2.reg = r1;
        !          2433:              break;
        !          2434:            case 0:
        !          2435:              entry.execfunc = &INST_ABCD;
        !          2436:              entry.params.mask = 0xff;
        !          2437:              am1.mode = am2.mode = Apdi;
        !          2438:              am1.reg = r1;
        !          2439:              break;
        !          2440:            }
        !          2441:            break;
        !          2442:          default:
        !          2443:            entry.execfunc = &INST_AND;
        !          2444:            am1 = am2;
        !          2445:            am2.mode = Dreg; am2.reg = r1;
        !          2446:            break;
        !          2447:          }
        !          2448:          break;
        !          2449:        case 3:
        !          2450:          entry.execfunc = &INST_MULS;
        !          2451:          entry.params.mask = 0xffff;
        !          2452:          am1.mode = Dreg; am1.reg = r1;
        !          2453:          break;
        !          2454:        }
        !          2455:       } else {
        !          2456:         am1.mode = Dreg; am1.reg = r1;
        !          2457:        switch(sz) {
        !          2458:        case 0: case 1: case 2:
        !          2459:          entry.execfunc = &INST_AND;
        !          2460:          entry.params.mask = sizemask(sz);
        !          2461:          break;
        !          2462:        case 3:
        !          2463:          entry.execfunc = &INST_MULU;
        !          2464:          entry.params.mask = 0xffff;
        !          2465:          break;
        !          2466:        }
        !          2467:       }
        !          2468:       break; 
        !          2469:     case 0xD000: 
        !          2470:       if (sz == 3) {
        !          2471:        entry.execfunc = &INST_ADDA;
        !          2472:        entry.params.mask = x ? 0xffffffff : 0xffff;
        !          2473:        am1.mode = Areg; am1.reg = r1;
        !          2474:       } else {
        !          2475:        entry.execfunc = &INST_ADD;
        !          2476:        entry.params.mask = sizemask(sz);
        !          2477:        if (x) {
        !          2478:          switch(am2.mode) {
        !          2479:          case Dreg:
        !          2480:            entry.execfunc = &INST_ADDX;
        !          2481:            am1.mode = Dreg;
        !          2482:            am1.reg = r1;
        !          2483:            break;
        !          2484:          case Areg:
        !          2485:            entry.execfunc = &INST_ADDX;
        !          2486:            am1.mode = am2.mode = Apdi;
        !          2487:            am1.reg = r1;
        !          2488:            break;
        !          2489:          default:
        !          2490:            am1 = am2;
        !          2491:            am2.mode = Dreg;
        !          2492:            am2.reg = r1;
        !          2493:            break;
        !          2494:          }
        !          2495:        } else {
        !          2496:          am1.mode = Dreg;
        !          2497:          am1.reg = r1;
        !          2498:        }
        !          2499:       }
        !          2500:       break;      
        !          2501:     case 0xE000: 
        !          2502:       int type;
        !          2503:      
        !          2504:       if (sz == 3) {
        !          2505:        entry.params.mask = 0xffff;
        !          2506:        type = r1*2 + x;
        !          2507:        switch(type) {
        !          2508:        case 0: entry.execfunc = &INST_ASR1; break;
        !          2509:        case 1: entry.execfunc = &INST_ASL1; break;
        !          2510:        case 2: entry.execfunc = &INST_LSR1; break;
        !          2511:        case 3: entry.execfunc = &INST_LSL1; break;
        !          2512:        case 4: entry.execfunc = &INST_ROXR1; break;
        !          2513:        case 5: entry.execfunc = &INST_ROXL1; break;
        !          2514:        case 6: entry.execfunc = &INST_ROR1; break;
        !          2515:        case 7: entry.execfunc = &INST_ROL1; break;
        !          2516:        default:
        !          2517:          entry.execfunc = &INST_NIMP; // 020 bit fiends
        !          2518:          break;
        !          2519:        }
        !          2520:        if (type < 8) {
        !          2521:          if (am2.mode == Dreg || am2.mode == Areg || am2.mode == PC16 ||
        !          2522:              am2.mode == PC8r || am2.mode == imm) {
        !          2523:            entry.execfunc = &INST_ILLG;
        !          2524:          }
        !          2525:        }
        !          2526:        am1 = am2;
        !          2527:       } else {
        !          2528:        type = x + (m2 & 3)*2;
        !          2529:        entry.params.mask = sizemask(sz);
        !          2530:        switch(type) {
        !          2531:        case 0: entry.execfunc = &INST_ASR; break;
        !          2532:        case 1: entry.execfunc = &INST_ASL; break;
        !          2533:        case 2: entry.execfunc = &INST_LSR; break;
        !          2534:        case 3: entry.execfunc = &INST_LSL; break;
        !          2535:        case 4: entry.execfunc = &INST_ROXR; break;
        !          2536:        case 5: entry.execfunc = &INST_ROXL; break;
        !          2537:        case 6: entry.execfunc = &INST_ROR; break;
        !          2538:        case 7: entry.execfunc = &INST_ROL; break;
        !          2539:        }
        !          2540:        am1.mode = Dreg; am1.reg = r2;
        !          2541:        if (m2 > 3) {
        !          2542:          am2.mode = Dreg; am2.reg = r1;
        !          2543:        } else {
        !          2544:          am2.mode = imm3;
        !          2545:          am2.reg = r1 ? r1 : 8;
        !          2546:        }
        !          2547:       }
        !          2548:       break;
        !          2549:     case 0xF000: 
        !          2550:       entry.execfunc = &INST_LINEF;
        !          2551:       break; 
        !          2552:     }
        !          2553:     entry.params.dest = am1; entry.params.src = am2;
        !          2554:     instr_dectab[opcode] = entry;
        !          2555:   }
        !          2556: // Mahlzeit!
        !          2557: }

unix.superglobalmegacorp.com

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