Annotation of previous/src/cpu/newcpu.c, revision 1.1.1.5

1.1.1.2   root        1: /*
                      2: * UAE - The Un*x Amiga Emulator
                      3: *
                      4: * MC68000 emulation
                      5: *
                      6: * (c) 1995 Bernd Schmidt
                      7: */
                      8: 
                      9: #define MMUOP_DEBUG 2
                     10: #define DEBUG_CD32CDTVIO 0
                     11: 
1.1.1.3   root       12: #include "main.h"
1.1.1.5 ! root       13: #include "m68000.h"
1.1.1.2   root       14: #include "compat.h"
                     15: #include "sysconfig.h"
                     16: #include "sysdeps.h"
                     17: #include "hatari-glue.h"
                     18: #include "options_cpu.h"
                     19: #include "maccess.h"
                     20: #include "memory.h"
                     21: #include "newcpu.h"
                     22: #include "cpummu.h"
1.1.1.3   root       23: #include "cpummu030.h"
1.1.1.5 ! root       24: #ifdef WITH_SOFTFLOAT
        !            25: #include "fpp-softfloat.h"
        !            26: #else
        !            27: #include "md-fpp.h"
        !            28: #endif
1.1.1.2   root       29: #include "main.h"
1.1.1.4   root       30: #include "dsp.h"
                     31: #include "dimension.h"
1.1.1.2   root       32: #include "reset.h"
                     33: #include "cycInt.h"
                     34: #include "dialog.h"
                     35: #include "screen.h"
                     36: #include "video.h"
                     37: #include "options.h"
                     38: #include "log.h"
                     39: #include "debugui.h"
                     40: #include "debugcpu.h"
                     41: 
                     42: 
                     43: /* Opcode of faulting instruction */
                     44: static uae_u16 last_op_for_exception_3;
                     45: /* PC at fault time */
                     46: static uaecptr last_addr_for_exception_3;
                     47: /* Address that generated the exception */
                     48: static uaecptr last_fault_for_exception_3;
                     49: /* read (0) or write (1) access */
                     50: static int last_writeaccess_for_exception_3;
                     51: /* instruction (1) or data (0) access */
                     52: static int last_instructionaccess_for_exception_3;
                     53: int mmu_enabled, mmu_triggered;
                     54: int cpu_cycles;
                     55: 
                     56: const int areg_byteinc[] = { 1, 1, 1, 1, 1, 1, 1, 2 };
                     57: const int imm8_table[] = { 8, 1, 2, 3, 4, 5, 6, 7 };
                     58: 
                     59: int movem_index1[256];
                     60: int movem_index2[256];
                     61: int movem_next[256];
                     62: 
                     63: cpuop_func *cpufunctbl[65536];
                     64: 
                     65: int OpcodeFamily;
                     66: struct mmufixup mmufixup[2];
                     67: 
1.1.1.5 ! root       68: uae_u32 fpp_get_fpsr (void);
1.1.1.2   root       69: 
                     70: static struct cache030 icaches030[CACHELINES030];
                     71: static struct cache030 dcaches030[CACHELINES030];
                     72: 
1.1.1.5 ! root       73: void m68k_disasm_2 (TCHAR *buf, int bufsize, uaecptr addr, uaecptr *nextpc, int cnt, uae_u32 *seaddr, uae_u32 *deaddr, int safemode);
1.1.1.2   root       74: 
                     75: uae_u32 (*x_prefetch)(int);
                     76: uae_u32 (*x_next_iword)(void);
                     77: uae_u32 (*x_next_ilong)(void);
1.1.1.4   root       78: uae_u32 (*x_get_ilong)(int);
                     79: uae_u32 (*x_get_iword)(int);
                     80: uae_u32 (*x_get_ibyte)(int);
1.1.1.2   root       81: uae_u32 (*x_get_long)(uaecptr);
                     82: uae_u32 (*x_get_word)(uaecptr);
                     83: uae_u32 (*x_get_byte)(uaecptr);
                     84: void (*x_put_long)(uaecptr,uae_u32);
                     85: void (*x_put_word)(uaecptr,uae_u32);
                     86: void (*x_put_byte)(uaecptr,uae_u32);
                     87: 
1.1.1.4   root       88: uae_u32 (*x_cp_next_iword)(void);
                     89: uae_u32 (*x_cp_next_ilong)(void);
                     90: uae_u32 (*x_cp_get_long)(uaecptr);
                     91: uae_u32 (*x_cp_get_word)(uaecptr);
                     92: uae_u32 (*x_cp_get_byte)(uaecptr);
                     93: void (*x_cp_put_long)(uaecptr,uae_u32);
                     94: void (*x_cp_put_word)(uaecptr,uae_u32);
                     95: void (*x_cp_put_byte)(uaecptr,uae_u32);
                     96: uae_u32 (REGPARAM3 *x_cp_get_disp_ea_020)(uae_u32 base, int idx) REGPARAM;
                     97: 
1.1.1.2   root       98: // shared memory access functions
                     99: static void set_x_funcs (void)
                    100: {
1.1.1.5 ! root      101:     if (currprefs.cpu_model == 68040) {
        !           102:         x_prefetch   = get_iword_mmu040;
        !           103:         x_get_ilong  = get_ilong_mmu040;
        !           104:         x_get_iword  = get_iword_mmu040;
        !           105:         x_get_ibyte  = get_ibyte_mmu040;
        !           106:         x_next_iword = next_iword_mmu040;
        !           107:         x_next_ilong = next_ilong_mmu040;
        !           108:         x_put_long   = put_long_mmu040;
        !           109:         x_put_word   = put_word_mmu040;
        !           110:         x_put_byte   = put_byte_mmu040;
        !           111:         x_get_long   = get_long_mmu040;
        !           112:         x_get_word   = get_word_mmu040;
        !           113:         x_get_byte   = get_byte_mmu040;
        !           114:     } else {
        !           115:         x_prefetch   = get_iword_mmu030;
        !           116:         x_get_ilong  = get_ilong_mmu030;
        !           117:         x_get_iword  = get_iword_mmu030;
        !           118:         x_get_ibyte  = get_ibyte_mmu030;
        !           119:         x_next_iword = next_iword_mmu030;
        !           120:         x_next_ilong = next_ilong_mmu030;
        !           121:         x_put_long   = put_long_mmu030;
        !           122:         x_put_word   = put_word_mmu030;
        !           123:         x_put_byte   = put_byte_mmu030;
        !           124:         x_get_long   = get_long_mmu030;
        !           125:         x_get_word   = get_word_mmu030;
        !           126:         x_get_byte   = get_byte_mmu030;
        !           127:     }
        !           128:     
        !           129:     if (currprefs.mmu_model == 68030) {
        !           130:         x_cp_put_long = put_long_mmu030_state;
        !           131:         x_cp_put_word = put_word_mmu030_state;
        !           132:         x_cp_put_byte = put_byte_mmu030_state;
        !           133:         x_cp_get_long = get_long_mmu030_state;
        !           134:         x_cp_get_word = get_word_mmu030_state;
        !           135:         x_cp_get_byte = get_byte_mmu030_state;
        !           136:         x_cp_next_iword = next_iword_mmu030_state;
        !           137:         x_cp_next_ilong = next_ilong_mmu030_state;
        !           138:         x_cp_get_disp_ea_020 = get_disp_ea_020_mmu030;
        !           139:     } else {
        !           140:         x_cp_put_long = x_put_long;
        !           141:         x_cp_put_word = x_put_word;
        !           142:         x_cp_put_byte = x_put_byte;
        !           143:         x_cp_get_long = x_get_long;
        !           144:         x_cp_get_word = x_get_word;
        !           145:         x_cp_get_byte = x_get_byte;
        !           146:         x_cp_next_iword = x_next_iword;
        !           147:         x_cp_next_ilong = x_next_ilong;
        !           148:         x_cp_get_disp_ea_020 = x_get_disp_ea_020;
        !           149:     }
        !           150: }
1.1.1.2   root      151: 
1.1.1.5 ! root      152: void flush_cpu_caches_040(uae_u16 opcode)
        !           153: {
        !           154:     int cache = (opcode >> 6) & 3;
        !           155:     if (!(cache & 2))
        !           156:         return;
        !           157:     set_cpu_caches(true);
1.1.1.2   root      158: }
                    159: 
1.1.1.4   root      160: void set_cpu_caches (bool flush)
1.1.1.2   root      161: {
                    162:        int i;
                    163: 
1.1.1.5 ! root      164:        if (currprefs.cpu_model == 68030) {
1.1.1.2   root      165:                if (regs.cacr & 0x08) { // clear instr cache
                    166:                        for (i = 0; i < CACHELINES030; i++) {
                    167:                                icaches030[i].valid[0] = 0;
                    168:                                icaches030[i].valid[1] = 0;
                    169:                                icaches030[i].valid[2] = 0;
                    170:                                icaches030[i].valid[3] = 0;
                    171:                        }
1.1.1.5 ! root      172:             regs.cacr &= ~0x08;
1.1.1.2   root      173:                }
                    174:                if (regs.cacr & 0x04) { // clear entry in instr cache
                    175:                        icaches030[(regs.caar >> 4) & (CACHELINES030 - 1)].valid[(regs.caar >> 2) & 3] = 0;
                    176:                        regs.cacr &= ~0x04;
                    177:                }
                    178:                if (regs.cacr & 0x800) { // clear data cache
                    179:                        for (i = 0; i < CACHELINES030; i++) {
                    180:                                dcaches030[i].valid[0] = 0;
                    181:                                dcaches030[i].valid[1] = 0;
                    182:                                dcaches030[i].valid[2] = 0;
                    183:                                dcaches030[i].valid[3] = 0;
                    184:                        }
                    185:                        regs.cacr &= ~0x800;
                    186:                }
                    187:                if (regs.cacr & 0x400) { // clear entry in data cache
                    188:                        dcaches030[(regs.caar >> 4) & (CACHELINES030 - 1)].valid[(regs.caar >> 2) & 3] = 0;
                    189:                        regs.cacr &= ~0x400;
                    190:                }
                    191:        } else if (currprefs.cpu_model == 68040) {
1.1.1.5 ! root      192:         if(ConfigureParams.System.bRealtime) {
        !           193: #if 0 /* FIXME */
        !           194:             if(regs.cacr & 0x8000) {
        !           195:                 flush_icache(0, -1);
        !           196:                 x_prefetch   = getc_iword_mmu040;
        !           197:                 x_get_ilong  = getc_ilong_mmu040;
        !           198:                 x_get_iword  = getc_iword_mmu040;
        !           199:                 x_get_ibyte  = getc_ibyte_mmu040;
        !           200:                 x_next_iword = nextc_iword_mmu040;
        !           201:                 x_next_ilong = nextc_ilong_mmu040;
        !           202:             } else
        !           203: #endif
        !           204:             {
        !           205:                 x_prefetch   = get_iword_mmu040;
        !           206:                 x_get_ilong  = get_ilong_mmu040;
        !           207:                 x_get_iword  = get_iword_mmu040;
        !           208:                 x_get_ibyte  = get_ibyte_mmu040;
        !           209:                 x_next_iword = next_iword_mmu040;
        !           210:                 x_next_ilong = next_ilong_mmu040;
        !           211:             }
        !           212:         }
1.1.1.2   root      213:        }
                    214: }
                    215: 
1.1.1.5 ! root      216: static uae_u32 REGPARAM2 op_illg_1 (uae_u32 opcode)
1.1.1.2   root      217: {
1.1.1.5 ! root      218:     op_illg (opcode);
        !           219:     return 4;
1.1.1.2   root      220: }
1.1.1.5 ! root      221: static uae_u32 REGPARAM2 op_unimpl_1 (uae_u32 opcode)
1.1.1.2   root      222: {
1.1.1.5 ! root      223:     if ((opcode & 0xf000) == 0xf000 || currprefs.cpu_model < 68060)
        !           224:         op_illg (opcode);
        !           225:     else
        !           226:         op_unimpl (opcode);
        !           227:     return 4;
1.1.1.2   root      228: }
                    229: 
                    230: void build_cpufunctbl (void)
                    231: {
                    232:        int i, opcnt;
                    233:        unsigned long opcode;
                    234:        const struct cputbl *tbl = 0;
                    235:        int lvl;
                    236: 
                    237:        switch (currprefs.cpu_model)
                    238:        {
                    239:        case 68040:
                    240:                lvl = 4;
1.1.1.5 ! root      241:                tbl = op_smalltbl_31_ff;
1.1.1.2   root      242:                break;
                    243:        case 68030:
                    244:                lvl = 3;
1.1.1.5 ! root      245:         tbl = op_smalltbl_32_ff;
1.1.1.2   root      246:                break;
                    247:        default:
1.1.1.5 ! root      248:                changed_prefs.cpu_model = currprefs.cpu_model = 68030;
        !           249:         lvl = 3;
        !           250:         tbl = op_smalltbl_32_ff;
1.1.1.2   root      251:        }
                    252: 
                    253:        if (tbl == 0) {
                    254:                write_log ("no CPU emulation cores available CPU=%d!", currprefs.cpu_model);
1.1.1.5 ! root      255:         DebugUI();
1.1.1.2   root      256:        }
                    257: 
                    258:        for (opcode = 0; opcode < 65536; opcode++)
                    259:                cpufunctbl[opcode] = op_illg_1;
                    260:        for (i = 0; tbl[i].handler != NULL; i++) {
                    261:                opcode = tbl[i].opcode;
                    262:                cpufunctbl[opcode] = tbl[i].handler;
                    263:        }
                    264: 
                    265:        opcnt = 0;
                    266:        for (opcode = 0; opcode < 65536; opcode++) {
                    267:                cpuop_func *f;
                    268: 
                    269:                if (table68k[opcode].mnemo == i_ILLG)
                    270:                        continue;
                    271:                if (table68k[opcode].clev > lvl) {
                    272:                        continue;
                    273:                }
                    274: 
                    275:                if (table68k[opcode].handler != -1) {
                    276:                        int idx = table68k[opcode].handler;
                    277:                        f = cpufunctbl[idx];
                    278:                        if (f == op_illg_1)
1.1.1.5 ! root      279:                 DebugUI();
1.1.1.2   root      280:                        cpufunctbl[opcode] = f;
                    281:                        opcnt++;
                    282:                }
                    283:        }
1.1.1.5 ! root      284:        write_log ("Building CPU, %d opcodes (%d %d)\n",
        !           285:                opcnt, lvl, currprefs.cpu_compatible ? 1 : 0);
        !           286:        write_log ("CPU=%d, MMU=%d, FPU=%d ($%02x), JIT%s=%d, realtime=%d\n",
1.1.1.4   root      287:                currprefs.cpu_model, currprefs.mmu_model,
                    288:                currprefs.fpu_model, currprefs.fpu_revision,
1.1.1.2   root      289:                currprefs.cachesize ? (currprefs.compfpu ? "=CPU/FPU" : "=CPU") : "",
1.1.1.5 ! root      290:                currprefs.cachesize, ConfigureParams.System.bRealtime);
1.1.1.4   root      291:        set_cpu_caches (0);
1.1.1.2   root      292:        if (currprefs.mmu_model) {
1.1.1.3   root      293:         if (currprefs.cpu_model >= 68040) {
                    294:             mmu_reset ();
                    295:             mmu_set_tc (regs.tcr);
                    296:             mmu_set_super (regs.s != 0);
                    297:         } else {
                    298:             mmu030_reset(1);
                    299:         }
                    300:     }
1.1.1.2   root      301: }
                    302: 
