Annotation of uae/cpu.cc, revision 1.1.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.