1.1.1.5 ! root      303: static void prefs_changed_cpu (void) {
1.1.1.2   root      304:        currprefs.cpu_model = changed_prefs.cpu_model;
                    305:        currprefs.fpu_model = changed_prefs.fpu_model;
1.1.1.4   root      306:     currprefs.fpu_revision = changed_prefs.fpu_revision;
1.1.1.2   root      307:        currprefs.mmu_model = changed_prefs.mmu_model;
                    308:        currprefs.cpu_compatible = changed_prefs.cpu_compatible;
                    309: }
                    310: 
                    311: void check_prefs_changed_cpu (void)
                    312: {
                    313:        bool changed = 0;
                    314: 
1.1.1.5 ! root      315:     if (changed
1.1.1.2   root      316:                || currprefs.cpu_model != changed_prefs.cpu_model
                    317:                || currprefs.fpu_model != changed_prefs.fpu_model
1.1.1.4   root      318:         || currprefs.fpu_revision != changed_prefs.fpu_revision
1.1.1.2   root      319:                || currprefs.mmu_model != changed_prefs.mmu_model
1.1.1.5 ! root      320:                || currprefs.cpu_compatible != changed_prefs.cpu_compatible) {
1.1.1.2   root      321: 
                    322:                        prefs_changed_cpu ();
                    323:                        build_cpufunctbl ();
                    324:                        changed = 1;
                    325:        }
                    326: 
                    327:        if (currprefs.cpu_idle != changed_prefs.cpu_idle) {
                    328:                currprefs.cpu_idle = changed_prefs.cpu_idle;
                    329:        }
                    330:        if (changed)
1.1.1.4   root      331:                set_special (SPCFLAG_MODE_CHANGE);
1.1.1.2   root      332: 
                    333: }
                    334: 
                    335: void init_m68k (void)
                    336: {
                    337:        int i;
                    338: 
                    339:        prefs_changed_cpu ();
1.1.1.5 ! root      340:     
1.1.1.2   root      341:        for (i = 0 ; i < 256 ; i++) {
                    342:                int j;
                    343:                for (j = 0 ; j < 8 ; j++) {
                    344:                        if (i & (1 << j)) break;
                    345:                }
                    346:                movem_index1[i] = j;
                    347:                movem_index2[i] = 7-j;
                    348:                movem_next[i] = i & (~(1 << j));
                    349:        }
                    350: 
                    351:        write_log ("Building CPU table for configuration: %d", currprefs.cpu_model);
                    352:        regs.address_space_mask = 0xffffffff;
1.1.1.5 ! root      353: 
        !           354:     if (currprefs.fpu_model > 0)
1.1.1.2   root      355:                write_log ("/%d", currprefs.fpu_model);
1.1.1.5 ! root      356:     if (currprefs.cpu_compatible)
1.1.1.2   root      357:                write_log (" prefetch");
                    358:        write_log ("\n");
                    359: 
                    360:        read_table68k ();
                    361:        do_merges ();
                    362: 
                    363:        write_log ("%d CPU functions\n", nr_cpuop_funcs);
                    364: 
                    365:        build_cpufunctbl ();
                    366:        set_x_funcs ();
                    367: }
                    368: 
1.1.1.5 ! root      369: struct regstruct regs;
1.1.1.2   root      370: struct flag_struct regflags;
                    371: 
1.1.1.5 ! root      372: #define get_word_debug(o) DBGMemory_ReadWord (o)
        !           373: #define get_iword_debug(o) DBGMemory_ReadWord (o)
        !           374: #define get_ilong_debug(o) DBGMemory_ReadLong (o)
        !           375: 
        !           376: static uaecptr ShowEA (void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, wordsizes size, TCHAR *buf, uae_u32 *eaddr, int safemode)
        !           377: {
        !           378:     uae_u16 dp;
        !           379:     uae_s8 disp8;
        !           380:     uae_s16 disp16;
        !           381:     int r;
        !           382:     uae_u32 dispreg;
        !           383:     uaecptr addr = pc;
        !           384:     uae_s32 offset = 0;
        !           385:     TCHAR buffer[80];
        !           386:     
        !           387:     switch (mode){
        !           388:         case Dreg:
        !           389:             _stprintf (buffer, _T("D%d"), reg);
        !           390:             break;
        !           391:         case Areg:
        !           392:             _stprintf (buffer, _T("A%d"), reg);
        !           393:             break;
        !           394:         case Aind:
        !           395:             _stprintf (buffer, _T("(A%d)"), reg);
        !           396:             addr = regs.regs[reg + 8];
        !           397:             break;
        !           398:         case Aipi:
        !           399:             _stprintf (buffer, _T("(A%d)+"), reg);
        !           400:             addr = regs.regs[reg + 8];
        !           401:             break;
        !           402:         case Apdi:
        !           403:             _stprintf (buffer, _T("-(A%d)"), reg);
        !           404:             addr = regs.regs[reg + 8];
        !           405:             break;
        !           406:         case Ad16:
        !           407:         {
        !           408:             TCHAR offtxt[80];
        !           409:             disp16 = get_iword_debug (pc); pc += 2;
        !           410:             if (disp16 < 0)
        !           411:                 _stprintf (offtxt, _T("-$%04x"), -disp16);
        !           412:             else
        !           413:                 _stprintf (offtxt, _T("$%04x"), disp16);
        !           414:             addr = m68k_areg (regs, reg) + disp16;
        !           415:             _stprintf (buffer, _T("(A%d, %s) == $%08x"), reg, offtxt, addr);
        !           416:         }
        !           417:             break;
        !           418:         case Ad8r:
        !           419:             dp = get_iword_debug (pc); pc += 2;
        !           420:             disp8 = dp & 0xFF;
        !           421:             r = (dp & 0x7000) >> 12;
        !           422:             dispreg = dp & 0x8000 ? m68k_areg (regs, r) : m68k_dreg (regs, r);
        !           423:             if (!(dp & 0x800)) dispreg = (uae_s32)(uae_s16)(dispreg);
        !           424:             dispreg <<= (dp >> 9) & 3;
        !           425:             
        !           426:             if (dp & 0x100) {
        !           427:                 uae_s32 outer = 0, disp = 0;
        !           428:                 uae_s32 base = m68k_areg (regs, reg);
        !           429:                 TCHAR name[10];
        !           430:                 _stprintf (name, _T("A%d, "), reg);
        !           431:                 if (dp & 0x80) { base = 0; name[0] = 0; }
        !           432:                 if (dp & 0x40) dispreg = 0;
        !           433:                 if ((dp & 0x30) == 0x20) { disp = (uae_s32)(uae_s16)get_iword_debug (pc); pc += 2; }
        !           434:                 if ((dp & 0x30) == 0x30) { disp = get_ilong_debug (pc); pc += 4; }
        !           435:                 base += disp;
        !           436:                 
        !           437:                 if ((dp & 0x3) == 0x2) { outer = (uae_s32)(uae_s16)get_iword_debug (pc); pc += 2; }
        !           438:                 if ((dp & 0x3) == 0x3) { outer = get_ilong_debug (pc); pc += 4; }
        !           439:                 
        !           440:                 if (!(dp & 4)) base += dispreg;
        !           441:                 if ((dp & 3) && !safemode) base = get_ilong_debug (base);
        !           442:                 if (dp & 4) base += dispreg;
        !           443:                 
        !           444:                 addr = base + outer;
        !           445:                 _stprintf (buffer, _T("(%s%c%d.%c*%d+%d)+%d == $%08x"), name,
        !           446:                            dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W',
        !           447:                            1 << ((dp >> 9) & 3),
        !           448:                            disp, outer, addr);
        !           449:             } else {
        !           450:                 addr = m68k_areg (regs, reg) + (uae_s32)((uae_s8)disp8) + dispreg;
        !           451:                 _stprintf (buffer, _T("(A%d, %c%d.%c*%d, $%02x) == $%08x"), reg,
        !           452:                            dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W',
        !           453:                            1 << ((dp >> 9) & 3), disp8, addr);
        !           454:             }
        !           455:             break;
        !           456:         case PC16:
        !           457:             disp16 = get_iword_debug (pc); pc += 2;
        !           458:             addr += (uae_s16)disp16;
        !           459:             _stprintf (buffer, _T("(PC,$%04x) == $%08x"), disp16 & 0xffff, addr);
        !           460:             break;
        !           461:         case PC8r:
        !           462:             dp = get_iword_debug (pc); pc += 2;
        !           463:             disp8 = dp & 0xFF;
        !           464:             r = (dp & 0x7000) >> 12;
        !           465:             dispreg = dp & 0x8000 ? m68k_areg (regs, r) : m68k_dreg (regs, r);
        !           466:             if (!(dp & 0x800)) dispreg = (uae_s32)(uae_s16)(dispreg);
        !           467:             dispreg <<= (dp >> 9) & 3;
        !           468:             
        !           469:             if (dp & 0x100) {
        !           470:                 uae_s32 outer = 0, disp = 0;
        !           471:                 uae_s32 base = addr;
        !           472:                 TCHAR name[10];
        !           473:                 _stprintf (name, _T("PC, "));
        !           474:                 if (dp & 0x80) { base = 0; name[0] = 0; }
        !           475:                 if (dp & 0x40) dispreg = 0;
        !           476:                 if ((dp & 0x30) == 0x20) { disp = (uae_s32)(uae_s16)get_iword_debug (pc); pc += 2; }
        !           477:                 if ((dp & 0x30) == 0x30) { disp = get_ilong_debug (pc); pc += 4; }
        !           478:                 base += disp;
        !           479:                 
        !           480:                 if ((dp & 0x3) == 0x2) { outer = (uae_s32)(uae_s16)get_iword_debug (pc); pc += 2; }
        !           481:                 if ((dp & 0x3) == 0x3) { outer = get_ilong_debug (pc); pc += 4; }
        !           482:                 
        !           483:                 if (!(dp & 4)) base += dispreg;
        !           484:                 if ((dp & 3) && !safemode) base = get_ilong_debug (base);
        !           485:                 if (dp & 4) base += dispreg;
        !           486:                 
        !           487:                 addr = base + outer;
        !           488:                 _stprintf (buffer, _T("(%s%c%d.%c*%d+%d)+%d == $%08x"), name,
        !           489:                            dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W',
        !           490:                            1 << ((dp >> 9) & 3),
        !           491:                            disp, outer, addr);
        !           492:             } else {
        !           493:                 addr += (uae_s32)((uae_s8)disp8) + dispreg;
        !           494:                 _stprintf (buffer, _T("(PC, %c%d.%c*%d, $%02x) == $%08x"), dp & 0x8000 ? 'A' : 'D',
        !           495:                            (int)r, dp & 0x800 ? 'L' : 'W',  1 << ((dp >> 9) & 3),
        !           496:                            disp8, addr);
        !           497:             }
        !           498:             break;
        !           499:         case absw:
        !           500:             addr = (uae_s32)(uae_s16)get_iword_debug (pc);
        !           501:             _stprintf (buffer, _T("$%08x"), addr);
        !           502:             pc += 2;
        !           503:             break;
        !           504:         case absl:
        !           505:             addr = get_ilong_debug (pc);
        !           506:             _stprintf (buffer, _T("$%08x"), addr);
        !           507:             pc += 4;
        !           508:             break;
        !           509:         case imm:
        !           510:             switch (size){
        !           511:                 case sz_byte:
        !           512:                     _stprintf (buffer, _T("#$%02x"), (get_iword_debug (pc) & 0xff));
        !           513:                     pc += 2;
        !           514:                     break;
        !           515:                 case sz_word:
        !           516:                     _stprintf (buffer, _T("#$%04x"), (get_iword_debug (pc) & 0xffff));
        !           517:                     pc += 2;
        !           518:                     break;
        !           519:                 case sz_long:
        !           520:                     _stprintf(buffer, _T("#$%08x"), (get_ilong_debug(pc)));
        !           521:                     pc += 4;
        !           522:                     break;
        !           523:                 case sz_single:
        !           524:                 {
        !           525:                     fptype fp;
        !           526:                     to_single(&fp, get_ilong_debug(pc));
        !           527:                     _stprintf(buffer, _T("#%s"), fp_print(&fp));
        !           528:                     pc += 4;
        !           529:                 }
        !           530:                     break;
        !           531:                 case sz_double:
        !           532:                 {
        !           533:                     fptype fp;
        !           534:                     to_double(&fp, get_ilong_debug(pc), get_ilong_debug(pc + 4));
        !           535:                     _stprintf(buffer, _T("#%s"), fp_print(&fp));
        !           536:                     pc += 8;
        !           537:                 }
        !           538:                     break;
        !           539:                 case sz_extended:
        !           540:                 {
        !           541:                     fptype fp;
        !           542:                     to_exten(&fp, get_ilong_debug(pc), get_ilong_debug(pc + 4), get_ilong_debug(pc + 8));
        !           543:                     _stprintf(buffer, _T("#%s"), fp_print(&fp));
        !           544:                     pc += 12;
        !           545:                     break;
        !           546:                 }
        !           547:                 case sz_packed:
        !           548:                     _stprintf(buffer, _T("#$%08x%08x%08x"), get_ilong_debug(pc), get_ilong_debug(pc + 4), get_ilong_debug(pc + 8));
        !           549:                     pc += 12;
        !           550:                     break;
        !           551:                 default:
        !           552:                     break;
        !           553:             }
        !           554:             break;
        !           555:         case imm0:
        !           556:             offset = (uae_s32)(uae_s8)get_iword_debug (pc);
        !           557:             _stprintf (buffer, _T("#$%02x"), (uae_u32)(offset & 0xff));
        !           558:             addr = pc + 2 + offset;
        !           559:             pc += 2;
        !           560:             break;
        !           561:         case imm1:
        !           562:             offset = (uae_s32)(uae_s16)get_iword_debug (pc);
        !           563:             buffer[0] = 0;
        !           564:             _stprintf (buffer, _T("#$%04x"), (uae_u32)(offset & 0xffff));
        !           565:             addr = pc + offset;
        !           566:             pc += 2;
        !           567:             break;
        !           568:         case imm2:
        !           569:             offset = (uae_s32)get_ilong_debug (pc);
        !           570:             _stprintf (buffer, _T("#$%08x"), (uae_u32)offset);
        !           571:             addr = pc + offset;
        !           572:             pc += 4;
        !           573:             break;
        !           574:         case immi:
        !           575:             offset = (uae_s32)(uae_s8)(reg & 0xff);
        !           576:             _stprintf (buffer, _T("#$%08x"), (uae_u32)offset);
        !           577:             addr = pc + offset;
        !           578:             break;
        !           579:         default:
        !           580:             break;
        !           581:     }
        !           582:     if (buf == 0)
        !           583:         f_out (f, _T("%s"), buffer);
        !           584:     else
        !           585:         _tcscat (buf, buffer);
        !           586:     if (eaddr)
        !           587:         *eaddr = addr;
        !           588:     return pc;
1.1.1.2   root      589: }
                    590: 
                    591: void REGPARAM2 MakeSR (void)
                    592: {
                    593:        regs.sr = ((regs.t1 << 15) | (regs.t0 << 14)
                    594:                | (regs.s << 13) | (regs.m << 12) | (regs.intmask << 8)
                    595:                | (GET_XFLG () << 4) | (GET_NFLG () << 3)
                    596:                | (GET_ZFLG () << 2) | (GET_VFLG () << 1)
                    597:                |  GET_CFLG ());
                    598: }
                    599: 
                    600: void REGPARAM2 MakeFromSR (void)
                    601: {
                    602:        int oldm = regs.m;
                    603:        int olds = regs.s;
                    604: 
                    605:        SET_XFLG ((regs.sr >> 4) & 1);
                    606:        SET_NFLG ((regs.sr >> 3) & 1);
                    607:        SET_ZFLG ((regs.sr >> 2) & 1);
                    608:        SET_VFLG ((regs.sr >> 1) & 1);
                    609:        SET_CFLG (regs.sr & 1);
                    610:        if (regs.t1 == ((regs.sr >> 15) & 1) &&
                    611:                regs.t0 == ((regs.sr >> 14) & 1) &&
                    612:                regs.s  == ((regs.sr >> 13) & 1) &&
                    613:                regs.m  == ((regs.sr >> 12) & 1) &&
                    614:                regs.intmask == ((regs.sr >> 8) & 7))
                    615:                return;
                    616:        regs.t1 = (regs.sr >> 15) & 1;
                    617:        regs.t0 = (regs.sr >> 14) & 1;
                    618:        regs.s  = (regs.sr >> 13) & 1;
                    619:        regs.m  = (regs.sr >> 12) & 1;
                    620:        regs.intmask = (regs.sr >> 8) & 7;
                    621:        if (currprefs.cpu_model >= 68020) {
                    622:                if (olds != regs.s) {
                    623:                        if (olds) {
                    624:                                if (oldm)
                    625:                                        regs.msp = m68k_areg (regs, 7);
                    626:                                else
                    627:                                        regs.isp = m68k_areg (regs, 7);
                    628:                                m68k_areg (regs, 7) = regs.usp;
                    629:                        } else {
                    630:                                regs.usp = m68k_areg (regs, 7);
                    631:                                m68k_areg (regs, 7) = regs.m ? regs.msp : regs.isp;
                    632:                        }
                    633:                } else if (olds && oldm != regs.m) {
                    634:                        if (oldm) {
                    635:                                regs.msp = m68k_areg (regs, 7);
                    636:                                m68k_areg (regs, 7) = regs.isp;
                    637:                        } else {
                    638:                                regs.isp = m68k_areg (regs, 7);
                    639:                                m68k_areg (regs, 7) = regs.msp;
                    640:                        }
                    641:                }
                    642:        } else {
                    643:                regs.t0 = regs.m = 0;
                    644:                if (olds != regs.s) {
                    645:                        if (olds) {
                    646:                                regs.isp = m68k_areg (regs, 7);
                    647:                                m68k_areg (regs, 7) = regs.usp;
                    648:                        } else {
                    649:                                regs.usp = m68k_areg (regs, 7);
                    650:                                m68k_areg (regs, 7) = regs.isp;
                    651:                        }
                    652:                }
                    653:        }
                    654:        if (currprefs.mmu_model)
                    655:                mmu_set_super (regs.s != 0);
                    656: 
                    657:        doint ();
                    658:        if (regs.t1 || regs.t0)
                    659:                set_special (SPCFLAG_TRACE);
                    660:        else
                    661:                /* Keep SPCFLAG_DOTRACE, we still want a trace exception for
                    662:                SR-modifying instructions (including STOP).  */
                    663:                unset_special (SPCFLAG_TRACE);
                    664: }
                    665: 
1.1.1.5 ! root      666: static void exception_check_trace (int nr)
1.1.1.2   root      667: {
1.1.1.5 ! root      668:     unset_special (SPCFLAG_TRACE | SPCFLAG_DOTRACE);
        !           669:     if (regs.t1 && !regs.t0) {
        !           670:         /* trace stays pending if exception is div by zero, chk,
        !           671:          * trapv or trap #x
        !           672:          */
        !           673:         if (nr == 5 || nr == 6 || nr == 7 || (nr >= 32 && nr <= 47))
        !           674:             set_special (SPCFLAG_DOTRACE);
        !           675:     }
        !           676:     regs.t1 = regs.t0 = 0;
1.1.1.2   root      677: }
                    678: 
                    679: static void exception_debug (int nr)
                    680: {
                    681: #ifdef DEBUGGER
                    682:        if (!exception_debugging)
                    683:                return;
1.1.1.5 ! root      684:        printf ("Exception %d, PC=%08X\n", nr, M68K_GETPC);
        !           685:     DebugUI();
1.1.1.2   root      686: #endif
                    687: }
                    688: 
1.1.1.4   root      689: void cpu_halt (int e)
                    690: {
                    691:        write_log("HALT!");
1.1.1.5 ! root      692:     DebugUI();
1.1.1.4   root      693: }
1.1.1.3   root      694: 
1.1.1.4   root      695: static void Exception_build_stack_frame (uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int nr, int format)
                    696: {
1.1.1.3   root      697:     int i;
1.1.1.4   root      698:    
                    699: #if 0
1.1.1.3   root      700:     if (nr < 24 || nr > 31) { // do not print debugging for interrupts
1.1.1.4   root      701:         write_log(_T("Building exception stack frame (format %X)\n"), format);
1.1.1.3   root      702:     }
1.1.1.4   root      703: #endif
                    704: 
1.1.1.3   root      705:     switch (format) {
                    706:         case 0x0: // four word stack frame
                    707:         case 0x1: // throwaway four word stack frame
                    708:             break;
                    709:         case 0x2: // six word stack frame
                    710:             m68k_areg (regs, 7) -= 4;
                    711:             x_put_long (m68k_areg (regs, 7), oldpc);
                    712:             break;
1.1.1.5 ! root      713:         case 0x3: // floating point post-instruction stack frame (68040)
        !           714:             m68k_areg (regs, 7) -= 4;
        !           715:             x_put_long (m68k_areg (regs, 7), regs.fp_ea);
        !           716:             break;
1.1.1.3   root      717:         case 0x7: // access error stack frame (68040)
1.1.1.4   root      718: 
                    719:                        for (i = 3; i >= 0; i--) {
                    720:                                // WB1D/PD0,PD1,PD2,PD3
1.1.1.3   root      721:                 m68k_areg (regs, 7) -= 4;
1.1.1.4   root      722:                 x_put_long (m68k_areg (regs, 7), mmu040_move16[i]);
                    723:                        }
                    724: 
1.1.1.3   root      725:             m68k_areg (regs, 7) -= 4;
1.1.1.4   root      726:             x_put_long (m68k_areg (regs, 7), 0); // WB1A
                    727:                        m68k_areg (regs, 7) -= 4;
                    728:             x_put_long (m68k_areg (regs, 7), 0); // WB2D
1.1.1.3   root      729:             m68k_areg (regs, 7) -= 4;
1.1.1.4   root      730:             x_put_long (m68k_areg (regs, 7), regs.wb2_address); // WB2A
                    731:                        m68k_areg (regs, 7) -= 4;
                    732:             x_put_long (m68k_areg (regs, 7), regs.wb3_data); // WB3D
1.1.1.3   root      733:             m68k_areg (regs, 7) -= 4;
1.1.1.4   root      734:             x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); // WB3A
                    735: 
                    736:                        m68k_areg (regs, 7) -= 4;
                    737:             x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); // FA
                    738:             
                    739:                        m68k_areg (regs, 7) -= 2;
1.1.1.3   root      740:             x_put_word (m68k_areg (regs, 7), 0);
                    741:             m68k_areg (regs, 7) -= 2;
1.1.1.4   root      742:             x_put_word (m68k_areg (regs, 7), regs.wb2_status);
                    743:             regs.wb2_status = 0;
1.1.1.3   root      744:             m68k_areg (regs, 7) -= 2;
                    745:             x_put_word (m68k_areg (regs, 7), regs.wb3_status);
                    746:             regs.wb3_status = 0;
1.1.1.4   root      747: 
                    748:                        m68k_areg (regs, 7) -= 2;
                    749:                        x_put_word (m68k_areg (regs, 7), ssw);
1.1.1.3   root      750:             m68k_areg (regs, 7) -= 4;
1.1.1.4   root      751:             x_put_long (m68k_areg (regs, 7), regs.mmu_effective_addr);
1.1.1.3   root      752:             break;
                    753:         case 0x9: // coprocessor mid-instruction stack frame (68020, 68030)
                    754:             m68k_areg (regs, 7) -= 4;
1.1.1.5 ! root      755:             x_put_long (m68k_areg (regs, 7), regs.fp_ea);
1.1.1.3   root      756:             m68k_areg (regs, 7) -= 4;
1.1.1.5 ! root      757:             x_put_long (m68k_areg (regs, 7), regs.fp_opword);
1.1.1.3   root      758:             m68k_areg (regs, 7) -= 4;
                    759:             x_put_long (m68k_areg (regs, 7), oldpc);
                    760:             break;
                    761:         case 0x8: // bus and address error stack frame (68010)
1.1.1.4   root      762:             write_log(_T("Exception stack frame format %X not implemented\n"), format);
1.1.1.3   root      763:             return;
1.1.1.4   root      764:         case 0x4: // floating point unimplemented stack frame (68LC040, 68EC040)
                    765:                                // or 68060 bus access fault stack frame
                    766:                        m68k_areg (regs, 7) -= 4;
1.1.1.5 ! root      767:                        x_put_long (m68k_areg (regs, 7), ssw);
1.1.1.4   root      768:                        m68k_areg (regs, 7) -= 4;
1.1.1.5 ! root      769:                        x_put_long (m68k_areg (regs, 7), oldpc);
1.1.1.4   root      770:                        break;
                    771:                case 0xB: // long bus cycle fault stack frame (68020, 68030)
                    772:                        // We always use B frame because it is easier to emulate,
                    773:                        // our PC always points at start of instruction but A frame assumes
                    774:                        // it is + 2 and handling this properly is not easy.
                    775:                        // Store state information to internal register space
                    776:                        for (i = 0; i < mmu030_idx + 1; i++) {
                    777:                                m68k_areg (regs, 7) -= 4;
                    778:                                x_put_long (m68k_areg (regs, 7), mmu030_ad[i].val);
                    779:                        }
                    780:                        while (i < 9) {
                    781:                 uae_u32 v = 0;
                    782:                                m68k_areg (regs, 7) -= 4;
1.1.1.5 ! root      783:                 // mmu030_idx is always small enough if instruction is FMOVEM.
1.1.1.4   root      784:                 if (mmu030_state[1] & MMU030_STATEFLAG1_FMOVEM) {
                    785:                     if (i == 7)
                    786:                         v = mmu030_fmovem_store[0];
                    787:                     else if (i == 8)
                    788:                         v = mmu030_fmovem_store[1];
                    789:                 }
                    790:                 x_put_long (m68k_areg (regs, 7), v);
                    791:                 i++;
                    792:                        }
                    793:                         // version & internal information (We store index here)
                    794:                        m68k_areg (regs, 7) -= 2;
                    795:                        x_put_word (m68k_areg (regs, 7), mmu030_idx);
                    796:                        // 3* internal registers
                    797:                        m68k_areg (regs, 7) -= 2;
                    798:                        x_put_word (m68k_areg (regs, 7), mmu030_state[2]);
                    799:                        m68k_areg (regs, 7) -= 2;
                    800:                        x_put_word (m68k_areg (regs, 7), mmu030_state[1]);
                    801:                        m68k_areg (regs, 7) -= 2;
                    802:                        x_put_word (m68k_areg (regs, 7), mmu030_state[0]);
                    803:                        // data input buffer = fault address
                    804:                        m68k_areg (regs, 7) -= 4;
                    805:                        x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr);
                    806:                        // 2xinternal
                    807:                        m68k_areg (regs, 7) -= 2;
                    808:                        x_put_word (m68k_areg (regs, 7), 0);
                    809:                        m68k_areg (regs, 7) -= 2;
                    810:                        x_put_word (m68k_areg (regs, 7), 0);
                    811:                        // stage b address
                    812:                        m68k_areg (regs, 7) -= 4;
                    813:                        x_put_long (m68k_areg (regs, 7), mm030_stageb_address);
                    814:                        // 2xinternal
                    815:                        m68k_areg (regs, 7) -= 4;
                    816:                        x_put_long (m68k_areg (regs, 7), mmu030_disp_store[1]);
                    817:                /* fall through */
                    818:                case 0xA: // short bus cycle fault stack frame (68020, 68030)
                    819:                        m68k_areg (regs, 7) -= 4;
                    820:                        x_put_long (m68k_areg (regs, 7), mmu030_disp_store[0]);
                    821:                        m68k_areg (regs, 7) -= 4;
                    822:                         // Data output buffer = value that was going to be written
                    823:                        x_put_long (m68k_areg (regs, 7), (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) ? mmu030_data_buffer : mmu030_ad[mmu030_idx].val);
                    824:                        m68k_areg (regs, 7) -= 4;
                    825:                        x_put_long (m68k_areg (regs, 7), mmu030_opcode);  // Internal register (opcode storage)
                    826:                        m68k_areg (regs, 7) -= 4;
                    827:                        x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); // data cycle fault address
                    828:                        m68k_areg (regs, 7) -= 2;
                    829:                        x_put_word (m68k_areg (regs, 7), 0);  // Instr. pipe stage B
                    830:                        m68k_areg (regs, 7) -= 2;
                    831:                        x_put_word (m68k_areg (regs, 7), 0);  // Instr. pipe stage C
                    832:                        m68k_areg (regs, 7) -= 2;
                    833:                        x_put_word (m68k_areg (regs, 7), ssw);
                    834:                        m68k_areg (regs, 7) -= 2;
                    835:                        x_put_word (m68k_areg (regs, 7), 0);  // Internal register
                    836:                        break;
                    837:                default:
                    838:             write_log(_T("Unknown exception stack frame format: %X\n"), format);
1.1.1.3   root      839:             return;
                    840:     }
                    841:     m68k_areg (regs, 7) -= 2;
1.1.1.4   root      842:     x_put_word (m68k_areg (regs, 7), (format << 12) | (nr * 4));
1.1.1.3   root      843:     m68k_areg (regs, 7) -= 4;
                    844:     x_put_long (m68k_areg (regs, 7), currpc);
                    845:     m68k_areg (regs, 7) -= 2;
                    846:     x_put_word (m68k_areg (regs, 7), regs.sr);
                    847: }
                    848: 
1.1.1.5 ! root      849: 
1.1.1.4   root      850: // 68030 MMU
                    851: static void Exception_mmu030 (int nr, uaecptr oldpc)
                    852: {
                    853:     uae_u32 currpc = m68k_getpc (), newpc;
1.1.1.3   root      854:     
1.1.1.4   root      855:     exception_debug (nr);
                    856:     MakeSR ();
1.1.1.3   root      857:     
                    858:     if (!regs.s) {
1.1.1.4   root      859:         regs.usp = m68k_areg (regs, 7);
1.1.1.3   root      860:         m68k_areg(regs, 7) = regs.m ? regs.msp : regs.isp;
                    861:         regs.s = 1;
1.1.1.4   root      862:         mmu_set_super (1);
1.1.1.3   root      863:     }
1.1.1.4   root      864:  
                    865: #if 0
1.1.1.3   root      866:     if (nr < 24 || nr > 31) { // do not print debugging for interrupts
1.1.1.4   root      867:         write_log (_T("Exception_mmu030: Exception %i: %08x %08x %08x\n"),
1.1.1.3   root      868:                    nr, currpc, oldpc, regs.mmu_fault_addr);
                    869:     }
1.1.1.4   root      870: #endif
                    871: 
                    872: #if 0
                    873:        write_log (_T("Exception %d -> %08x\n", nr, newpc));
                    874: #endif
                    875: 
                    876: 
                    877:     newpc = x_get_long (regs.vbr + 4 * nr);
                    878: 
                    879:        if (regs.m && nr >= 24 && nr < 32) { /* M + Interrupt */
                    880:         Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x0);
                    881:         MakeSR(); /* this sets supervisor bit in status reg */
                    882:         regs.m = 0; /* clear the M bit (but frame 0x1 uses sr with M bit set) */
                    883:         regs.msp = m68k_areg (regs, 7);
                    884:         m68k_areg (regs, 7) = regs.isp;
                    885:         Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x1);
1.1.1.3   root      886:     } else if (nr ==5 || nr == 6 || nr == 7 || nr == 9 || nr == 56) {
1.1.1.4   root      887:         Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x2);
                    888:     } else if (nr == 2) {
                    889:         Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr,  0xB);
                    890:     } else if (nr == 3) {
                    891:                regs.mmu_fault_addr = last_fault_for_exception_3;
                    892:                mmu030_state[0] = mmu030_state[1] = 0;
                    893:                mmu030_data_buffer = 0;
                    894:         Exception_build_stack_frame (last_fault_for_exception_3, currpc, MMU030_SSW_RW | MMU030_SSW_SIZE_W | (regs.s ? 6 : 2), nr,  0xA);
1.1.1.5 ! root      895:     } else if (nr >= 48 && nr < 55) {
        !           896:         if (regs.fpu_exp_pre) {
        !           897:             Exception_build_stack_frame(oldpc, regs.instruction_pc, 0, nr, 0x0);
        !           898:         } else { /* mid-instruction */
        !           899:             Exception_build_stack_frame(regs.fpiar, currpc, 0, nr, 0x9);
        !           900:         }
1.1.1.3   root      901:     } else {
1.1.1.4   root      902:         Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x0);
1.1.1.3   root      903:     }
                    904:     
                    905:        if (newpc & 1) {
                    906:                if (nr == 2 || nr == 3)
1.1.1.4   root      907:                        cpu_halt (2);
1.1.1.3   root      908:                else
1.1.1.5 ! root      909:                        exception3_read(regs.ir, newpc);
1.1.1.3   root      910:                return;
                    911:        }
1.1.1.5 ! root      912:        m68k_setpci (newpc);
        !           913:        exception_check_trace (nr);
1.1.1.3   root      914: }
                    915: 
                    916: 
1.1.1.5 ! root      917: // 68040 MMU
1.1.1.2   root      918: static void Exception_mmu (int nr, uaecptr oldpc)
                    919: {
                    920:        uae_u32 currpc = m68k_getpc (), newpc;
                    921: 
                    922:        exception_debug (nr);
                    923:        MakeSR ();
                    924: 
                    925:        if (!regs.s) {
                    926:                regs.usp = m68k_areg (regs, 7);
1.1.1.5 ! root      927:         if (currprefs.cpu_model >= 68020 && currprefs.cpu_model < 68060) {
1.1.1.2   root      928:                        m68k_areg (regs, 7) = regs.m ? regs.msp : regs.isp;
1.1.1.4   root      929:                } else {
1.1.1.2   root      930:                        m68k_areg (regs, 7) = regs.isp;
1.1.1.4   root      931:                }
1.1.1.2   root      932:                regs.s = 1;
                    933:                mmu_set_super (1);
                    934:        }
1.1.1.3   root      935:     
1.1.1.4   root      936:        newpc = x_get_long (regs.vbr + 4 * nr);
                    937: #if 0
                    938:        write_log (_T("Exception %d: %08x -> %08x\n"), nr, currpc, newpc);
                    939: #endif
                    940: 
                    941:        if (nr == 2) { // bus error
                    942:         //write_log (_T("Exception_mmu %08x %08x %08x\n"), currpc, oldpc, regs.mmu_fault_addr);
                    943:         if (currprefs.mmu_model == 68040)
                    944:                        Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x7);
                    945:                else
1.1.1.5 ! root      946:                        Exception_build_stack_frame(regs.mmu_fault_addr, currpc, regs.mmu_fslw, nr, 0x4);
1.1.1.3   root      947:        } else if (nr == 3) { // address error
1.1.1.4   root      948:         Exception_build_stack_frame(last_fault_for_exception_3, currpc, 0, nr, 0x2);
                    949:                write_log (_T("Exception %d (%x) at %x!\n"), nr, last_fault_for_exception_3, currpc);
                    950:        } else if (nr == 5 || nr == 6 || nr == 7 || nr == 9) {
1.1.1.3   root      951:         Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x2);
1.1.1.2   root      952:        } else if (regs.m && nr >= 24 && nr < 32) { /* M + Interrupt */
1.1.1.4   root      953:         Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x0);
                    954:         MakeSR(); /* this sets supervisor bit in status reg */
                    955:         regs.m = 0; /* clear the M bit (but frame 0x1 uses sr with M bit set) */
                    956:         regs.msp = m68k_areg (regs, 7);
                    957:         m68k_areg (regs, 7) = regs.isp;
                    958:         Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x1);
1.1.1.5 ! root      959:        } else if (nr == 60 || nr == 61) {
1.1.1.4   root      960:         Exception_build_stack_frame(oldpc, regs.instruction_pc, regs.mmu_ssw, nr, 0x0);
1.1.1.5 ! root      961:     } else if (nr >= 48 && nr <= 55) {
        !           962:         if (regs.fpu_exp_pre) {
        !           963:             if (currprefs.cpu_model == 68060 && nr == 55 && regs.fp_unimp_pend == 2) { // packed decimal real
        !           964:                 Exception_build_stack_frame(regs.fp_ea, regs.instruction_pc, 0, nr, 0x2);
        !           965:             } else {
        !           966:                 Exception_build_stack_frame(oldpc, regs.instruction_pc, 0, nr, 0x0);
        !           967:             }
        !           968:         } else { /* post-instruction */
        !           969:             if (currprefs.cpu_model == 68060 && nr == 55 && regs.fp_unimp_pend == 2) { // packed decimal real
        !           970:                 Exception_build_stack_frame(regs.fp_ea, currpc, 0, nr, 0x2);
        !           971:             } else {
        !           972:                 Exception_build_stack_frame(oldpc, currpc, 0, nr, 0x3);
        !           973:             }
        !           974:         }
        !           975:     } else if (nr == 11 && regs.fp_unimp_ins) {
        !           976:         regs.fp_unimp_ins = false;
        !           977:         if ((currprefs.cpu_model == 68060 && (currprefs.fpu_model == 0 || (regs.pcr & 2))) ||
        !           978:             (currprefs.cpu_model == 68040 && currprefs.fpu_model == 0)) {
        !           979:             Exception_build_stack_frame(regs.fp_ea, currpc, regs.instruction_pc, nr, 0x4);
        !           980:         } else {
        !           981:             Exception_build_stack_frame(regs.fp_ea, currpc, regs.mmu_ssw, nr, 0x2);
        !           982:         }
1.1.1.2   root      983:        } else {
1.1.1.3   root      984:         Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x0);
1.1.1.2   root      985:        }
1.1.1.3   root      986:     
1.1.1.2   root      987:        if (newpc & 1) {
                    988:                if (nr == 2 || nr == 3)
1.1.1.4   root      989:                        cpu_halt (2);
1.1.1.2   root      990:                else
1.1.1.5 ! root      991:                        exception3_read (regs.ir, newpc);
1.1.1.2   root      992:                return;
                    993:        }
1.1.1.5 ! root      994:        m68k_setpci (newpc);
        !           995:        exception_check_trace (nr);
1.1.1.2   root      996: }
                    997: 
                    998: 
1.1.1.5 ! root      999: /* Handle exceptions. */
        !          1000: static void ExceptionX (int nr, uaecptr address)
1.1.1.2   root     1001: {
1.1.1.5 ! root     1002:     if (currprefs.cpu_model == 68030)
        !          1003:         Exception_mmu030 (nr, m68k_getpc ());
1.1.1.3   root     1004:     else
1.1.1.5 ! root     1005:         Exception_mmu (nr, m68k_getpc ());
1.1.1.2   root     1006: }
1.1.1.5 ! root     1007: 
1.1.1.4   root     1008: void REGPARAM2 Exception (int nr)
                   1009: {
1.1.1.5 ! root     1010:     ExceptionX (nr, -1);
1.1.1.4   root     1011: }
1.1.1.5 ! root     1012: void REGPARAM2 ExceptionL (int nr, uaecptr address)
1.1.1.2   root     1013: {
1.1.1.5 ! root     1014:     ExceptionX (nr, address);
        !          1015: }
1.1.1.2   root     1016: 
1.1.1.5 ! root     1017: static void do_interrupt (int nr, int Pending)
        !          1018: {
1.1.1.2   root     1019:        regs.stopped = 0;
                   1020:        unset_special (SPCFLAG_STOP);
                   1021:        assert (nr < 8 && nr >= 0);
                   1022: 
                   1023:        /* On Hatari, only video ints are using SPCFLAG_INT (see m68000.c) */
1.1.1.4   root     1024:        Exception (nr + 24);
1.1.1.2   root     1025: 
                   1026:        regs.intmask = nr;
                   1027:        doint ();
                   1028: 
                   1029:        set_special (SPCFLAG_INT);
                   1030: }
                   1031: 
                   1032: 
                   1033: void m68k_reset (int hardreset)
                   1034: {
1.1.1.4   root     1035:     regs.spcflags &= (SPCFLAG_MODE_CHANGE | SPCFLAG_BRK);
1.1.1.2   root     1036:        regs.ipl = regs.ipl_pin = 0;
                   1037:        regs.s = 1;
                   1038:        regs.m = 0;
                   1039:        regs.stopped = 0;
                   1040:        regs.t1 = 0;
                   1041:        regs.t0 = 0;
                   1042:        SET_ZFLG (0);
                   1043:        SET_XFLG (0);
                   1044:        SET_CFLG (0);
                   1045:        SET_VFLG (0);
                   1046:        SET_NFLG (0);
                   1047:        regs.intmask = 7;
                   1048:        regs.vbr = regs.sfc = regs.dfc = 0;
                   1049:        regs.irc = 0xffff;
                   1050:        
                   1051:        m68k_areg (regs, 7) = get_long (0);
                   1052:        m68k_setpc (get_long (4));
                   1053: 
                   1054:        fpu_reset ();
                   1055: 
                   1056:        regs.caar = regs.cacr = 0;
                   1057:        regs.itt0 = regs.itt1 = regs.dtt0 = regs.dtt1 = 0;
                   1058:        regs.tcr = regs.mmusr = regs.urp = regs.srp = regs.buscr = 0;
                   1059: 
                   1060:        mmufixup[0].reg = -1;
                   1061:        mmufixup[1].reg = -1;
                   1062:        if (currprefs.mmu_model) {
1.1.1.3   root     1063:         if (currprefs.cpu_model >= 68040) {
                   1064:             mmu_reset ();
                   1065:             mmu_set_tc (regs.tcr);
                   1066:             mmu_set_super (regs.s != 0);
                   1067:         }
                   1068:         else {
                   1069:             mmu030_reset(hardreset);
                   1070:         }
                   1071:     }
1.1.1.2   root     1072: 
                   1073:        regs.pcr = 0;
                   1074: }
                   1075: 
1.1.1.4   root     1076: void REGPARAM2 op_unimpl (uae_u16 opcode)
                   1077: {
1.1.1.5 ! root     1078:     static int warned;
        !          1079:     if (warned < 20) {
        !          1080:         write_log (_T("68060 unimplemented opcode %04X, PC=%08x\n"), opcode, regs.instruction_pc);
        !          1081:         warned++;
        !          1082:     }
        !          1083:     ExceptionL (61, regs.instruction_pc);
1.1.1.4   root     1084: }
                   1085: 
                   1086: uae_u32 REGPARAM2 op_illg (uae_u32 opcode)
1.1.1.2   root     1087: {
                   1088:        uaecptr pc = m68k_getpc ();
                   1089:        static int warned;
                   1090: 
                   1091:        if (warned < 20) {
1.1.1.4   root     1092:                write_log ("Illegal instruction: %04x at %08X\n", opcode, pc);
1.1.1.2   root     1093:                warned++;
                   1094:        }
                   1095: 
                   1096:        if ((opcode & 0xF000)==0xA000)
1.1.1.4   root     1097:                Exception (10);
1.1.1.2   root     1098:        else 
                   1099:        if ((opcode & 0xF000)==0xF000)
1.1.1.4   root     1100:                Exception (11);
1.1.1.2   root     1101:        else
1.1.1.4   root     1102:                Exception (4);
1.1.1.2   root     1103:        return 4;
                   1104: }
                   1105: 
                   1106: #ifdef CPUEMU_0
                   1107: 
1.1.1.5 ! root     1108: // 68030 (68851) MMU instructions only
        !          1109: bool mmu_op30 (uaecptr pc, uae_u32 opcode, uae_u16 extra, uaecptr extraa)
1.1.1.2   root     1110: {
1.1.1.5 ! root     1111:     bool fline = false;
        !          1112:     
        !          1113:     if (extra & 0x8000) {
        !          1114:         fline = mmu_op30_ptest (pc, opcode, extra, extraa);
        !          1115:     } else if ((extra&0xE000)==0x2000 && (extra & 0x1C00)) {
        !          1116:         fline = mmu_op30_pflush (pc, opcode, extra, extraa);
        !          1117:     } else if ((extra&0xE000)==0x2000 && !(extra & 0x1C00)) {
        !          1118:         fline = mmu_op30_pload (pc, opcode, extra, extraa);
        !          1119:     } else {
        !          1120:         fline = mmu_op30_pmove (pc, opcode, extra, extraa);
        !          1121:     }
        !          1122:     
        !          1123:     if (fline) {
        !          1124:         m68k_setpc(pc);
        !          1125:         op_illg(opcode);
        !          1126:     }
        !          1127:     return fline;
1.1.1.2   root     1128: }
                   1129: 
                   1130: void mmu_op (uae_u32 opcode, uae_u32 extra)
                   1131: {
                   1132:        if (currprefs.cpu_model) {
                   1133:                mmu_op_real (opcode, extra);
                   1134:                return;
                   1135:        }
                   1136: #if MMUOP_DEBUG > 1
                   1137:        write_log ("mmu_op %04X PC=%08X\n", opcode, m68k_getpc ());
                   1138: #endif
                   1139:        if ((opcode & 0xFE0) == 0x0500) {
                   1140:                /* PFLUSH */
                   1141:                regs.mmusr = 0;
                   1142: #if MMUOP_DEBUG > 0
                   1143:                write_log ("PFLUSH\n");
                   1144: #endif
                   1145:                return;
                   1146:        } else if ((opcode & 0x0FD8) == 0x548) {
                   1147:                if (currprefs.cpu_model < 68060) { /* PTEST not in 68060 */
                   1148:                        /* PTEST */
                   1149: #if MMUOP_DEBUG > 0
                   1150:                        write_log ("PTEST\n");
                   1151: #endif
                   1152:                        return;
                   1153:                }
                   1154:        }
                   1155: #if MMUOP_DEBUG > 0
                   1156:        write_log ("Unknown MMU OP %04X\n", opcode);
                   1157: #endif
                   1158:        m68k_setpc (m68k_getpc () - 2);
                   1159:        op_illg (opcode);
                   1160: }
                   1161: 
                   1162: #endif
                   1163: 
                   1164: static uaecptr last_trace_ad = 0;
                   1165: 
                   1166: static void do_trace (void)
                   1167: {
                   1168:        if (regs.t0 && currprefs.cpu_model >= 68020) {
                   1169:                uae_u16 opcode;
                   1170:                /* should also include TRAP, CHK, SR modification FPcc */
                   1171:                /* probably never used so why bother */
                   1172:                /* We can afford this to be inefficient... */
                   1173:                m68k_setpc (m68k_getpc ());
                   1174:                opcode = x_get_word (regs.pc);
                   1175:                if (opcode == 0x4e73                    /* RTE */
                   1176:                        || opcode == 0x4e74             /* RTD */
                   1177:                        || opcode == 0x4e75             /* RTS */
                   1178:                        || opcode == 0x4e77             /* RTR */
                   1179:                        || opcode == 0x4e76             /* TRAPV */
                   1180:                        || (opcode & 0xffc0) == 0x4e80  /* JSR */
                   1181:                        || (opcode & 0xffc0) == 0x4ec0  /* JMP */
                   1182:                        || (opcode & 0xff00) == 0x6100  /* BSR */
                   1183:                        || ((opcode & 0xf000) == 0x6000 /* Bcc */
                   1184:                        && cctrue ((opcode >> 8) & 0xf))
                   1185:                        || ((opcode & 0xf0f0) == 0x5050 /* DBcc */
                   1186:                        && !cctrue ((opcode >> 8) & 0xf)
                   1187:                        && (uae_s16)m68k_dreg (regs, opcode & 7) != 0))
                   1188:                {
                   1189:                        last_trace_ad = m68k_getpc ();
                   1190:                        unset_special (SPCFLAG_TRACE);
                   1191:                        set_special (SPCFLAG_DOTRACE);
                   1192:                }
                   1193:        } else if (regs.t1) {
                   1194:                last_trace_ad = m68k_getpc ();
                   1195:                unset_special (SPCFLAG_TRACE);
                   1196:                set_special (SPCFLAG_DOTRACE);
                   1197:        }
                   1198: }
                   1199: 
                   1200: void doint (void)
                   1201: {
                   1202:        if (currprefs.cpu_compatible)
                   1203:                set_special (SPCFLAG_INT);
                   1204:        else
                   1205:                set_special (SPCFLAG_DOINT);
                   1206: }
                   1207: 
                   1208: #define IDLETIME (currprefs.cpu_idle * sleep_resolution / 700)
                   1209: 
                   1210: /*
                   1211:  * Handle special flags
                   1212:  */
                   1213: 
1.1.1.5 ! root     1214: static int do_specialties (int cycles)
1.1.1.2   root     1215: {
                   1216:        if (regs.spcflags & SPCFLAG_DOTRACE)
1.1.1.4   root     1217:                Exception (9);
1.1.1.2   root     1218: 
                   1219:     /* Handle the STOP instruction */
                   1220:     if ( regs.spcflags & SPCFLAG_STOP ) {
1.1.1.5 ! root     1221:         while (regs.spcflags & SPCFLAG_STOP) {
1.1.1.2   root     1222: 
1.1.1.5 ! root     1223:             /* Take care of quit event if needed */
        !          1224:             if (regs.spcflags & SPCFLAG_BRK)
        !          1225:                 return 1;
        !          1226:         
        !          1227:             M68000_AddCycles(cpu_cycles);
        !          1228: 
        !          1229:             /* It is possible one or more ints happen at the same time */
        !          1230:             /* We must process them during the same cpu cycle until the special INT flag is set */
        !          1231:             while (PendingInterrupt.time <=0 && PendingInterrupt.pFunction) {
        !          1232:                 /* 1st, we call the interrupt handler */
        !          1233:                 CALL_VAR(PendingInterrupt.pFunction);
        !          1234:                 
        !          1235:                 if ((regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE))) {
        !          1236:                     unset_special (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE);
        !          1237:                     // SPCFLAG_BRK breaks STOP condition, need to prefetch
        !          1238:                     m68k_resumestopped ();
        !          1239:                     return 1;
        !          1240:                 }
1.1.1.2   root     1241: 
1.1.1.5 ! root     1242:                 if (currprefs.cpu_idle && ((regs.spcflags & SPCFLAG_STOP)) == SPCFLAG_STOP) {
        !          1243:                     /* sleep 1ms if STOP-instruction is executed */
        !          1244:                     if (1) {
        !          1245:                         static int sleepcnt, lvpos;
        !          1246:                         if (vpos != lvpos) {
        !          1247:                             sleepcnt--;
        !          1248:                             lvpos = vpos;
        !          1249:                             if (sleepcnt < 0) {
        !          1250:                                     /*sleepcnt = IDLETIME / 2; */  /* Laurent : badly removed for now */
        !          1251:                                 host_sleep_ms(1);
        !          1252:                             }
        !          1253:                         }
        !          1254:                     }
        !          1255:                 }
        !          1256:             }
        !          1257:         }
1.1.1.2   root     1258:        }
                   1259: 
                   1260:        if (regs.spcflags & SPCFLAG_TRACE)
                   1261:                do_trace ();
                   1262: 
                   1263:        if (regs.spcflags & SPCFLAG_DOINT) {
                   1264:                unset_special (SPCFLAG_DOINT);
                   1265:                set_special (SPCFLAG_INT);
                   1266:        }
                   1267: 
                   1268:     if (regs.spcflags & SPCFLAG_DEBUGGER)
                   1269:                DebugCpu_Check();
                   1270: 
                   1271:        if ((regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE))) {
                   1272:                unset_special(SPCFLAG_MODE_CHANGE);
                   1273:                return 1;
                   1274:        }
1.1.1.5 ! root     1275:     
1.1.1.2   root     1276:        return 0;
                   1277: }
                   1278: 
1.1.1.5 ! root     1279: #ifndef CPUEMU_0
1.1.1.2   root     1280: 
1.1.1.5 ! root     1281: #else
1.1.1.2   root     1282: 
1.1.1.5 ! root     1283: static int lastRegsS = 0;
1.1.1.2   root     1284: 
1.1.1.5 ! root     1285: // Previous MMU 68030
        !          1286: static void m68k_run_mmu030 (void)
1.1.1.2   root     1287: {
1.1.1.5 ! root     1288:        uae_u16 opcode;
        !          1289:        uaecptr pc;
        !          1290:        struct flag_struct f;
        !          1291:        f.cznv = 0;
        !          1292:        f.x    = 0;
        !          1293:     int intr             = 0;
        !          1294:     int lastintr         = 0;
        !          1295:        mmu030_opcode_stageb = -1;
        !          1296: retry:
        !          1297:        TRY (prb) {
        !          1298:                for (;;) {
        !          1299:                        int cnt;
        !          1300: insretry:
        !          1301:                        pc = regs.instruction_pc = m68k_getpc ();
        !          1302:                        f.cznv = regflags.cznv;
        !          1303:                        f.x    = regflags.x;
        !          1304:             
        !          1305:                        mmu030_state[0] = mmu030_state[1] = mmu030_state[2] = 0;
        !          1306:                        mmu030_opcode = -1;
        !          1307:                        if (mmu030_opcode_stageb < 0) {
        !          1308:                                opcode = get_iword_mmu030 (0);
        !          1309:                        } else {
        !          1310:                                opcode = mmu030_opcode_stageb;
        !          1311:                                mmu030_opcode_stageb = -1;
        !          1312:                        }
1.1.1.2   root     1313: 
1.1.1.5 ! root     1314:                        mmu030_opcode = opcode;
        !          1315:                        mmu030_ad[0].done = false;
1.1.1.2   root     1316: 
1.1.1.5 ! root     1317:             Uint64 beforeCycles = nCyclesMainCounter;
        !          1318:                        cnt = 50;
        !          1319:                        for (;;) {
        !          1320:                                opcode = mmu030_opcode;
        !          1321:                                mmu030_idx = 0;
        !          1322:                                mmu030_retry = false;
        !          1323:                                cpu_cycles = (*cpufunctbl[opcode])(opcode);
        !          1324:                                cnt--; // so that we don't get in infinite loop if things go horribly wrong
        !          1325:                                if (!mmu030_retry)
        !          1326:                                        break;
        !          1327:                                if (cnt < 0) {
        !          1328:                                        cpu_halt (9);
        !          1329:                                        break;
        !          1330:                                }
        !          1331:                                if (mmu030_retry && mmu030_opcode == -1)
        !          1332:                                        goto insretry; // urgh
        !          1333:                        }
1.1.1.2   root     1334: 
1.1.1.5 ! root     1335:                        mmu030_opcode = -1;
        !          1336:             
        !          1337:             M68000_AddCycles(cpu_cycles);
        !          1338:             cpu_cycles = nCyclesMainCounter - beforeCycles;
        !          1339:             
        !          1340:                        DSP_Run(cpu_cycles);
        !          1341:             i860_Run(cpu_cycles);
1.1.1.2   root     1342: 
1.1.1.5 ! root     1343:                        /* We can have several interrupts at the same time before the next CPU instruction */
        !          1344:                        /* We must check for pending interrupt and call do_specialties_interrupt() only */
        !          1345:                        /* if the cpu is not in the STOP state. Else, the int could be acknowledged now */
        !          1346:                        /* and prevent exiting the STOP state when calling do_specialties() after. */
        !          1347:                        /* For performance, we first test PendingInterruptCount, then regs.spcflags */
        !          1348:                        while ( ( PendingInterrupt.time <= 0 ) && ( PendingInterrupt.pFunction ) && ( ( regs.spcflags & SPCFLAG_STOP ) == 0 ) ) {
        !          1349:                                CALL_VAR(PendingInterrupt.pFunction);           /* call the interrupt handler */
        !          1350:                        }
1.1.1.2   root     1351: 
1.1.1.5 ! root     1352:             /* Previous: for now we poll the interrupt pins with every instruction.
        !          1353:              * TODO: only do this when an actual interrupt is active to not
        !          1354:              * unneccessarily slow down emulation.
        !          1355:              */
        !          1356:             intr = intlev ();
        !          1357:             if (intr>regs.intmask || (intr==7 && intr>lastintr))
        !          1358:                 do_interrupt (intr, false);
        !          1359:             lastintr = intr;
        !          1360:             
        !          1361:             if(lastRegsS != regs.s) {
        !          1362:                 host_realtime(!(regs.s));
        !          1363:                 lastRegsS = regs.s;
        !          1364:             }
1.1.1.2   root     1365: 
1.1.1.5 ! root     1366:             if (regs.spcflags & ~SPCFLAG_INT) {
        !          1367:                                if (do_specialties (cpu_cycles))
        !          1368:                                        return;
        !          1369:                        }
        !          1370:                }
        !          1371:        } CATCH (prb) {
1.1.1.2   root     1372: 
1.1.1.5 ! root     1373:                regflags.cznv = f.cznv;
        !          1374:                regflags.x    = f.x;
1.1.1.2   root     1375: 
1.1.1.5 ! root     1376:                m68k_setpci (regs.instruction_pc);
1.1.1.2   root     1377: 
1.1.1.5 ! root     1378:                if (mmufixup[0].reg >= 0) {
        !          1379:                        m68k_areg (regs, mmufixup[0].reg) = mmufixup[0].value;
        !          1380:                        mmufixup[0].reg = -1;
1.1.1.2   root     1381:                }
1.1.1.5 ! root     1382:                if (mmufixup[1].reg >= 0) {
        !          1383:                        m68k_areg (regs, mmufixup[1].reg) = mmufixup[1].value;
        !          1384:                        mmufixup[1].reg = -1;
1.1.1.2   root     1385:                }
                   1386: 
1.1.1.5 ! root     1387:                TRY (prb2) {
        !          1388:                        Exception (prb);
        !          1389:                } CATCH (prb2) {
        !          1390:             write_log("[FATAL] double fault\n");
        !          1391:             m68k_reset (1); // auto-reset CPU
        !          1392:                        //cpu_halt (1);
        !          1393:                        return;
        !          1394:                } ENDTRY
        !          1395:        } ENDTRY
        !          1396:     goto retry;
1.1.1.2   root     1397: }
                   1398: 
1.1.1.5 ! root     1399: /* Aranym MMU 68040  */
        !          1400: static void m68k_run_mmu040 (void)
1.1.1.2   root     1401: {
1.1.1.4   root     1402:        uae_u16 opcode;
                   1403:        struct flag_struct f;
1.1.1.5 ! root     1404:        f.cznv = 0;
        !          1405:        f.x    = 0;
1.1.1.4   root     1406:        uaecptr pc;
                   1407:     int intr = 0;
                   1408:     int lastintr = 0;
1.1.1.2   root     1409:        
                   1410:        for (;;) {
                   1411:        TRY (prb) {
                   1412:                for (;;) {
1.1.1.4   root     1413:                        f.cznv = regflags.cznv;
                   1414:                        f.x = regflags.x;
                   1415:                        mmu_restart = true;
                   1416:                        pc = regs.instruction_pc = m68k_getpc ();
1.1.1.5 ! root     1417:         
        !          1418:             Uint64 beforeCycles = nCyclesMainCounter;
1.1.1.4   root     1419:                        mmu_opcode = -1;
                   1420:                        mmu_opcode = opcode = x_prefetch (0);
1.1.1.2   root     1421:                        cpu_cycles = (*cpufunctbl[opcode])(opcode);
1.1.1.5 ! root     1422:             M68000_AddCycles(cpu_cycles);
        !          1423:             
        !          1424:             cpu_cycles = nCyclesMainCounter - beforeCycles;
1.1.1.2   root     1425: 
1.1.1.5 ! root     1426:                        DSP_Run(cpu_cycles);
        !          1427:             i860_Run(cpu_cycles);
1.1.1.2   root     1428: 
                   1429:                        /* We can have several interrupts at the same time before the next CPU instruction */
                   1430:                        /* We must check for pending interrupt and call do_specialties_interrupt() only */
                   1431:                        /* if the cpu is not in the STOP state. Else, the int could be acknowledged now */
                   1432:                        /* and prevent exiting the STOP state when calling do_specialties() after. */
                   1433:                        /* For performance, we first test PendingInterruptCount, then regs.spcflags */
1.1.1.5 ! root     1434:                        while ( ( PendingInterrupt.time <= 0 ) && ( PendingInterrupt.pFunction ) && ( ( regs.spcflags & SPCFLAG_STOP ) == 0 ) ) {
        !          1435:                                CALL_VAR(PendingInterrupt.pFunction);           /* call the interrupt handler */
1.1.1.2   root     1436:                        }
1.1.1.4   root     1437: 
                   1438:             /* Previous: for now we poll the interrupt pins with every instruction.
                   1439:              * TODO: only do this when an actual interrupt is active to not
                   1440:              * unneccessarily slow down emulation.
                   1441:              */
                   1442:             intr = intlev ();
1.1.1.5 ! root     1443:             if (intr>regs.intmask || (intr==7 && intr>lastintr))
1.1.1.4   root     1444:                 do_interrupt (intr, false);
                   1445:             lastintr = intr;
                   1446:             
1.1.1.5 ! root     1447:             if(lastRegsS != regs.s) {
        !          1448:                 host_realtime(!(regs.s));
        !          1449:                 lastRegsS = regs.s;
        !          1450:             }
1.1.1.4   root     1451:             
1.1.1.5 ! root     1452:                        if (regs.spcflags & ~SPCFLAG_INT) {
        !          1453:                                if (do_specialties (cpu_cycles))
1.1.1.2   root     1454:                                        return;
                   1455:                        }
                   1456:                } // end of for(;;)
                   1457:        } CATCH (prb) {
                   1458: 
1.1.1.4   root     1459:                if (mmu_restart) {
                   1460:                        /* restore state if instruction restart */
                   1461:                        regflags.cznv = f.cznv;
                   1462:                        regflags.x = f.x;
1.1.1.5 ! root     1463:                        m68k_setpci (regs.instruction_pc);
1.1.1.4   root     1464:                }
1.1.1.2   root     1465: 
                   1466:                if (mmufixup[0].reg >= 0) {
                   1467:                        m68k_areg (regs, mmufixup[0].reg) = mmufixup[0].value;
                   1468:                        mmufixup[0].reg = -1;
                   1469:                }
                   1470: 
1.1.1.5 ! root     1471:                TRY (prb2) {
        !          1472:                        Exception (prb);
        !          1473:                } CATCH (prb2) {
        !          1474:             write_log("[FATAL] double fault\n");
        !          1475:             m68k_reset (1); // auto-reset CPU
        !          1476:             //cpu_halt (1);
        !          1477:             return;
1.1.1.2   root     1478:                } ENDTRY
                   1479: 
                   1480:        } ENDTRY
                   1481:        }
                   1482: }
                   1483: 
                   1484: #endif /* CPUEMU_0 */
                   1485: 
                   1486: int in_m68k_go = 0;
                   1487: 
1.1.1.5 ! root     1488: #if 0
1.1.1.2   root     1489: static void exception2_handle (uaecptr addr, uaecptr fault)
                   1490: {
                   1491:        last_addr_for_exception_3 = addr;
                   1492:        last_fault_for_exception_3 = fault;
                   1493:        last_writeaccess_for_exception_3 = 0;
                   1494:        last_instructionaccess_for_exception_3 = 0;
1.1.1.4   root     1495:        Exception (2);
1.1.1.2   root     1496: }
1.1.1.5 ! root     1497: #endif
1.1.1.2   root     1498: 
                   1499: void m68k_go (int may_quit)
                   1500: {
                   1501:        int hardboot = 1;
                   1502: 
                   1503:        if (in_m68k_go || !may_quit) {
                   1504:                write_log ("Bug! m68k_go is not reentrant.\n");
1.1.1.5 ! root     1505:         DebugUI();
1.1.1.2   root     1506:        }
1.1.1.5 ! root     1507:     
1.1.1.2   root     1508:        in_m68k_go++;
                   1509:        for (;;) {
                   1510:                void (*run_func)(void);
                   1511:                
                   1512:                if (regs.spcflags & SPCFLAG_BRK) {
                   1513:                        unset_special(SPCFLAG_BRK);
                   1514:                                break;
                   1515:                }
                   1516: 
                   1517:                        quit_program = 0;
                   1518:                        hardboot = 0;
                   1519: 
                   1520: #ifdef DEBUGGER
                   1521:                if (debugging)
                   1522:                        debug ();
                   1523: #endif
1.1.1.5 ! root     1524:         
1.1.1.2   root     1525:        set_x_funcs ();
1.1.1.5 ! root     1526:         run_func=currprefs.cpu_model == 68040 ? m68k_run_mmu040 : m68k_run_mmu030;
1.1.1.2   root     1527:                run_func ();
                   1528:        }
                   1529:        in_m68k_go--;
                   1530: }
                   1531: 
                   1532: 
1.1.1.5 ! root     1533: #if 1
        !          1534: TCHAR* buf_out (TCHAR *buffer, int *bufsize, const TCHAR *format, ...)
1.1.1.2   root     1535: {
1.1.1.5 ! root     1536:     va_list parms;
        !          1537:     
        !          1538:     if (buffer == NULL)
        !          1539:     {
        !          1540:         return NULL;
        !          1541:     }
        !          1542:     
        !          1543:     va_start (parms, format);
        !          1544:     vsnprintf (buffer, (*bufsize) - 1, format, parms);
        !          1545:     va_end (parms);
        !          1546:     *bufsize -= _tcslen (buffer);
        !          1547:     
        !          1548:     return buffer + _tcslen (buffer);
1.1.1.2   root     1549: }
1.1.1.5 ! root     1550: #endif
1.1.1.2   root     1551: 
1.1.1.5 ! root     1552: static const TCHAR *ccnames[] =
1.1.1.2   root     1553: {
1.1.1.5 ! root     1554:     _T("T "),_T("F "),_T("HI"),_T("LS"),_T("CC"),_T("CS"),_T("NE"),_T("EQ"),
        !          1555:     _T("VC"),_T("VS"),_T("PL"),_T("MI"),_T("GE"),_T("LT"),_T("GT"),_T("LE")
        !          1556: };
        !          1557: static const TCHAR *fpccnames[] =
        !          1558: {
        !          1559:     _T("F"),
        !          1560:     _T("EQ"),
        !          1561:     _T("OGT"),
        !          1562:     _T("OGE"),
        !          1563:     _T("OLT"),
        !          1564:     _T("OLE"),
        !          1565:     _T("OGL"),
        !          1566:     _T("OR"),
        !          1567:     _T("UN"),
        !          1568:     _T("UEQ"),
        !          1569:     _T("UGT"),
        !          1570:     _T("UGE"),
        !          1571:     _T("ULT"),
        !          1572:     _T("ULE"),
        !          1573:     _T("NE"),
        !          1574:     _T("T"),
        !          1575:     _T("SF"),
        !          1576:     _T("SEQ"),
        !          1577:     _T("GT"),
        !          1578:     _T("GE"),
        !          1579:     _T("LT"),
        !          1580:     _T("LE"),
        !          1581:     _T("GL"),
        !          1582:     _T("GLE"),
        !          1583:     _T("NGLE"),
        !          1584:     _T("NGL"),
        !          1585:     _T("NLE"),
        !          1586:     _T("NLT"),
        !          1587:     _T("NGE"),
        !          1588:     _T("NGT"),
        !          1589:     _T("SNE"),
        !          1590:     _T("ST")
        !          1591: };
        !          1592: static const TCHAR *fpuopcodes[] =
        !          1593: {
        !          1594:     _T("FMOVE"),
        !          1595:     _T("FINT"),
        !          1596:     _T("FSINH"),
        !          1597:     _T("FINTRZ"),
        !          1598:     _T("FSQRT"),
        !          1599:     NULL,
        !          1600:     _T("FLOGNP1"),
        !          1601:     NULL,
        !          1602:     _T("FETOXM1"),
        !          1603:     _T("FTANH"),
        !          1604:     _T("FATAN"),
        !          1605:     NULL,
        !          1606:     _T("FASIN"),
        !          1607:     _T("FATANH"),
        !          1608:     _T("FSIN"),
        !          1609:     _T("FTAN"),
        !          1610:     _T("FETOX"),       // 0x10
        !          1611:     _T("FTWOTOX"),
        !          1612:     _T("FTENTOX"),
        !          1613:     NULL,
        !          1614:     _T("FLOGN"),
        !          1615:     _T("FLOG10"),
        !          1616:     _T("FLOG2"),
        !          1617:     NULL,
        !          1618:     _T("FABS"),
        !          1619:     _T("FCOSH"),
        !          1620:     _T("FNEG"),
        !          1621:     NULL,
        !          1622:     _T("FACOS"),
        !          1623:     _T("FCOS"),
        !          1624:     _T("FGETEXP"),
        !          1625:     _T("FGETMAN"),
        !          1626:     _T("FDIV"),                // 0x20
        !          1627:     _T("FMOD"),
        !          1628:     _T("FADD"),
        !          1629:     _T("FMUL"),
        !          1630:     _T("FSGLDIV"),
        !          1631:     _T("FREM"),
        !          1632:     _T("FSCALE"),
        !          1633:     _T("FSGLMUL"),
        !          1634:     _T("FSUB"),
        !          1635:     NULL,
        !          1636:     NULL,
        !          1637:     NULL,
        !          1638:     NULL,
        !          1639:     NULL,
        !          1640:     NULL,
        !          1641:     NULL,
        !          1642:     _T("FSINCOS"),     // 0x30
        !          1643:     _T("FSINCOS"),
        !          1644:     _T("FSINCOS"),
        !          1645:     _T("FSINCOS"),
        !          1646:     _T("FSINCOS"),
        !          1647:     _T("FSINCOS"),
        !          1648:     _T("FSINCOS"),
        !          1649:     _T("FSINCOS"),
        !          1650:     _T("FCMP"),
        !          1651:     NULL,
        !          1652:     _T("FTST"),
        !          1653:     NULL,
        !          1654:     NULL,
        !          1655:     NULL,
        !          1656:     NULL,
        !          1657:     NULL
        !          1658: };
1.1.1.2   root     1659: 
1.1.1.5 ! root     1660: static const TCHAR *movemregs[] =
1.1.1.2   root     1661: {
1.1.1.5 ! root     1662:     _T("D0"),
        !          1663:     _T("D1"),
        !          1664:     _T("D2"),
        !          1665:     _T("D3"),
        !          1666:     _T("D4"),
        !          1667:     _T("D5"),
        !          1668:     _T("D6"),
        !          1669:     _T("D7"),
        !          1670:     _T("A0"),
        !          1671:     _T("A1"),
        !          1672:     _T("A2"),
        !          1673:     _T("A3"),
        !          1674:     _T("A4"),
        !          1675:     _T("A5"),
        !          1676:     _T("A6"),
        !          1677:     _T("A7"),
        !          1678:     _T("FP0"),
        !          1679:     _T("FP1"),
        !          1680:     _T("FP2"),
        !          1681:     _T("FP3"),
        !          1682:     _T("FP4"),
        !          1683:     _T("FP5"),
        !          1684:     _T("FP6"),
        !          1685:     _T("FP7"),
        !          1686:     _T("FPIAR"),
        !          1687:     _T("FPSR"),
        !          1688:     _T("FPCR")
        !          1689: };
1.1.1.2   root     1690: 
1.1.1.5 ! root     1691: static void addmovemreg (TCHAR *out, int *prevreg, int *lastreg, int *first, int reg, int fpmode)
        !          1692: {
        !          1693:     TCHAR *p = out + _tcslen (out);
        !          1694:     if (*prevreg < 0) {
        !          1695:         *prevreg = reg;
        !          1696:         *lastreg = reg;
        !          1697:         return;
        !          1698:     }
        !          1699:     if (reg < 0 || fpmode == 2 || (*prevreg) + 1 != reg || (reg & 8) != ((*prevreg & 8))) {
        !          1700:         _stprintf (p, _T("%s%s"), (*first) ? _T("") : _T("/"), movemregs[*lastreg]);
        !          1701:         p = p + _tcslen (p);
        !          1702:         if (*lastreg != *prevreg) {
        !          1703:             if ((*lastreg) + 2 == reg) {
        !          1704:                 _stprintf(p, _T("/%s"), movemregs[*prevreg]);
        !          1705:             } else if ((*lastreg) != (*prevreg)) {
        !          1706:                 _stprintf(p, _T("-%s"), movemregs[*prevreg]);
        !          1707:             }
        !          1708:         }
        !          1709:         *lastreg = reg;
        !          1710:         *first = 0;
        !          1711:     }
        !          1712:     *prevreg = reg;
1.1.1.2   root     1713: }
                   1714: 
1.1.1.5 ! root     1715: static void movemout (TCHAR *out, uae_u16 mask, int mode, int fpmode)
1.1.1.2   root     1716: {
1.1.1.5 ! root     1717:     unsigned int dmask, amask;
        !          1718:     int prevreg = -1, lastreg = -1, first = 1;
        !          1719:     int i;
        !          1720:     
        !          1721:     if (mode == Apdi && !fpmode) {
        !          1722:         uae_u8 dmask2;
        !          1723:         uae_u8 amask2;
        !          1724:         
        !          1725:         amask2 = mask & 0xff;
        !          1726:         dmask2 = (mask >> 8) & 0xff;
        !          1727:         dmask = 0;
        !          1728:         amask = 0;
        !          1729:         for (i = 0; i < 8; i++) {
        !          1730:             if (dmask2 & (1 << i))
        !          1731:                 dmask |= 1 << (7 - i);
        !          1732:             if (amask2 & (1 << i))
        !          1733:                 amask |= 1 << (7 - i);
        !          1734:         }
        !          1735:     } else {
        !          1736:         dmask = mask & 0xff;
        !          1737:         amask = (mask >> 8) & 0xff;
        !          1738:         if (fpmode == 1 && mode != Apdi) {
        !          1739:             uae_u8 dmask2 = dmask;
        !          1740:             dmask = 0;
        !          1741:             for (i = 0; i < 8; i++) {
        !          1742:                 if (dmask2 & (1 << i))
        !          1743:                     dmask |= 1 << (7 - i);
        !          1744:             }
        !          1745:         }
        !          1746:     }
        !          1747:     if (fpmode) {
        !          1748:         while (dmask) { addmovemreg(out, &prevreg, &lastreg, &first, movem_index1[dmask] + (fpmode == 2 ? 24 : 16), fpmode); dmask = movem_next[dmask]; }
        !          1749:     } else {
        !          1750:         while (dmask) { addmovemreg (out, &prevreg, &lastreg, &first, movem_index1[dmask], fpmode); dmask = movem_next[dmask]; }
        !          1751:         while (amask) { addmovemreg (out, &prevreg, &lastreg, &first, movem_index1[amask] + 8, fpmode); amask = movem_next[amask]; }
        !          1752:     }
        !          1753:     addmovemreg(out, &prevreg, &lastreg, &first, -1, fpmode);
        !          1754: }
1.1.1.2   root     1755: 
1.1.1.5 ! root     1756: static const TCHAR *fpsizes[] = {
        !          1757:     _T("L"),
        !          1758:     _T("S"),
        !          1759:     _T("X"),
        !          1760:     _T("P"),
        !          1761:     _T("W"),
        !          1762:     _T("D"),
        !          1763:     _T("B"),
        !          1764:     _T("P")
        !          1765: };
        !          1766: static const int fpsizeconv[] = {
        !          1767:     sz_long,
        !          1768:     sz_single,
        !          1769:     sz_extended,
        !          1770:     sz_packed,
        !          1771:     sz_word,
        !          1772:     sz_double,
        !          1773:     sz_byte,
        !          1774:     sz_packed
        !          1775: };
1.1.1.2   root     1776: 
1.1.1.5 ! root     1777: static void disasm_size (TCHAR *instrname, struct instr *dp)
        !          1778: {
        !          1779:     if (dp->unsized) {
        !          1780:         _tcscat(instrname, _T(" "));
        !          1781:         return;
        !          1782:     }
        !          1783:     switch (dp->size)
        !          1784:     {
        !          1785:         case sz_byte:
        !          1786:             _tcscat (instrname, _T(".B "));
        !          1787:             break;
        !          1788:         case sz_word:
        !          1789:             _tcscat (instrname, _T(".W "));
        !          1790:             break;
        !          1791:         case sz_long:
        !          1792:             _tcscat (instrname, _T(".L "));
        !          1793:             break;
        !          1794:         default:
        !          1795:             _tcscat (instrname, _T(" "));
        !          1796:             break;
        !          1797:     }
        !          1798: }
1.1.1.2   root     1799: 
1.1.1.5 ! root     1800: void m68k_disasm_2 (TCHAR *buf, int bufsize, uaecptr pc, uaecptr *nextpc, int cnt, uae_u32 *seaddr, uae_u32 *deaddr, int safemode)
        !          1801: {
        !          1802:     uae_u32 seaddr2;
        !          1803:     uae_u32 deaddr2;
        !          1804:     
        !          1805:     if (buf)
        !          1806:         memset (buf, 0, bufsize * sizeof (TCHAR));
        !          1807:     if (!table68k)
        !          1808:         return;
        !          1809:     while (cnt-- > 0) {
        !          1810:         TCHAR instrname[100], *ccpt;
        !          1811:         int i;
        !          1812:         uae_u32 opcode;
        !          1813:         uae_u16 extra;
        !          1814:         struct mnemolookup *lookup;
        !          1815:         struct instr *dp;
        !          1816:         uaecptr oldpc;
        !          1817:         uaecptr m68kpc_illg = 0;
        !          1818:         bool illegal = false;
        !          1819:         
        !          1820:         seaddr2 = deaddr2 = 0;
        !          1821:         oldpc = pc;
        !          1822:         opcode = get_word_debug (pc);
        !          1823:         extra = get_word_debug (pc + 2);
        !          1824:         if (cpufunctbl[opcode] == op_illg_1 || cpufunctbl[opcode] == op_unimpl_1) {
        !          1825:             m68kpc_illg = pc + 2;
        !          1826:             illegal = true;
        !          1827:         }
        !          1828:         
        !          1829:         dp = table68k + opcode;
        !          1830:         if (dp->mnemo == i_ILLG) {
        !          1831:             illegal = false;
        !          1832:             opcode = 0x4AFC;
        !          1833:             dp = table68k + opcode;
        !          1834:         }
        !          1835:         for (lookup = lookuptab;lookup->mnemo != dp->mnemo; lookup++)
        !          1836:             ;
        !          1837:         
        !          1838:         buf = buf_out (buf, &bufsize, _T("%08X "), pc);
        !          1839:         
        !          1840:         pc += 2;
        !          1841:         
        !          1842:         if (lookup->friendlyname)
        !          1843:             _tcscpy (instrname, lookup->friendlyname);
        !          1844:         else
        !          1845:             _tcscpy (instrname, lookup->name);
        !          1846:         ccpt = _tcsstr (instrname, _T("cc"));
        !          1847:         if (ccpt != 0) {
        !          1848:             if ((opcode & 0xf000) == 0xf000)
        !          1849:                 _tcscpy (ccpt, fpccnames[extra & 0x1f]);
        !          1850:             else
        !          1851:                 _tcsncpy (ccpt, ccnames[dp->cc], 2);
        !          1852:         }
        !          1853:         disasm_size (instrname, dp);
        !          1854:         
        !          1855:         if (lookup->mnemo == i_MOVEC2 || lookup->mnemo == i_MOVE2C) {
        !          1856:             uae_u16 imm = extra;
        !          1857:             uae_u16 creg = imm & 0x0fff;
        !          1858:             uae_u16 r = imm >> 12;
        !          1859:             TCHAR regs[16];
        !          1860:             const TCHAR *cname = _T("?");
        !          1861:             int i;
        !          1862:             for (i = 0; m2cregs[i].regname; i++) {
        !          1863:                 if (m2cregs[i].regno == creg)
        !          1864:                     break;
        !          1865:             }
        !          1866:             _stprintf (regs, _T("%c%d"), r >= 8 ? 'A' : 'D', r >= 8 ? r - 8 : r);
        !          1867:             if (m2cregs[i].regname)
        !          1868:                 cname = m2cregs[i].regname;
        !          1869:             if (lookup->mnemo == i_MOVE2C) {
        !          1870:                 _tcscat (instrname, regs);
        !          1871:                 _tcscat (instrname, _T(","));
        !          1872:                 _tcscat (instrname, cname);
        !          1873:             } else {
        !          1874:                 _tcscat (instrname, cname);
        !          1875:                 _tcscat (instrname, _T(","));
        !          1876:                 _tcscat (instrname, regs);
        !          1877:             }
        !          1878:             pc += 2;
        !          1879:         } else if (lookup->mnemo == i_MVMEL) {
        !          1880:             uae_u16 mask = extra;
        !          1881:             pc += 2;
        !          1882:             pc = ShowEA (0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, deaddr, safemode);
        !          1883:             _tcscat (instrname, _T(","));
        !          1884:             movemout (instrname, mask, dp->dmode, 0);
        !          1885:         } else if (lookup->mnemo == i_MVMLE) {
        !          1886:             uae_u16 mask = extra;
        !          1887:             pc += 2;
        !          1888:             movemout(instrname, mask, dp->dmode, 0);
        !          1889:             _tcscat(instrname, _T(","));
        !          1890:             pc = ShowEA(0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, deaddr, safemode);
        !          1891:         } else if (lookup->mnemo == i_DIVL || lookup->mnemo == i_MULL) {
        !          1892:             TCHAR *p;
        !          1893:             pc = ShowEA(0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, safemode);
        !          1894:             extra = get_word_debug(pc);
        !          1895:             pc += 2;
        !          1896:             p = instrname + _tcslen(instrname);
        !          1897:             if (extra & 0x0400)
        !          1898:                 _stprintf(p, _T(",D%d:D%d"), extra & 7, (extra >> 12) & 7);
        !          1899:             else
        !          1900:                 _stprintf(p, _T(",D%d"), (extra >> 12) & 7);
        !          1901:         } else if (lookup->mnemo == i_MOVES) {
        !          1902:             TCHAR *p;
        !          1903:             pc += 2;
        !          1904:             if (!(extra & 0x1000)) {
        !          1905:                 pc = ShowEA(0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, safemode);
        !          1906:                 p = instrname + _tcslen(instrname);
        !          1907:                 _stprintf(p, _T(",%c%d"), (extra & 0x8000) ? 'A' : 'D', (extra >> 12) & 7);
        !          1908:             } else {
        !          1909:                 p = instrname + _tcslen(instrname);
        !          1910:                 _stprintf(p, _T("%c%d,"), (extra & 0x8000) ? 'A' : 'D', (extra >> 12) & 7);
        !          1911:                 pc = ShowEA(0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, safemode);
        !          1912:             }
        !          1913:         } else if (lookup->mnemo == i_BFEXTS || lookup->mnemo == i_BFEXTU ||
        !          1914:                    lookup->mnemo == i_BFCHG || lookup->mnemo == i_BFCLR ||
        !          1915:                    lookup->mnemo == i_BFFFO || lookup->mnemo == i_BFINS ||
        !          1916:                    lookup->mnemo == i_BFSET || lookup->mnemo == i_BFTST) {
        !          1917:             TCHAR *p;
        !          1918:             int reg = -1;
        !          1919:             
        !          1920:             pc += 2;
        !          1921:             p = instrname + _tcslen(instrname);
        !          1922:             if (lookup->mnemo == i_BFEXTS || lookup->mnemo == i_BFEXTU || lookup->mnemo == i_BFFFO || lookup->mnemo == i_BFINS)
        !          1923:                 reg = (extra >> 12) & 7;
        !          1924:             if (lookup->mnemo == i_BFINS)
        !          1925:                 _stprintf(p, _T("D%d,"), reg);
        !          1926:             pc = ShowEA(0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, safemode);
        !          1927:             _tcscat(instrname, _T(" {"));
        !          1928:             p = instrname + _tcslen(instrname);
        !          1929:             if (extra & 0x0800)
        !          1930:                 _stprintf(p, _T("D%d"), (extra >> 6) & 7);
        !          1931:             else
        !          1932:                 _stprintf(p, _T("%d"), (extra >> 6) & 31);
        !          1933:             _tcscat(instrname, _T(":"));
        !          1934:             p = instrname + _tcslen(instrname);
        !          1935:             if (extra & 0x0020)
        !          1936:                 _stprintf(p, _T("D%d"), extra & 7);
        !          1937:             else
        !          1938:                 _stprintf(p, _T("%d"), extra  & 31);
        !          1939:             _tcscat(instrname, _T("}"));
        !          1940:             p = instrname + _tcslen(instrname);
        !          1941:             if (lookup->mnemo == i_BFFFO || lookup->mnemo == i_BFEXTS || lookup->mnemo == i_BFEXTU)
        !          1942:                 _stprintf(p, _T(",D%d"), reg);
        !          1943:         } else if (lookup->mnemo == i_CPUSHA || lookup->mnemo == i_CPUSHL || lookup->mnemo == i_CPUSHP ||
        !          1944:                    lookup->mnemo == i_CINVA || lookup->mnemo == i_CINVL || lookup->mnemo == i_CINVP) {
        !          1945:             if ((opcode & 0xc0) == 0xc0)
        !          1946:                 _tcscat(instrname, _T("BC"));
        !          1947:             else if (opcode & 0x80)
        !          1948:                 _tcscat(instrname, _T("IC"));
        !          1949:             else if (opcode & 0x40)
        !          1950:                 _tcscat(instrname, _T("DC"));
        !          1951:             else
        !          1952:                 _tcscat(instrname, _T("?"));
        !          1953:             if (lookup->mnemo == i_CPUSHL || lookup->mnemo == i_CPUSHP || lookup->mnemo == i_CINVL || lookup->mnemo == i_CINVP) {
        !          1954:                 TCHAR *p = instrname + _tcslen(instrname);
        !          1955:                 _stprintf(p, _T(",(A%d)"), opcode & 7);
        !          1956:             }
        !          1957:         } else if (lookup->mnemo == i_FPP) {
        !          1958:             TCHAR *p;
        !          1959:             int ins = extra & 0x3f;
        !          1960:             int size = (extra >> 10) & 7;
        !          1961:             
        !          1962:             pc += 2;
        !          1963:             if ((extra & 0xfc00) == 0x5c00) { // FMOVECR (=i_FPP with source specifier = 7)
        !          1964:                 fptype fp;
        !          1965:                 if (fpu_get_constant(&fp, extra & 0x3f))
        !          1966:                     _stprintf(instrname, _T("FMOVECR.X #%s,FP%d"), fp_print(&fp), (extra >> 7) & 7);
        !          1967:                 else
        !          1968:                     _stprintf(instrname, _T("FMOVECR.X #?,FP%d"), (extra >> 7) & 7);
        !          1969:             } else if ((extra & 0x8000) == 0x8000) { // FMOVEM
        !          1970:                 int dr = (extra >> 13) & 1;
        !          1971:                 int mode;
        !          1972:                 int dreg = (extra >> 4) & 7;
        !          1973:                 int regmask, fpmode;
        !          1974:                 
        !          1975:                 if (extra & 0x4000) {
        !          1976:                     mode = (extra >> 11) & 3;
        !          1977:                     regmask = extra & 0xff;  // FMOVEM FPx
        !          1978:                     fpmode = 1;
        !          1979:                     _tcscpy(instrname, _T("FMOVEM.X "));
        !          1980:                 } else {
        !          1981:                     mode = 0;
        !          1982:                     regmask = (extra >> 10) & 7;  // FMOVEM control
        !          1983:                     fpmode = 2;
        !          1984:                     _tcscpy(instrname, _T("FMOVEM.L "));
        !          1985:                     if (regmask == 1 || regmask == 2 || regmask == 4)
        !          1986:                         _tcscpy(instrname, _T("FMOVE.L "));
        !          1987:                 }
        !          1988:                 p = instrname + _tcslen(instrname);
        !          1989:                 if (dr) {
        !          1990:                     if (mode & 1)
        !          1991:                         _stprintf(instrname, _T("D%d"), dreg);
        !          1992:                     else
        !          1993:                         movemout(instrname, regmask, dp->dmode, fpmode);
        !          1994:                     _tcscat(instrname, _T(","));
        !          1995:                     pc = ShowEA(0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, deaddr, safemode);
        !          1996:                 } else {
        !          1997:                     pc = ShowEA(0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, deaddr, safemode);
        !          1998:                     _tcscat(instrname, _T(","));
        !          1999:                     p = instrname + _tcslen(instrname);
        !          2000:                     if (mode & 1)
        !          2001:                         _stprintf(p, _T("D%d"), dreg);
        !          2002:                     else
        !          2003:                         movemout(p, regmask, dp->dmode, fpmode);
        !          2004:                 }
        !          2005:             } else {
        !          2006:                 if (fpuopcodes[ins])
        !          2007:                     _tcscpy(instrname, fpuopcodes[ins]);
        !          2008:                 else
        !          2009:                     _tcscpy(instrname, _T("F?"));
        !          2010:                 
        !          2011:                 if ((extra & 0xe000) == 0x6000) { // FMOVE to memory
        !          2012:                     int kfactor = extra & 0x7f;
        !          2013:                     _tcscpy(instrname, _T("FMOVE."));
        !          2014:                     _tcscat(instrname, fpsizes[size]);
        !          2015:                     _tcscat(instrname, _T(" "));
        !          2016:                     p = instrname + _tcslen(instrname);
        !          2017:                     _stprintf(p, _T("FP%d,"), (extra >> 7) & 7);
        !          2018:                     pc = ShowEA(0, pc, opcode, dp->dreg, dp->dmode, fpsizeconv[size], instrname, &deaddr2, safemode);
        !          2019:                     p = instrname + _tcslen(instrname);
        !          2020:                     if (size == 7) {
        !          2021:                         _stprintf(p, _T(" {D%d}"), (kfactor >> 4));
        !          2022:                     } else if (kfactor) {
        !          2023:                         if (kfactor & 0x40)
        !          2024:                             kfactor |= ~0x3f;
        !          2025:                         _stprintf(p, _T(" {%d}"), kfactor);
        !          2026:                     }
        !          2027:                 } else {
        !          2028:                     if (extra & 0x4000) { // source is EA
        !          2029:                         _tcscat(instrname, _T("."));
        !          2030:                         _tcscat(instrname, fpsizes[size]);
        !          2031:                         _tcscat(instrname, _T(" "));
        !          2032:                         pc = ShowEA(0, pc, opcode, dp->dreg, dp->dmode, fpsizeconv[size], instrname, &seaddr2, safemode);
        !          2033:                     } else { // source is FPx
        !          2034:                         p = instrname + _tcslen(instrname);
        !          2035:                         _stprintf(p, _T(".X FP%d"), (extra >> 10) & 7);
        !          2036:                     }
        !          2037:                     p = instrname + _tcslen(instrname);
        !          2038:                     if ((extra & 0x4000) || (((extra >> 7) & 7) != ((extra >> 10) & 7)))
        !          2039:                         _stprintf(p, _T(",FP%d"), (extra >> 7) & 7);
        !          2040:                     if (ins >= 0x30 && ins < 0x38) { // FSINCOS
        !          2041:                         p = instrname + _tcslen(instrname);
        !          2042:                         _stprintf(p, _T(",FP%d"), extra & 7);
        !          2043:                     }
        !          2044:                 }
        !          2045:             }
        !          2046:         } else if ((opcode & 0xf000) == 0xa000) {
        !          2047:             _tcscpy(instrname, _T("A-LINE"));
        !          2048:         } else {
        !          2049:             if (dp->suse) {
        !          2050:                 pc = ShowEA (0, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, &seaddr2, safemode);
        !          2051:             }
        !          2052:             if (dp->suse && dp->duse)
        !          2053:                 _tcscat (instrname, _T(","));
        !          2054:             if (dp->duse) {
        !          2055:                 pc = ShowEA (0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &deaddr2, safemode);
        !          2056:             }
        !          2057:         }
        !          2058:         
        !          2059:         for (i = 0; i < (int)(pc - oldpc) / 2 && i < 5; i++) {
        !          2060:             buf = buf_out (buf, &bufsize, _T("%04x "), get_word_debug (oldpc + i * 2));
        !          2061:         }
        !          2062:         while (i++ < 5)
        !          2063:             buf = buf_out (buf, &bufsize, _T("     "));
        !          2064:         
        !          2065:         if (illegal)
        !          2066:             buf = buf_out (buf, &bufsize, _T("[ "));
        !          2067:         buf = buf_out (buf, &bufsize, instrname);
        !          2068:         if (illegal)
        !          2069:             buf = buf_out (buf, &bufsize, _T(" ]"));
        !          2070:         
        !          2071:         if (ccpt != 0) {
        !          2072:             uaecptr addr2 = deaddr2 ? deaddr2 : seaddr2;
        !          2073:             if (deaddr)
        !          2074:                 *deaddr = pc;
        !          2075:             if ((opcode & 0xf000) == 0xf000) {
        !          2076:                 if (fpp_cond(dp->cc)) {
        !          2077:                     buf = buf_out(buf, &bufsize, _T(" == $%08x (T)"), addr2);
        !          2078:                 } else {
        !          2079:                     buf = buf_out(buf, &bufsize, _T(" == $%08x (F)"), addr2);
        !          2080:                 }
        !          2081:             } else {
        !          2082:                 if (cctrue (dp->cc)) {
        !          2083:                     buf = buf_out (buf, &bufsize, _T(" == $%08x (T)"), addr2);
        !          2084:                 } else {
        !          2085:                     buf = buf_out (buf, &bufsize, _T(" == $%08x (F)"), addr2);
        !          2086:                 }
        !          2087:             }
        !          2088:         } else if ((opcode & 0xff00) == 0x6100) { /* BSR */
        !          2089:             if (deaddr)
        !          2090:                 *deaddr = pc;
        !          2091:             buf = buf_out (buf, &bufsize, _T(" == $%08x"), seaddr2);
        !          2092:         }
        !          2093:         buf = buf_out (buf, &bufsize, _T("\n"));
        !          2094:         
        !          2095:         if (illegal)
        !          2096:             pc =  m68kpc_illg;
        !          2097:     }
        !          2098:     if (nextpc)
        !          2099:         *nextpc = pc;
        !          2100:     if (seaddr)
        !          2101:         *seaddr = seaddr2;
        !          2102:     if (deaddr)
        !          2103:         *deaddr = deaddr2;
1.1.1.2   root     2104: }
                   2105: 
1.1.1.5 ! root     2106: void m68k_disasm_ea (uaecptr addr, uaecptr *nextpc, int cnt, uae_u32 *seaddr, uae_u32 *deaddr)
1.1.1.2   root     2107: {
1.1.1.5 ! root     2108:     TCHAR *buf;
        !          2109:     
        !          2110:     buf = xmalloc (TCHAR, (MAX_LINEWIDTH + 1) * cnt);
        !          2111:     if (!buf)
        !          2112:         return;
        !          2113:     m68k_disasm_2 (buf, (MAX_LINEWIDTH + 1) * cnt, addr, nextpc, cnt, seaddr, deaddr, 1);
        !          2114:     xfree (buf);
1.1.1.2   root     2115: }
1.1.1.5 ! root     2116: void m68k_disasm (uaecptr addr, uaecptr *nextpc, int cnt)
1.1.1.2   root     2117: {
1.1.1.5 ! root     2118:     TCHAR *buf;
        !          2119:     
        !          2120:     buf = xmalloc (TCHAR, (MAX_LINEWIDTH + 1) * cnt);
        !          2121:     if (!buf)
        !          2122:         return;
        !          2123:     m68k_disasm_2 (buf, (MAX_LINEWIDTH + 1) * cnt, addr, nextpc, cnt, NULL, NULL, 0);
        !          2124:     printf (_T("%s"), buf);
        !          2125:     xfree (buf);
1.1.1.2   root     2126: }
                   2127: 
                   2128: /*************************************************************
                   2129: Disasm the m68kcode at the given address into instrname
                   2130: and instrcode
                   2131: *************************************************************/
                   2132: void sm68k_disasm (TCHAR *instrname, TCHAR *instrcode, uaecptr addr, uaecptr *nextpc)
                   2133: {
1.1.1.5 ! root     2134:     TCHAR *ccpt;
        !          2135:     uae_u32 opcode;
        !          2136:     struct mnemolookup *lookup;
        !          2137:     struct instr *dp;
        !          2138:     uaecptr pc, oldpc;
        !          2139:     
        !          2140:     pc = oldpc = addr;
        !          2141:     opcode = get_word_debug (pc);
        !          2142:     if (cpufunctbl[opcode] == op_illg_1) {
        !          2143:         opcode = 0x4AFC;
        !          2144:     }
        !          2145:     dp = table68k + opcode;
        !          2146:     for (lookup = lookuptab;lookup->mnemo != dp->mnemo; lookup++);
        !          2147:     
        !          2148:     pc += 2;
        !          2149:     
        !          2150:     _tcscpy (instrname, lookup->name);
        !          2151:     ccpt = _tcsstr (instrname, _T("cc"));
        !          2152:     if (ccpt != 0) {
        !          2153:         _tcsncpy (ccpt, ccnames[dp->cc], 2);
        !          2154:     }
        !          2155:     switch (dp->size){
        !          2156:         case sz_byte: _tcscat (instrname, _T(".B ")); break;
        !          2157:         case sz_word: _tcscat (instrname, _T(".W ")); break;
        !          2158:         case sz_long: _tcscat (instrname, _T(".L ")); break;
        !          2159:         default: _tcscat (instrname, _T("   ")); break;
        !          2160:     }
        !          2161:     
        !          2162:     if (dp->suse) {
        !          2163:         pc = ShowEA (0, pc, opcode, dp->sreg, dp->smode, dp->size, instrname, NULL, 0);
        !          2164:     }
        !          2165:     if (dp->suse && dp->duse)
        !          2166:         _tcscat (instrname, _T(","));
        !          2167:     if (dp->duse) {
        !          2168:         pc = ShowEA (0, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, NULL, 0);
        !          2169:     }
        !          2170:     if (instrcode)
        !          2171:     {
        !          2172:         int i;
        !          2173:         for (i = 0; i < (int)(pc - oldpc) / 2; i++)
        !          2174:         {
        !          2175:             _stprintf (instrcode, _T("%04x "), get_iword_debug (oldpc + i * 2));
        !          2176:             instrcode += _tcslen (instrcode);
        !          2177:         }
        !          2178:     }
        !          2179:     if (nextpc)
        !          2180:         *nextpc = pc;
1.1.1.2   root     2181: }
                   2182: 
                   2183: struct cpum2c m2cregs[] = {
                   2184:        { 0, "SFC" },
                   2185:        { 1, "DFC" },
                   2186:        { 2, "CACR" },
                   2187:        { 3, "TC" },
                   2188:        { 4, "ITT0" },
                   2189:        { 5, "ITT1" },
                   2190:        { 6, "DTT0" },
                   2191:        { 7, "DTT1" },
                   2192:        { 8, "BUSC" },
                   2193:        { 0x800, "USP" },
                   2194:        { 0x801, "VBR" },
                   2195:        { 0x802, "CAAR" },
                   2196:        { 0x803, "MSP" },
                   2197:        { 0x804, "ISP" },
                   2198:        { 0x805, "MMUS" },
                   2199:        { 0x806, "URP" },
                   2200:        { 0x807, "SRP" },
                   2201:        { 0x808, "PCR" },
                   2202:        { -1, NULL }
                   2203: };
                   2204: 
1.1.1.5 ! root     2205: void m68k_dumpstate_2 (uaecptr pc, uaecptr *nextpc)
1.1.1.2   root     2206: {
1.1.1.5 ! root     2207:     int i, j;
        !          2208:     
        !          2209:     for (i = 0; i < 8; i++){
        !          2210:         printf (_T("  D%d %08X "), i, m68k_dreg (regs, i));
        !          2211:         if ((i & 3) == 3) printf (_T("\n"));
        !          2212:     }
        !          2213:     for (i = 0; i < 8; i++){
        !          2214:         printf (_T("  A%d %08X "), i, m68k_areg (regs, i));
        !          2215:         if ((i & 3) == 3) printf (_T("\n"));
        !          2216:     }
        !          2217:     if (regs.s == 0)
        !          2218:         regs.usp = m68k_areg (regs, 7);
        !          2219:     if (regs.s && regs.m)
        !          2220:         regs.msp = m68k_areg (regs, 7);
        !          2221:     if (regs.s && regs.m == 0)
        !          2222:         regs.isp = m68k_areg (regs, 7);
        !          2223:     j = 2;
        !          2224:     printf (_T("USP  %08X ISP  %08X "), regs.usp, regs.isp);
        !          2225:     for (i = 0; m2cregs[i].regno>= 0; i++) {
        !          2226:         if (!movec_illg (m2cregs[i].regno)) {
        !          2227:             if (!_tcscmp (m2cregs[i].regname, _T("USP")) || !_tcscmp (m2cregs[i].regname, _T("ISP")))
        !          2228:                 continue;
        !          2229:             if (j > 0 && (j % 4) == 0)
        !          2230:                 printf (_T("\n"));
        !          2231:             printf (_T("%-4s %08X "), m2cregs[i].regname, val_move2c (m2cregs[i].regno));
        !          2232:             j++;
        !          2233:         }
        !          2234:     }
        !          2235:     if (j > 0)
        !          2236:         printf (_T("\n"));
        !          2237:     printf (_T("T=%d%d S=%d M=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d STP=%d\n"),
        !          2238:                    regs.t1, regs.t0, regs.s, regs.m,
        !          2239:                    GET_XFLG (), GET_NFLG (), GET_ZFLG (),
        !          2240:                    GET_VFLG (), GET_CFLG (),
        !          2241:                    regs.intmask, regs.stopped);
1.1.1.2   root     2242: #ifdef FPUEMU
1.1.1.5 ! root     2243:     if (currprefs.fpu_model) {
        !          2244:         uae_u32 fpsr;
        !          2245:         for (i = 0; i < 8; i++){
        !          2246:             printf (_T("FP%d: %s "), i, fp_print(&regs.fp[i]));
        !          2247:             if ((i & 3) == 3)
        !          2248:                 printf (_T("\n"));
        !          2249:         }
        !          2250:         fpsr = fpp_get_fpsr ();
        !          2251:         printf (_T("FPSR: %08X FPCR: %04x FPIAR: %08x N=%d Z=%d I=%d NAN=%d\n"),
        !          2252:                        fpsr, regs.fpcr, regs.fpiar,
        !          2253:                        (fpsr & 0x8000000) != 0,
        !          2254:                        (fpsr & 0x4000000) != 0,
        !          2255:                        (fpsr & 0x2000000) != 0,
        !          2256:                        (fpsr & 0x1000000) != 0);
        !          2257:     }
1.1.1.2   root     2258: #endif
1.1.1.4   root     2259:     if (currprefs.mmu_model == 68030) {
1.1.1.5 ! root     2260:         printf (_T("SRP: %llX CRP: %llX\n"), srp_030, crp_030);
        !          2261:         printf (_T("TT0: %08X TT1: %08X TC: %08X\n"), tt0_030, tt1_030, tc_030);
        !          2262:     }
        !          2263:     if (currprefs.cpu_compatible && currprefs.cpu_model == 68000) {
        !          2264:         struct instr *dp;
        !          2265:         struct mnemolookup *lookup1, *lookup2;
        !          2266:         dp = table68k + regs.irc;
        !          2267:         for (lookup1 = lookuptab; lookup1->mnemo != dp->mnemo; lookup1++);
        !          2268:         dp = table68k + regs.ir;
        !          2269:         for (lookup2 = lookuptab; lookup2->mnemo != dp->mnemo; lookup2++);
        !          2270:         printf (_T("Prefetch %04x (%s) %04x (%s) Chip latch %08X\n"), regs.irc, lookup1->name, regs.ir, lookup2->name, regs.chipset_latch_rw);
        !          2271:     }
        !          2272:     
        !          2273:     if (pc != 0xffffffff) {
        !          2274:         m68k_disasm (pc, nextpc, 1);
        !          2275:         if (nextpc)
        !          2276:             printf (_T("Next PC: %08x\n"), *nextpc);
1.1.1.4   root     2277:     }
1.1.1.2   root     2278: }
1.1.1.5 ! root     2279: void m68k_dumpstate (uaecptr *nextpc)
1.1.1.2   root     2280: {
1.1.1.5 ! root     2281:     m68k_dumpstate_2 (m68k_getpc (), nextpc);
1.1.1.2   root     2282: }
                   2283: 
1.1.1.5 ! root     2284: static void exception3f (uae_u32 opcode, uaecptr addr, bool writeaccess, bool instructionaccess, bool notinstruction, uaecptr pc, bool plus2)
1.1.1.2   root     2285: {
1.1.1.5 ! root     2286:     if (currprefs.cpu_model >= 68040)
        !          2287:         addr &= ~1;
        !          2288:     if (currprefs.cpu_model >= 68020) {
        !          2289:         if (pc == 0xffffffff)
        !          2290:             last_addr_for_exception_3 = regs.instruction_pc;
        !          2291:         else
        !          2292:             last_addr_for_exception_3 = pc;
        !          2293:     } else if (pc == 0xffffffff) {
        !          2294:         last_addr_for_exception_3 = m68k_getpc ();
        !          2295:         if (plus2)
        !          2296:             last_addr_for_exception_3 += 2;
        !          2297:     } else {
        !          2298:         last_addr_for_exception_3 = pc;
        !          2299:     }
        !          2300:     last_fault_for_exception_3 = addr;
        !          2301:     last_op_for_exception_3 = opcode;
        !          2302:     last_writeaccess_for_exception_3 = writeaccess;
        !          2303:     last_instructionaccess_for_exception_3 = instructionaccess;
        !          2304:     Exception (3);
1.1.1.2   root     2305: }
                   2306: 
1.1.1.5 ! root     2307: void exception3_read(uae_u32 opcode, uaecptr addr)
1.1.1.4   root     2308: {
1.1.1.5 ! root     2309:     exception3f (opcode, addr, false, 0, false, 0xffffffff, false);
1.1.1.4   root     2310: }
                   2311: void exception3i (uae_u32 opcode, uaecptr addr)
1.1.1.2   root     2312: {
1.1.1.5 ! root     2313:     exception3f (opcode, addr, 0, 1, false, 0xffffffff, true);
1.1.1.4   root     2314: }
                   2315: void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc)
                   2316: {
1.1.1.5 ! root     2317:     exception3f (opcode, addr, w, i, false, pc, true);
1.1.1.2   root     2318: }
                   2319: 
1.1.1.4   root     2320: void exception2 (uaecptr addr, bool read, int size, uae_u32 fc)
1.1.1.2   root     2321: {
1.1.1.5 ! root     2322:     if (currprefs.mmu_model == 68030) {
        !          2323:         uae_u32 flags = size == 1 ? MMU030_SSW_SIZE_B : (size == 2 ? MMU030_SSW_SIZE_W : MMU030_SSW_SIZE_L);
        !          2324:         mmu030_page_fault (addr, read, flags, fc);
        !          2325:     } else {
        !          2326:         mmu_bus_error (addr, 0, fc, read == false, size, true);
        !          2327:     }
1.1.1.2   root     2328: }
                   2329: 
1.1.1.5 ! root     2330: void cpureset (void) {
1.1.1.2   root     2331:        uaecptr pc;
                   2332:        uaecptr ksboot = 0xf80002 - 2; /* -2 = RESET hasn't increased PC yet */
                   2333:        uae_u16 ins;
                   2334: 
1.1.1.5 ! root     2335:        if (currprefs.cpu_compatible) {
1.1.1.2   root     2336:                return;
                   2337:        }
1.1.1.5 ! root     2338:     
1.1.1.2   root     2339:        pc = m68k_getpc ();
                   2340:        /* panic, RAM is going to disappear under PC */
                   2341:        ins = get_word (pc + 2);
                   2342:        if ((ins & ~7) == 0x4ed0) {
                   2343:                int reg = ins & 7;
                   2344:                uae_u32 addr = m68k_areg (regs, reg);
                   2345:                write_log ("reset/jmp (ax) combination emulated -> %x\n", addr);
                   2346:                if (addr < 0x80000)
                   2347:                        addr += 0xf80000;
                   2348:                m68k_setpc (addr - 2);
                   2349:                return;
                   2350:        }
                   2351:        write_log ("M68K RESET PC=%x, rebooting..\n", pc);
                   2352:        m68k_setpc (ksboot);
                   2353: }
                   2354: 
                   2355: 
                   2356: void m68k_setstopped (void)
                   2357: {
                   2358:        regs.stopped = 1;
                   2359:        /* A traced STOP instruction drops through immediately without
                   2360:        actually stopping.  */
                   2361:        if ((regs.spcflags & SPCFLAG_DOTRACE) == 0)
                   2362:                set_special (SPCFLAG_STOP);
                   2363:        else
                   2364:                m68k_resumestopped ();
                   2365: }
                   2366: 
                   2367: void m68k_resumestopped (void)
                   2368: {
                   2369:        if (!regs.stopped)
                   2370:                return;
                   2371:        regs.stopped = 0;
                   2372:        unset_special (SPCFLAG_STOP);
                   2373: }

unix.superglobalmegacorp.com

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