Annotation of hatari/src/cpu/debug.c, revision 1.1

1.1     ! root        1: /*
        !             2: * UAE - The Un*x Amiga Emulator
        !             3: *
        !             4: * Debugger
        !             5: *
        !             6: * (c) 1995 Bernd Schmidt
        !             7: * (c) 2006 Toni Wilen
        !             8: *
        !             9: */
        !            10: 
        !            11: #include "sysconfig.h"
        !            12: #include "sysdeps.h"
        !            13: 
        !            14: #include "main.h"
        !            15: #include "hatari-glue.h"
        !            16: 
        !            17: #include <ctype.h>
        !            18: #include <signal.h>
        !            19: 
        !            20: #include "options_cpu.h"
        !            21: //#include "uae.h"
        !            22: #include "memory.h"
        !            23: #include "custom.h"
        !            24: #include "newcpu.h"
        !            25: #include "cpu_prefetch.h"
        !            26: #include "debug.h"
        !            27: //#include "cia.h"
        !            28: //#include "xwin.h"
        !            29: //#include "identify.h"
        !            30: //#include "audio.h"
        !            31: //#include "sound.h"
        !            32: //#include "disk.h"
        !            33: #include "savestate.h"
        !            34: //#include "autoconf.h"
        !            35: //#include "akiko.h"
        !            36: //#include "inputdevice.h"
        !            37: //#include "crc32.h"
        !            38: //#include "rommgr.h"
        !            39: //#include "inputrecord.h"
        !            40: #include "cpummu.h"
        !            41: #include "cpummu030.h"
        !            42: //#include "ppc/ppcd.h"
        !            43: //#include "uae/ppc.h"
        !            44: 
        !            45: #ifdef WINUAE_FOR_HATARI
        !            46: #include "stMemory.h"
        !            47: static int debug_mmu_mode;
        !            48: 
        !            49: #else
        !            50: int debugger_active;
        !            51: static uaecptr skipaddr_start, skipaddr_end;
        !            52: static int skipaddr_doskip;
        !            53: static uae_u32 skipins;
        !            54: static int do_skip;
        !            55: static int debug_rewind;
        !            56: static int memwatch_triggered;
        !            57: int memwatch_enabled;
        !            58: static uae_u16 sr_bpmask, sr_bpvalue;
        !            59: int debugging;
        !            60: int exception_debugging;
        !            61: int no_trace_exceptions;
        !            62: int debug_copper = 0;
        !            63: int debug_dma = 0;
        !            64: int debug_sprite_mask = 0xff;
        !            65: int debug_illegal = 0;
        !            66: uae_u64 debug_illegal_mask;
        !            67: static int debug_mmu_mode;
        !            68: static bool break_if_enforcer;
        !            69: 
        !            70: static uaecptr processptr;
        !            71: static uae_char *processname;
        !            72: 
        !            73: static uaecptr debug_copper_pc;
        !            74: 
        !            75: extern int audio_channel_mask;
        !            76: extern int inputdevice_logging;
        !            77: 
        !            78: void deactivate_debugger (void)
        !            79: {
        !            80:        debugger_active = 0;
        !            81:        debugging = 0;
        !            82:        exception_debugging = 0;
        !            83:        processptr = 0;
        !            84:        xfree (processname);
        !            85:        processname = NULL;
        !            86: }
        !            87: 
        !            88: void activate_debugger (void)
        !            89: {
        !            90:        do_skip = 0;
        !            91:        if (debugger_active)
        !            92:                return;
        !            93:        debugger_active = 1;
        !            94:        set_special (SPCFLAG_BRK);
        !            95:        debugging = 1;
        !            96:        mmu_triggered = 0;
        !            97: }
        !            98: 
        !            99: bool debug_enforcer(void)
        !           100: {
        !           101:        if (!break_if_enforcer)
        !           102:                return false;
        !           103:        activate_debugger();
        !           104:        return true;
        !           105: }
        !           106: 
        !           107: int firsthist = 0;
        !           108: int lasthist = 0;
        !           109: static struct regstruct history[MAX_HIST];
        !           110: 
        !           111: static TCHAR help[] = {
        !           112:        _T("          HELP for UAE Debugger\n")
        !           113:        _T("         -----------------------\n\n")
        !           114:        _T("  g [<address>]         Start execution at the current address or <address>.\n")
        !           115:        _T("  c                     Dump state of the CIA, disk drives and custom registers.\n")
        !           116:        _T("  r                     Dump state of the CPU.\n")
        !           117:        _T("  r <reg> <value>       Modify CPU registers (Dx,Ax,USP,ISP,VBR,...).\n")
        !           118:        _T("  m <address> [<lines>] Memory dump starting at <address>.\n")
        !           119:        _T("  d <address> [<lines>] Disassembly starting at <address>.\n")
        !           120:        _T("  t [instructions]      Step one or more instructions.\n")
        !           121:        _T("  z                     Step through one instruction - useful for JSR, DBRA etc.\n")
        !           122:        _T("  f                     Step forward until PC in RAM (\"boot block finder\").\n")
        !           123:        _T("  f <address>           Add/remove breakpoint.\n")
        !           124:        _T("  fa <address> [<start>] [<end>]\n")
        !           125:        _T("                        Find effective address <address>.\n")
        !           126:        _T("  fi                    Step forward until PC points to RTS, RTD or RTE.\n")
        !           127:        _T("  fi <opcode>           Step forward until PC points to <opcode>.\n")
        !           128:        _T("  fp \"<name>\"/<addr>    Step forward until process <name> or <addr> is active.\n")
        !           129:        _T("  fl                    List breakpoints.\n")
        !           130:        _T("  fd                    Remove all breakpoints.\n")
        !           131:        _T("  fs <lines to wait> | <vpos> <hpos> Wait n scanlines/position.\n")
        !           132:        _T("  fc <CCKs to wait>     Wait n color clocks.\n")
        !           133:        _T("  fS <val> <mask>       Break when (SR & mask) = val.\n")                   
        !           134:        _T("  f <addr1> <addr2>     Step forward until <addr1> <= PC <= <addr2>.\n")
        !           135:        _T("  e                     Dump contents of all custom registers, ea = AGA colors.\n")
        !           136:        _T("  i [<addr>]            Dump contents of interrupt and trap vectors.\n")
        !           137:        _T("  il [<mask>]           Exception breakpoint.\n")
        !           138:        _T("  o <0-2|addr> [<lines>]View memory as Copper instructions.\n")
        !           139:        _T("  od                    Enable/disable Copper vpos/hpos tracing.\n")
        !           140:        _T("  ot                    Copper single step trace.\n")
        !           141:        _T("  ob <addr>             Copper breakpoint.\n")
        !           142:        _T("  H[H] <cnt>            Show PC history (HH=full CPU info) <cnt> instructions.\n")
        !           143:        _T("  C <value>             Search for values like energy or lifes in games.\n")
        !           144:        _T("  Cl                    List currently found trainer addresses.\n")
        !           145:        _T("  D[idxzs <[max diff]>] Deep trainer. i=new value must be larger, d=smaller,\n")
        !           146:        _T("                        x = must be same, z = must be different, s = restart.\n")
        !           147:        _T("  W <address> <values[.x] separated by space> Write into Amiga memory.\n")
        !           148:        _T("  W <address> 'string' Write into Amiga memory.\n")
        !           149:        _T("  w <num> <address> <length> <R/W/I/F/C> [<value>[.x]] (read/write/opcode/freeze/mustchange).\n")
        !           150:        _T("                        Add/remove memory watchpoints.\n")
        !           151:        _T("  wd [<0-1>]            Enable illegal access logger. 1 = enable break.\n")
        !           152:        _T("  S <file> <addr> <n>   Save a block of Amiga memory.\n")
        !           153:        _T("  s \"<string>\"/<values> [<addr>] [<length>]\n")
        !           154:        _T("                        Search for string/bytes.\n")
        !           155:        _T("  T or Tt               Show exec tasks and their PCs.\n")
        !           156:        _T("  Td,Tl,Tr,Tp,Ts,TS,Ti,TO,TM Show devs, libs, resources, ports, semaphores,\n")
        !           157:        _T("                        residents, interrupts, doslist and memorylist.\n")
        !           158:        _T("  b                     Step to previous state capture position.\n")
        !           159:        _T("  M<a/b/s> <val>        Enable or disable audio channels, bitplanes or sprites.\n")
        !           160:        _T("  sp <addr> [<addr2][<size>] Dump sprite information.\n")
        !           161:        _T("  di <mode> [<track>]   Break on disk access. R=DMA read,W=write,RW=both,P=PIO.\n")
        !           162:        _T("                        Also enables level 1 disk logging.\n")
        !           163:        _T("  did <log level>       Enable disk logging.\n")
        !           164:        _T("  dj [<level bitmask>]  Enable joystick/mouse input debugging.\n")
        !           165:        _T("  smc [<0-1>]           Enable self-modifying code detector. 1 = enable break.\n")
        !           166:        _T("  dm                    Dump current address space map.\n")
        !           167:        _T("  v <vpos> [<hpos>]     Show DMA data (accurate only in cycle-exact mode).\n")
        !           168:        _T("                        v [-1 to -4] = enable visual DMA debugger.\n")
        !           169:        _T("  ?<value>              Hex ($ and 0x)/Bin (%)/Dec (!) converter.\n")
        !           170: #ifdef _WIN32
        !           171:        _T("  x                     Close debugger.\n")
        !           172:        _T("  xx                    Switch between console and GUI debugger.\n")
        !           173:        _T("  mg <address>          Memory dump starting at <address> in GUI.\n")
        !           174:        _T("  dg <address>          Disassembly starting at <address> in GUI.\n")
        !           175: #endif
        !           176:        _T("  q                     Quit the emulator. You don't want to use this command.\n\n")
        !           177: };
        !           178: 
        !           179: void debug_help (void)
        !           180: {
        !           181:        console_out (help);
        !           182: }
        !           183: 
        !           184: static int debug_linecounter;
        !           185: #define MAX_LINECOUNTER 1000
        !           186: 
        !           187: static int debug_out (const TCHAR *format, ...)
        !           188: {
        !           189:        va_list parms;
        !           190:        TCHAR buffer[4000];
        !           191: 
        !           192:        va_start (parms, format);
        !           193:        _vsntprintf (buffer, 4000 - 1, format, parms);
        !           194:        va_end (parms);
        !           195: 
        !           196:        console_out (buffer);
        !           197:        if (debug_linecounter < MAX_LINECOUNTER)
        !           198:                debug_linecounter++;
        !           199:        if (debug_linecounter >= MAX_LINECOUNTER)
        !           200:                return 0;
        !           201:        return 1;
        !           202: }
        !           203: 
        !           204: #endif /* ! WINUAE_FOR_HATARI */
        !           205: 
        !           206: uae_u32 get_byte_debug (uaecptr addr)
        !           207: {
        !           208:        uae_u32 v = 0xff;
        !           209:        if (debug_mmu_mode) {
        !           210:                flagtype olds = regs.s;
        !           211:                regs.s = (debug_mmu_mode & 4) != 0;
        !           212:                TRY(p) {
        !           213:                        if (currprefs.mmu_model == 68030) {
        !           214:                                v = mmu030_get_generic (addr, debug_mmu_mode, sz_byte, sz_byte, 0);
        !           215:                        } else {
        !           216:                                v = mmu_get_user_byte (addr, regs.s != 0, (debug_mmu_mode & 1) ? true : false, false, sz_byte);
        !           217:                        }
        !           218:                } CATCH(p) {
        !           219:                } ENDTRY
        !           220:                regs.s = olds;
        !           221:        } else {
        !           222: #ifndef WINUAE_FOR_HATARI
        !           223:                v = get_byte (addr);
        !           224: #else
        !           225:                v = STMemory_ReadByte ( addr );
        !           226: #endif
        !           227:        }
        !           228:        return v;
        !           229: }
        !           230: uae_u32 get_word_debug (uaecptr addr)
        !           231: {
        !           232:        uae_u32 v = 0xffff;
        !           233:        if (debug_mmu_mode) {
        !           234:                flagtype olds = regs.s;
        !           235:                regs.s = (debug_mmu_mode & 4) != 0;
        !           236:                TRY(p) {
        !           237:                        if (currprefs.mmu_model == 68030) {
        !           238:                                v = mmu030_get_generic (addr, debug_mmu_mode, sz_word, sz_word, 0);
        !           239:                        } else {
        !           240:                                v = mmu_get_user_word (addr, regs.s != 0, (debug_mmu_mode & 1) ? true : false, false, sz_word);
        !           241:                        }
        !           242:                } CATCH(p) {
        !           243:                } ENDTRY
        !           244:                regs.s = olds;
        !           245:        } else {
        !           246: #ifndef WINUAE_FOR_HATARI
        !           247:                v = get_word (addr);
        !           248: #else
        !           249:                v = STMemory_ReadWord ( addr );
        !           250: #endif
        !           251:        }
        !           252:        return v;
        !           253: }
        !           254: uae_u32 get_long_debug (uaecptr addr)
        !           255: {
        !           256:        uae_u32 v = 0xffffffff;
        !           257:        if (debug_mmu_mode) {
        !           258:                flagtype olds = regs.s;
        !           259:                regs.s = (debug_mmu_mode & 4) != 0;
        !           260:                TRY(p) {
        !           261:                        if (currprefs.mmu_model == 68030) {
        !           262:                                v = mmu030_get_generic (addr, debug_mmu_mode, sz_long, sz_long, 0);
        !           263:                        } else {
        !           264:                                v = mmu_get_user_long (addr, regs.s != 0, (debug_mmu_mode & 1) ? true : false, false, sz_long);
        !           265:                        }
        !           266:                } CATCH(p) {
        !           267:                } ENDTRY
        !           268:                regs.s = olds;
        !           269:        } else {
        !           270: #ifndef WINUAE_FOR_HATARI
        !           271:                v = get_long (addr);
        !           272: #else
        !           273:                v = STMemory_ReadLong ( addr );
        !           274: #endif
        !           275:        }
        !           276:        return v;
        !           277: }
        !           278: uae_u32 get_iword_debug (uaecptr addr)
        !           279: {
        !           280:        if (debug_mmu_mode) {
        !           281:                return get_word_debug (addr);
        !           282:        } else {
        !           283: #ifndef WINUAE_FOR_HATARI
        !           284:                if (valid_address (addr, 2))
        !           285:                        return get_word (addr);
        !           286:                return 0xffff;
        !           287: #else
        !           288:                return get_word_debug (addr);
        !           289: #endif
        !           290:        }
        !           291: }
        !           292: uae_u32 get_ilong_debug (uaecptr addr)
        !           293: {
        !           294:        if (debug_mmu_mode) {
        !           295:                return get_long_debug (addr);
        !           296:        } else {
        !           297: #ifndef WINUAE_FOR_HATARI
        !           298:                if (valid_address (addr, 4))
        !           299:                        return get_long (addr);
        !           300:                return 0xffffffff;
        !           301: #else
        !           302:                return get_long_debug (addr);
        !           303: #endif
        !           304:        }
        !           305: }
        !           306: 
        !           307: #ifndef WINUAE_FOR_HATARI
        !           308: int safe_addr (uaecptr addr, int size)
        !           309: {
        !           310:        if (debug_mmu_mode) {
        !           311:                flagtype olds = regs.s;
        !           312:                regs.s = (debug_mmu_mode & 4) != 0;
        !           313:                TRY(p) {
        !           314:                        if (currprefs.mmu_model >= 68040)
        !           315:                                addr = mmu_translate (addr, regs.s != 0, (debug_mmu_mode & 1), false);
        !           316:                        else
        !           317:                                addr = mmu030_translate (addr, regs.s != 0, (debug_mmu_mode & 1), false);
        !           318:                } CATCH(p) {
        !           319:                        return 0;
        !           320:                } ENDTRY
        !           321:                regs.s = olds;
        !           322:        }
        !           323:        addrbank *ab = &get_mem_bank (addr);
        !           324:        if (!ab)
        !           325:                return 0;
        !           326:        if (ab->flags & ABFLAG_SAFE)
        !           327:                return 1;
        !           328:        if (!ab->check (addr, size))
        !           329:                return 0;
        !           330:        if (ab->flags & (ABFLAG_RAM | ABFLAG_ROM | ABFLAG_ROMIN | ABFLAG_SAFE))
        !           331:                return 1;
        !           332:        return 0;
        !           333: }
        !           334: 
        !           335: static bool iscancel (int counter)
        !           336: {
        !           337:        static int cnt;
        !           338: 
        !           339:        cnt++;
        !           340:        if (cnt < counter)
        !           341:                return false;
        !           342:        cnt = 0;
        !           343:        if (!console_isch ())
        !           344:                return false;
        !           345:        console_getch ();
        !           346:        return true;
        !           347: }
        !           348: 
        !           349: static bool isoperator(TCHAR **cp)
        !           350: {
        !           351:        TCHAR c = **cp;
        !           352:        return c == '+' || c == '-' || c == '/' || c == '*' || c == '(' || c == ')';
        !           353: }
        !           354: 
        !           355: static void ignore_ws (TCHAR **c)
        !           356: {
        !           357:        while (**c && _istspace(**c))
        !           358:                (*c)++;
        !           359: }
        !           360: static TCHAR peekchar (TCHAR **c)
        !           361: {
        !           362:        return **c;
        !           363: }
        !           364: static TCHAR readchar (TCHAR **c)
        !           365: {
        !           366:        TCHAR cc = **c;
        !           367:        (*c)++;
        !           368:        return cc;
        !           369: }
        !           370: static TCHAR next_char (TCHAR **c)
        !           371: {
        !           372:        ignore_ws (c);
        !           373:        return *(*c)++;
        !           374: }
        !           375: static TCHAR peek_next_char (TCHAR **c)
        !           376: {
        !           377:        TCHAR *pc = *c;
        !           378:        return pc[1];
        !           379: }
        !           380: static int more_params (TCHAR **c)
        !           381: {
        !           382:        ignore_ws (c);
        !           383:        return (**c) != 0;
        !           384: }
        !           385: 
        !           386: static uae_u32 readint (TCHAR **c);
        !           387: static uae_u32 readbin (TCHAR **c);
        !           388: static uae_u32 readhex (TCHAR **c);
        !           389: 
        !           390: static int readregx (TCHAR **c, uae_u32 *valp)
        !           391: {
        !           392:        int i;
        !           393:        uae_u32 addr;
        !           394:        TCHAR *p = *c;
        !           395:        TCHAR tmp[10];
        !           396:        int extra = 0;
        !           397: 
        !           398:        addr = 0;
        !           399:        i = 0;
        !           400:        while (p[i]) {
        !           401:                tmp[i] = _totupper (p[i]);
        !           402:                if (i >= sizeof (tmp) / sizeof (TCHAR) - 1)
        !           403:                        break;
        !           404:                i++;
        !           405:        }
        !           406:        tmp[i] = 0;
        !           407:        if (_totupper (tmp[0]) == 'R') {
        !           408:                memmove (tmp, tmp + 1, sizeof (tmp) - sizeof (TCHAR));
        !           409:                extra = 1;
        !           410:        }
        !           411:        if (!_tcsncmp (tmp, _T("USP"), 3)) {
        !           412:                addr = regs.usp;
        !           413:                (*c) += 3;
        !           414:        } else if (!_tcsncmp (tmp, _T("VBR"), 3)) {
        !           415:                addr = regs.vbr;
        !           416:                (*c) += 3;
        !           417:        } else if (!_tcsncmp (tmp, _T("MSP"), 3)) {
        !           418:                addr = regs.msp;
        !           419:                (*c) += 3;
        !           420:        } else if (!_tcsncmp (tmp, _T("ISP"), 3)) {
        !           421:                addr = regs.isp;
        !           422:                (*c) += 3;
        !           423:        } else if (!_tcsncmp (tmp, _T("PC"), 2)) {
        !           424:                addr = regs.pc;
        !           425:                (*c) += 2;
        !           426:        } else if (tmp[0] == 'A' || tmp[0] == 'D') {
        !           427:                int reg = 0;
        !           428:                if (tmp[0] == 'A')
        !           429:                        reg += 8;
        !           430:                reg += tmp[1] - '0';
        !           431:                if (reg < 0 || reg > 15)
        !           432:                        return 0;
        !           433:                addr = regs.regs[reg];
        !           434:                (*c) += 2;
        !           435:        } else {
        !           436:                return 0;
        !           437:        }
        !           438:        *valp = addr;
        !           439:        (*c) += extra;
        !           440:        return 1;
        !           441: }
        !           442: 
        !           443: static bool readbinx (TCHAR **c, uae_u32 *valp)
        !           444: {
        !           445:        uae_u32 val = 0;
        !           446:        bool first = true;
        !           447: 
        !           448:        ignore_ws (c);
        !           449:        for (;;) {
        !           450:                TCHAR nc = **c;
        !           451:                if (nc != '1' && nc != '0') {
        !           452:                        if (first)
        !           453:                                return false;
        !           454:                        break;
        !           455:                }
        !           456:                first = false;
        !           457:                (*c)++;
        !           458:                val <<= 1;
        !           459:                if (nc == '1')
        !           460:                        val |= 1;
        !           461:        }
        !           462:        *valp = val;
        !           463:        return true;
        !           464: }
        !           465: 
        !           466: static bool readhexx (TCHAR **c, uae_u32 *valp)
        !           467: {
        !           468:        uae_u32 val = 0;
        !           469:        TCHAR nc;
        !           470: 
        !           471:        ignore_ws (c);
        !           472:        if (!isxdigit (peekchar (c)))
        !           473:                return false;
        !           474:        while (isxdigit (nc = **c)) {
        !           475:                (*c)++;
        !           476:                val *= 16;
        !           477:                nc = _totupper (nc);
        !           478:                if (isdigit (nc)) {
        !           479:                        val += nc - '0';
        !           480:                } else {
        !           481:                        val += nc - 'A' + 10;
        !           482:                }
        !           483:        }
        !           484:        *valp = val;
        !           485:        return true;
        !           486: }
        !           487: 
        !           488: static bool readintx (TCHAR **c, uae_u32 *valp)
        !           489: {
        !           490:        uae_u32 val = 0;
        !           491:        TCHAR nc;
        !           492:        int negative = 0;
        !           493: 
        !           494:        ignore_ws (c);
        !           495:        if (**c == '-')
        !           496:                negative = 1, (*c)++;
        !           497:        if (!isdigit (peekchar (c)))
        !           498:                return false;
        !           499:        while (isdigit (nc = **c)) {
        !           500:                (*c)++;
        !           501:                val *= 10;
        !           502:                val += nc - '0';
        !           503:        }
        !           504:        *valp = val * (negative ? -1 : 1);
        !           505:        return true;
        !           506: }
        !           507: 
        !           508: 
        !           509: static int checkvaltype2 (TCHAR **c, uae_u32 *val, TCHAR def)
        !           510: {
        !           511:        TCHAR nc;
        !           512: 
        !           513:        ignore_ws (c);
        !           514:        nc = _totupper (**c);
        !           515:        if (nc == '!') {
        !           516:                (*c)++;
        !           517:                return readintx (c, val) ? 1 : 0;
        !           518:        }
        !           519:        if (nc == '$') {
        !           520:                (*c)++;
        !           521:                return  readhexx (c, val) ? 1 : 0;
        !           522:        }
        !           523:        if (nc == '0' && _totupper ((*c)[1]) == 'X') {
        !           524:                (*c)+= 2;
        !           525:                return  readhexx (c, val) ? 1 : 0;
        !           526:        }
        !           527:        if (nc == '%') {
        !           528:                (*c)++;
        !           529:                return readbinx (c, val) ? 1: 0;
        !           530:        }
        !           531:        if (nc >= 'A' && nc <= 'Z' && nc != 'A' && nc != 'D') {
        !           532:                if (readregx (c, val))
        !           533:                        return 1;
        !           534:        }
        !           535:        if (def == '!') {
        !           536:                return readintx (c, val) ? -1 : 0;
        !           537:                return -1;
        !           538:        } else if (def == '$') {
        !           539:                return readhexx (c, val) ? -1 : 0;
        !           540:        } else if (def == '%') {
        !           541:                return readbinx (c, val) ? -1 : 0;
        !           542:        }
        !           543:        return 0;
        !           544: }
        !           545: 
        !           546: static int readsize (int val, TCHAR **c)
        !           547: {
        !           548:        TCHAR cc = _totupper (readchar(c));
        !           549:        if (cc == 'B')
        !           550:                return 1;
        !           551:        if (cc == 'W')
        !           552:                return 2;
        !           553:        if (cc == '3')
        !           554:                return 3;
        !           555:        if (cc == 'L')
        !           556:                return 4;
        !           557:        return 0;
        !           558: }
        !           559: 
        !           560: static int checkvaltype (TCHAR **cp, uae_u32 *val, int *size, TCHAR def)
        !           561: {
        !           562:        TCHAR form[256], *p;
        !           563:        bool gotop = false;
        !           564:        double out;
        !           565: 
        !           566:        form[0] = 0;
        !           567:        *size = 0;
        !           568:        p = form;
        !           569:        for (;;) {
        !           570:                uae_u32 v;
        !           571:                if (!checkvaltype2 (cp, &v, def))
        !           572:                        return 0;
        !           573:                *val = v;
        !           574:                // stupid but works!
        !           575:                _stprintf(p, _T("%u"), v);
        !           576:                p += _tcslen (p);
        !           577:                if (peekchar (cp) == '.') {
        !           578:                        readchar (cp);
        !           579:                        *size = readsize (v, cp);
        !           580:                }
        !           581:                if (!isoperator (cp))
        !           582:                        break;
        !           583:                gotop = true;
        !           584:                *p++= readchar (cp);
        !           585:                *p = 0;
        !           586:        }
        !           587:        if (!gotop) {
        !           588:                if (*size == 0) {
        !           589:                        uae_s32 v = (uae_s32)(*val);
        !           590:                        if (v > 255 || v < -127) {
        !           591:                                *size = 2;
        !           592:                        } else if (v > 65535 || v < -32767) {
        !           593:                                *size = 4;
        !           594:                        } else {
        !           595:                                *size = 1;
        !           596:                        }
        !           597:                }
        !           598:                return 1;
        !           599:        }
        !           600:        if (calc (form, &out)) {
        !           601:                *val = (uae_u32)out;
        !           602:                if (*size == 0) {
        !           603:                        uae_s32 v = (uae_s32)(*val);
        !           604:                        if (v > 255 || v < -127) {
        !           605:                                *size = 2;
        !           606:                        } else if (v > 65535 || v < -32767) {
        !           607:                                *size = 4;
        !           608:                        } else {
        !           609:                                *size = 1;
        !           610:                        }
        !           611:                }
        !           612:                return 1;
        !           613:        }
        !           614:        return 0;
        !           615: }
        !           616: 
        !           617: 
        !           618: static uae_u32 readnum (TCHAR **c, int *size, TCHAR def)
        !           619: {
        !           620:        uae_u32 val;
        !           621:        if (checkvaltype (c, &val, size, def))
        !           622:                return val;
        !           623:        return 0;
        !           624: }
        !           625: 
        !           626: static uae_u32 readint (TCHAR **c)
        !           627: {
        !           628:        int size;
        !           629:        return readnum (c, &size, '!');
        !           630: }
        !           631: static uae_u32 readhex (TCHAR **c)
        !           632: {
        !           633:        int size;
        !           634:        return readnum (c, &size, '$');
        !           635: }
        !           636: static uae_u32 readbin (TCHAR **c)
        !           637: {
        !           638:        int size;
        !           639:        return readnum (c, &size, '%');
        !           640: }
        !           641: static uae_u32 readint (TCHAR **c, int *size)
        !           642: {
        !           643:        return readnum (c, size, '!');
        !           644: }
        !           645: static uae_u32 readhex (TCHAR **c, int *size)
        !           646: {
        !           647:        return readnum (c, size, '$');
        !           648: }
        !           649: 
        !           650: static int next_string (TCHAR **c, TCHAR *out, int max, int forceupper)
        !           651: {
        !           652:        TCHAR *p = out;
        !           653:        int startmarker = 0;
        !           654: 
        !           655:        if (**c == '\"') {
        !           656:                startmarker = 1;
        !           657:                (*c)++;
        !           658:        }
        !           659:        *p = 0;
        !           660:        while (**c != 0) {
        !           661:                if (**c == '\"' && startmarker)
        !           662:                        break;
        !           663:                if (**c == 32 && !startmarker) {
        !           664:                        ignore_ws (c);
        !           665:                        break;
        !           666:                }
        !           667:                *p = next_char (c);
        !           668:                if (forceupper)
        !           669:                        *p = _totupper(*p);
        !           670:                *++p = 0;
        !           671:                max--;
        !           672:                if (max <= 1)
        !           673:                        break;
        !           674:        }
        !           675:        return _tcslen (out);
        !           676: }
        !           677: 
        !           678: static void converter (TCHAR **c)
        !           679: {
        !           680:        uae_u32 v = readint (c);
        !           681:        TCHAR s[100];
        !           682:        TCHAR *p = s;
        !           683:        int i;
        !           684: 
        !           685:        for (i = 0; i < 32; i++)
        !           686:                s[i] = (v & (1 << (31 - i))) ? '1' : '0';
        !           687:        s[i] = 0;
        !           688:        console_out_f (_T("0x%08X = %%%s = %u = %d\n"), v, s, v, (uae_s32)v);
        !           689: }
        !           690: 
        !           691: int notinrom (void)
        !           692: {
        !           693:        uaecptr pc = munge24 (m68k_getpc ());
        !           694:        if (pc < 0x00e00000 || pc > 0x00ffffff)
        !           695:                return 1;
        !           696:        return 0;
        !           697: }
        !           698: 
        !           699: static uae_u32 lastaddr (void)
        !           700: {
        !           701:        if (currprefs.z3fastmem2_size)
        !           702:                return z3fastmem2_bank.start + currprefs.z3fastmem2_size;
        !           703:        if (currprefs.z3fastmem_size)
        !           704:                return z3fastmem_bank.start + currprefs.z3fastmem_size;
        !           705:        if (currprefs.z3chipmem_size)
        !           706:                return z3chipmem_bank.start + currprefs.z3chipmem_size;
        !           707:        if (currprefs.mbresmem_high_size)
        !           708:                return a3000hmem_bank.start + currprefs.mbresmem_high_size;
        !           709:        if (currprefs.mbresmem_low_size)
        !           710:                return a3000lmem_bank.start + currprefs.mbresmem_low_size;
        !           711:        if (currprefs.bogomem_size)
        !           712:                return bogomem_bank.start + currprefs.bogomem_size;
        !           713:        if (currprefs.fastmem_size)
        !           714:                return fastmem_bank.start + currprefs.fastmem_size;
        !           715:        return currprefs.chipmem_size;
        !           716: }
        !           717: 
        !           718: static uaecptr nextaddr2 (uaecptr addr, int *next)
        !           719: {
        !           720:        uaecptr prev, prevx;
        !           721:        int size, sizex;
        !           722: 
        !           723:        if (addr >= lastaddr ()) {
        !           724:                *next = -1;
        !           725:                return 0xffffffff;
        !           726:        }
        !           727:        prev = currprefs.z3autoconfig_start + currprefs.z3fastmem_size;
        !           728:        size = currprefs.z3fastmem2_size;
        !           729: 
        !           730:        if (currprefs.z3fastmem_size) {
        !           731:                prevx = prev;
        !           732:                sizex = size;
        !           733:                size = currprefs.z3fastmem_size;
        !           734:                prev = z3fastmem_bank.start;
        !           735:                if (addr == prev + size) {
        !           736:                        *next = prevx + sizex;
        !           737:                        return prevx;
        !           738:                }
        !           739:        }
        !           740:        if (currprefs.z3chipmem_size) {
        !           741:                prevx = prev;
        !           742:                sizex = size;
        !           743:                size = currprefs.z3chipmem_size;
        !           744:                prev = z3chipmem_bank.start;
        !           745:                if (addr == prev + size) {
        !           746:                        *next = prevx + sizex;
        !           747:                        return prevx;
        !           748:                }
        !           749:        }
        !           750:        if (currprefs.mbresmem_high_size) {
        !           751:                sizex = size;
        !           752:                prevx = prev;
        !           753:                size = currprefs.mbresmem_high_size;
        !           754:                prev = a3000hmem_bank.start;
        !           755:                if (addr == prev + size) {
        !           756:                        *next = prevx + sizex;
        !           757:                        return prevx;
        !           758:                }
        !           759:        }
        !           760:        if (currprefs.mbresmem_low_size) {
        !           761:                prevx = prev;
        !           762:                sizex = size;
        !           763:                size = currprefs.mbresmem_low_size;
        !           764:                prev = a3000lmem_bank.start;
        !           765:                if (addr == prev + size) {
        !           766:                        *next = prevx + sizex;
        !           767:                        return prevx;
        !           768:                }
        !           769:        }
        !           770:        if (currprefs.bogomem_size) {
        !           771:                sizex = size;
        !           772:                prevx = prev;
        !           773:                size = currprefs.bogomem_size;
        !           774:                prev = bogomem_bank.start;
        !           775:                if (addr == prev + size) {
        !           776:                        *next = prevx + sizex;
        !           777:                        return prevx;
        !           778:                }
        !           779:        }
        !           780:        if (currprefs.fastmem_size) {
        !           781:                sizex = size;
        !           782:                prevx = prev;
        !           783:                size = currprefs.fastmem_size;
        !           784:                prev = fastmem_bank.start;
        !           785:                if (addr == prev + size) {
        !           786:                        *next = prevx + sizex;
        !           787:                        return prevx;
        !           788:                }
        !           789:        }
        !           790:        sizex = size;
        !           791:        prevx = prev;
        !           792:        size = currprefs.chipmem_size;
        !           793:        if (addr == size) {
        !           794:                *next = prevx + sizex;
        !           795:                return prevx;
        !           796:        }
        !           797:        if (addr == 1)
        !           798:                *next = size;
        !           799:        return addr;
        !           800: }
        !           801: 
        !           802: static uaecptr nextaddr (uaecptr addr, uaecptr last, uaecptr *end)
        !           803: {
        !           804:        static uaecptr old;
        !           805:        uaecptr paddr = addr;
        !           806:        int next = last;
        !           807:        if (last && 0) {
        !           808:                if (addr >= last)
        !           809:                        return 0xffffffff;
        !           810:                return addr + 1;
        !           811:        }
        !           812:        if (addr == 0xffffffff) {
        !           813:                if (end)
        !           814:                        *end = currprefs.chipmem_size;
        !           815:                return 0;
        !           816:        }
        !           817:        if (end)
        !           818:                next = *end;
        !           819:        addr = nextaddr2 (addr + 1, &next);
        !           820:        if (end)
        !           821:                *end = next;
        !           822:        if (old != next) {
        !           823:                if (addr != 0xffffffff)
        !           824:                        console_out_f (_T("Scanning.. %08x - %08x (%s)\n"), addr & 0xffffff00, next, get_mem_bank (addr).name);
        !           825:                old = next;
        !           826:        }
        !           827: #if 0
        !           828:        if (next && addr != 0xffffffff) {
        !           829:                uaecptr xa = addr;
        !           830:                if (xa == 1)
        !           831:                        xa = 0;
        !           832:                console_out_f ("%08X -> %08X (%08X)...\n", xa, xa + next - 1, next);
        !           833:        }
        !           834: #endif
        !           835:        return addr;
        !           836: }
        !           837: 
        !           838: uaecptr dumpmem2 (uaecptr addr, TCHAR *out, int osize)
        !           839: {
        !           840:        int i, cols = 8;
        !           841:        int nonsafe = 0;
        !           842: 
        !           843:        if (osize <= (9 + cols * 5 + 1 + 2 * cols))
        !           844:                return addr;
        !           845:        _stprintf (out, _T("%08X "), addr);
        !           846:        for (i = 0; i < cols; i++) {
        !           847:                uae_u8 b1, b2;
        !           848:                b1 = b2 = 0;
        !           849:                if (safe_addr (addr, 1)) {
        !           850:                        b1 = get_byte_debug (addr + 0);
        !           851:                        b2 = get_byte_debug (addr + 1);
        !           852:                        _stprintf (out + 9 + i * 5, _T("%02X%02X "), b1, b2);
        !           853:                        out[9 + cols * 5 + 1 + i * 2 + 0] = b1 >= 32 && b1 < 127 ? b1 : '.';
        !           854:                        out[9 + cols * 5 + 1 + i * 2 + 1] = b2 >= 32 && b2 < 127 ? b2 : '.';
        !           855:                } else {
        !           856:                        nonsafe++;
        !           857:                        _tcscpy (out + 9 + i * 5, _T("**** "));
        !           858:                        out[9 + cols * 5 + 1 + i * 2 + 0] = '*';
        !           859:                        out[9 + cols * 5 + 1 + i * 2 + 1] = '*';
        !           860:                }
        !           861:                addr += 2;
        !           862:        }
        !           863:        out[9 + cols * 5] = ' ';
        !           864:        out[9 + cols * 5 + 1 + 2 * cols] = 0;
        !           865:        if (nonsafe == cols) {
        !           866:                addrbank *ab = &get_mem_bank (addr);
        !           867:                if (ab->name)
        !           868:                        memcpy (out + (9 + 4 + 1) * sizeof (TCHAR), ab->name, _tcslen (ab->name) * sizeof (TCHAR));
        !           869:        }
        !           870:        return addr;
        !           871: }
        !           872: 
        !           873: static void dumpmem (uaecptr addr, uaecptr *nxmem, int lines)
        !           874: {
        !           875:        TCHAR line[MAX_LINEWIDTH + 1];
        !           876:        for (;lines--;) {
        !           877:                addr = dumpmem2 (addr, line, sizeof(line));
        !           878:                debug_out (_T("%s"), line);
        !           879:                if (!debug_out (_T("\n")))
        !           880:                        break;
        !           881:        }
        !           882:        *nxmem = addr;
        !           883: }
        !           884: 
        !           885: static void dump_custom_regs (int aga)
        !           886: {
        !           887:        int len, i, j, end;
        !           888:        uae_u8 *p1, *p2, *p3, *p4;
        !           889: 
        !           890:        if (aga) {
        !           891:                dump_aga_custom();
        !           892:                return;
        !           893:        }
        !           894: 
        !           895:        p1 = p2 = save_custom (&len, 0, 1);
        !           896:        p1 += 4; // skip chipset type
        !           897:        for (i = 0; i < 4; i++) {
        !           898:                p4 = p1 + 0xa0 + i * 16;
        !           899:                p3 = save_audio (i, &len, 0);
        !           900:                p4[0] = p3[12];
        !           901:                p4[1] = p3[13];
        !           902:                p4[2] = p3[14];
        !           903:                p4[3] = p3[15];
        !           904:                p4[4] = p3[4];
        !           905:                p4[5] = p3[5];
        !           906:                p4[6] = p3[8];
        !           907:                p4[7] = p3[9];
        !           908:                p4[8] = 0;
        !           909:                p4[9] = p3[1];
        !           910:                p4[10] = p3[10];
        !           911:                p4[11] = p3[11];
        !           912:                free (p3);
        !           913:        }
        !           914:        end = 0;
        !           915:        while (custd[end].name)
        !           916:                end++;
        !           917:        end++;
        !           918:        end /= 2;
        !           919:        for (i = 0; i < end; i++) {
        !           920:                uae_u16 v1, v2;
        !           921:                int addr1, addr2;
        !           922:                j = end + i;
        !           923:                addr1 = custd[i].adr & 0x1ff;
        !           924:                addr2 = custd[j].adr & 0x1ff;
        !           925:                v1 = (p1[addr1 + 0] << 8) | p1[addr1 + 1];
        !           926:                v2 = (p1[addr2 + 0] << 8) | p1[addr2 + 1];
        !           927:                console_out_f (_T("%03X %s\t%04X\t%03X %s\t%04X\n"),
        !           928:                        addr1, custd[i].name, v1,
        !           929:                        addr2, custd[j].name, v2);
        !           930:        }
        !           931:        free (p2);
        !           932: }
        !           933: 
        !           934: static void dump_vectors (uaecptr addr)
        !           935: {
        !           936:        int i = 0, j = 0;
        !           937: 
        !           938:        if (addr == 0xffffffff)
        !           939:                addr = regs.vbr;
        !           940: 
        !           941:        while (int_labels[i].name || trap_labels[j].name) {
        !           942:                if (int_labels[i].name) {
        !           943:                        console_out_f (_T("$%08X %02d: %12s $%08X  "), int_labels[i].adr + addr, int_labels[i].adr / 4,
        !           944:                                int_labels[i].name, get_long_debug (int_labels[i].adr + addr));
        !           945:                        i++;
        !           946:                }
        !           947:                if (trap_labels[j].name) {
        !           948:                        console_out_f (_T("$%08X %02d: %12s $%08X"), trap_labels[j].adr + addr, trap_labels[j].adr / 4,
        !           949:                                trap_labels[j].name, get_long_debug (trap_labels[j].adr + addr));
        !           950:                        j++;
        !           951:                }
        !           952:                console_out (_T("\n"));
        !           953:        }
        !           954: }
        !           955: 
        !           956: static void disassemble_wait (FILE *file, unsigned long insn)
        !           957: {
        !           958:        int vp, hp, ve, he, bfd, v_mask, h_mask;
        !           959:        int doout = 0;
        !           960: 
        !           961:        vp = (insn & 0xff000000) >> 24;
        !           962:        hp = (insn & 0x00fe0000) >> 16;
        !           963:        ve = (insn & 0x00007f00) >> 8;
        !           964:        he = (insn & 0x000000fe);
        !           965:        bfd = (insn & 0x00008000) >> 15;
        !           966: 
        !           967:        /* bit15 can never be masked out*/
        !           968:        v_mask = vp & (ve | 0x80);
        !           969:        h_mask = hp & he;
        !           970:        if (v_mask > 0) {
        !           971:                doout = 1;
        !           972:                console_out (_T("vpos "));
        !           973:                if (ve != 0x7f) {
        !           974:                        console_out_f (_T("& 0x%02x "), ve);
        !           975:                }
        !           976:                console_out_f (_T(">= 0x%02x"), v_mask);
        !           977:        }
        !           978:        if (he > 0) {
        !           979:                if (v_mask > 0) {
        !           980:                        console_out (_T(" and"));
        !           981:                }
        !           982:                console_out (_T(" hpos "));
        !           983:                if (he != 0xfe) {
        !           984:                        console_out_f (_T("& 0x%02x "), he);
        !           985:                }
        !           986:                console_out_f (_T(">= 0x%02x"), h_mask);
        !           987:        } else {
        !           988:                if (doout)
        !           989:                        console_out (_T(", "));
        !           990:                console_out (_T(", ignore horizontal"));
        !           991:        }
        !           992: 
        !           993:        console_out_f (_T("\n                        \t;  VP %02x, VE %02x; HP %02x, HE %02x; BFD %d\n"),
        !           994:                vp, ve, hp, he, bfd);
        !           995: }
        !           996: 
        !           997: #define NR_COPPER_RECORDS 100000
        !           998: /* Record copper activity for the debugger.  */
        !           999: struct cop_rec
        !          1000: {
        !          1001:        uae_u16 w1, w2;
        !          1002:        int hpos, vpos;
        !          1003:        int bhpos, bvpos;
        !          1004:        uaecptr addr;
        !          1005: };
        !          1006: static struct cop_rec *cop_record[2];
        !          1007: static int nr_cop_records[2], curr_cop_set;
        !          1008: 
        !          1009: #define NR_DMA_REC_HPOS 256
        !          1010: #define NR_DMA_REC_VPOS 1000
        !          1011: static struct dma_rec *dma_record[2];
        !          1012: static int dma_record_toggle;
        !          1013: 
        !          1014: void record_dma_reset (void)
        !          1015: {
        !          1016:        int v, h;
        !          1017:        struct dma_rec *dr, *dr2;
        !          1018: 
        !          1019:        if (!dma_record[0])
        !          1020:                return;
        !          1021:        dma_record_toggle ^= 1;
        !          1022:        dr = dma_record[dma_record_toggle];
        !          1023:        for (v = 0; v < NR_DMA_REC_VPOS; v++) {
        !          1024:                for (h = 0; h < NR_DMA_REC_HPOS; h++) {
        !          1025:                        dr2 = &dr[v * NR_DMA_REC_HPOS + h];
        !          1026:                        memset (dr2, 0, sizeof (struct dma_rec));
        !          1027:                        dr2->reg = 0xffff;
        !          1028:                        dr2->addr = 0xffffffff;
        !          1029:                }
        !          1030:        }
        !          1031: }
        !          1032: 
        !          1033: void record_copper_reset (void)
        !          1034: {
        !          1035:        /* Start a new set of copper records.  */
        !          1036:        curr_cop_set ^= 1;
        !          1037:        nr_cop_records[curr_cop_set] = 0;
        !          1038: }
        !          1039: 
        !          1040: STATIC_INLINE uae_u32 ledcolor (uae_u32 c, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *a)
        !          1041: {
        !          1042:        uae_u32 v = rc[(c >> 16) & 0xff] | gc[(c >> 8) & 0xff] | bc[(c >> 0) & 0xff];
        !          1043:        if (a)
        !          1044:                v |= a[255 - ((c >> 24) & 0xff)];
        !          1045:        return v;
        !          1046: }
        !          1047: 
        !          1048: STATIC_INLINE void putpixel (uae_u8 *buf, int bpp, int x, xcolnr c8)
        !          1049: {
        !          1050:        if (x <= 0)
        !          1051:                return;
        !          1052: 
        !          1053:        switch (bpp) {
        !          1054:        case 1:
        !          1055:                buf[x] = (uae_u8)c8;
        !          1056:                break;
        !          1057:        case 2:
        !          1058:                {
        !          1059:                        uae_u16 *p = (uae_u16*)buf + x;
        !          1060:                        *p = (uae_u16)c8;
        !          1061:                        break;
        !          1062:                }
        !          1063:        case 3:
        !          1064:                /* no 24 bit yet */
        !          1065:                break;
        !          1066:        case 4:
        !          1067:                {
        !          1068:                        uae_u32 *p = (uae_u32*)buf + x;
        !          1069:                        *p = c8;
        !          1070:                        break;
        !          1071:                }
        !          1072:        }
        !          1073: }
        !          1074: 
        !          1075: #define lc(x) ledcolor (x, xredcolors, xgreencolors, xbluecolors, NULL)
        !          1076: 
        !          1077: static uae_u32 intlevc[] = { 0x000000, 0x444444, 0x008800, 0xffff00, 0x000088, 0x880000, 0xff0000, 0xffffff };
        !          1078: 
        !          1079: void debug_draw_cycles (uae_u8 *buf, int bpp, int line, int width, int height, uae_u32 *xredcolors, uae_u32 *xgreencolors, uae_u32 *xbluescolors)
        !          1080: {
        !          1081:        int y, x, xx, dx, xplus, yplus;
        !          1082:        struct dma_rec *dr;
        !          1083:        int t;
        !          1084:        uae_u32 cc[DMARECORD_MAX];
        !          1085: 
        !          1086:        if (debug_dma >= 4)
        !          1087:                yplus = 2;
        !          1088:        else
        !          1089:                yplus = 1;
        !          1090:        if (debug_dma >= 3)
        !          1091:                xplus = 2;
        !          1092:        else
        !          1093:                xplus = 1;
        !          1094: 
        !          1095:        t = dma_record_toggle ^ 1;
        !          1096:        y = line / yplus - 8;
        !          1097: 
        !          1098:        if (y < 0)
        !          1099:                return;
        !          1100:        if (y > maxvpos)
        !          1101:                return;
        !          1102:        if (y >= height)
        !          1103:                return;
        !          1104: 
        !          1105:        dx = width - xplus * ((maxhpos + 1) & ~1) - 16;
        !          1106: 
        !          1107:        cc[0] = lc(0x222222);
        !          1108:        cc[DMARECORD_REFRESH] = lc(0x444444);
        !          1109:        cc[DMARECORD_CPU] = lc(0x888888);
        !          1110:        cc[DMARECORD_COPPER] = lc(0xeeee00);
        !          1111:        cc[DMARECORD_AUDIO] = lc(0xff0000);
        !          1112:        cc[DMARECORD_BLITTER] = lc(0x008888);
        !          1113:        cc[DMARECORD_BLITTER_FILL] = lc(0x0088ff);
        !          1114:        cc[DMARECORD_BLITTER_LINE] = lc(0x00ff00);
        !          1115:        cc[DMARECORD_BITPLANE] = lc(0x0000ff);
        !          1116:        cc[DMARECORD_SPRITE] = lc(0xff00ff);
        !          1117:        cc[DMARECORD_DISK] = lc(0xffffff);
        !          1118: 
        !          1119:        uae_s8 intlev = 0;
        !          1120:        for (x = 0; x < maxhpos; x++) {
        !          1121:                uae_u32 c = cc[0];
        !          1122:                xx = x * xplus + dx;
        !          1123:                dr = &dma_record[t][y * NR_DMA_REC_HPOS + x];
        !          1124:                if (dr->reg != 0xffff) {
        !          1125:                        c = cc[dr->type];
        !          1126:                }
        !          1127:                if (dr->intlev > intlev)
        !          1128:                        intlev = dr->intlev;
        !          1129:                putpixel (buf, bpp, xx + 4, c);
        !          1130:                if (xplus)
        !          1131:                        putpixel (buf, bpp, xx + 4 + 1, c);
        !          1132:        }
        !          1133:        putpixel (buf, bpp, dx + 0, 0);
        !          1134:        putpixel (buf, bpp, dx + 1, lc(intlevc[intlev]));
        !          1135:        putpixel (buf, bpp, dx + 2, lc(intlevc[intlev]));
        !          1136:        putpixel (buf, bpp, dx + 3, 0);
        !          1137: }
        !          1138: 
        !          1139: #define HEATMAP_COUNT 50
        !          1140: static struct memory_heatmap *heatmap;
        !          1141: struct memory_heatmap
        !          1142: {
        !          1143:        uae_u16 cnt;
        !          1144:        uae_u16 type;
        !          1145: };
        !          1146: 
        !          1147: static void memwatch_heatmap (uaecptr addr, int rwi, int size)
        !          1148: {
        !          1149: }
        !          1150: 
        !          1151: static void record_dma_heatmap (uaecptr addr, int type)
        !          1152: {
        !          1153:        if (addr >= 0x01000000 || !heatmap)
        !          1154:                return;
        !          1155:        struct memory_heatmap *hp = &heatmap[addr / 2];
        !          1156:        hp->cnt = HEATMAP_COUNT;
        !          1157:        hp->type = type;
        !          1158: }
        !          1159: 
        !          1160: void record_dma_event (int evt, int hpos, int vpos)
        !          1161: {
        !          1162:        struct dma_rec *dr;
        !          1163: 
        !          1164:        if (!dma_record[0])
        !          1165:                return;
        !          1166:        if (hpos >= NR_DMA_REC_HPOS || vpos >= NR_DMA_REC_VPOS)
        !          1167:                return;
        !          1168:        dr = &dma_record[dma_record_toggle][vpos * NR_DMA_REC_HPOS + hpos];
        !          1169:        dr->evt |= evt;
        !          1170: }
        !          1171: 
        !          1172: struct dma_rec *record_dma (uae_u16 reg, uae_u16 dat, uae_u32 addr, int hpos, int vpos, int type)
        !          1173: {
        !          1174:        struct dma_rec *dr;
        !          1175: 
        !          1176:        if (!heatmap)
        !          1177:                heatmap = xcalloc (struct memory_heatmap, 16 * 1024 * 1024 / 2);
        !          1178:        if (!dma_record[0]) {
        !          1179:                dma_record[0] = xmalloc (struct dma_rec, NR_DMA_REC_HPOS * NR_DMA_REC_VPOS);
        !          1180:                dma_record[1] = xmalloc (struct dma_rec, NR_DMA_REC_HPOS * NR_DMA_REC_VPOS);
        !          1181:                dma_record_toggle = 0;
        !          1182:                record_dma_reset ();
        !          1183:        }
        !          1184:        if (hpos >= NR_DMA_REC_HPOS || vpos >= NR_DMA_REC_VPOS)
        !          1185:                return NULL;
        !          1186: 
        !          1187:        record_dma_heatmap (addr, type);
        !          1188: 
        !          1189:        dr = &dma_record[dma_record_toggle][vpos * NR_DMA_REC_HPOS + hpos];
        !          1190:        if (dr->reg != 0xffff) {
        !          1191:                write_log (_T("DMA conflict: v=%d h=%d OREG=%04X NREG=%04X\n"), vpos, hpos, dr->reg, reg);
        !          1192:                return dr;
        !          1193:        }
        !          1194:        dr->reg = reg;
        !          1195:        dr->dat = dat;
        !          1196:        dr->addr = addr;
        !          1197:        dr->type = type;
        !          1198:        dr->intlev = regs.intmask;
        !          1199:        return dr;
        !          1200: }
        !          1201: 
        !          1202: static void decode_dma_record (int hpos, int vpos, int toggle, bool logfile)
        !          1203: {
        !          1204:        struct dma_rec *dr;
        !          1205:        int h, i, maxh, cnt;
        !          1206:        uae_u32 cycles;
        !          1207: 
        !          1208:        if (!dma_record[0])
        !          1209:                return;
        !          1210:        dr = &dma_record[dma_record_toggle ^ toggle][vpos * NR_DMA_REC_HPOS];
        !          1211:        if (logfile)
        !          1212:                write_dlog (_T("Line: %02X %3d HPOS %02X %3d:\n"), vpos, vpos, hpos, hpos);
        !          1213:        else
        !          1214:                console_out_f (_T("Line: %02X %3d HPOS %02X %3d:\n"), vpos, vpos, hpos, hpos);
        !          1215:        h = hpos;
        !          1216:        dr += hpos;
        !          1217:        maxh = hpos + 80;
        !          1218:        if (maxh > maxhpos)
        !          1219:                maxh = maxhpos;
        !          1220:        cycles = vsync_cycles;
        !          1221:        if (toggle)
        !          1222:                cycles -= maxvpos * maxhpos * CYCLE_UNIT;
        !          1223:        cnt = 0;
        !          1224:        while (h < maxh) {
        !          1225:                int col = 9;
        !          1226:                int cols = 8;
        !          1227:                TCHAR l1[81];
        !          1228:                TCHAR l2[81];
        !          1229:                TCHAR l3[81];
        !          1230:                TCHAR l4[81];
        !          1231:                TCHAR l5[81];
        !          1232:                for (i = 0; i < cols && h < maxh; i++, h++, dr++) {
        !          1233:                        int cl = i * col, cl2;
        !          1234:                        int r = dr->reg;
        !          1235:                        bool longsize = false;
        !          1236:                        TCHAR *sr;
        !          1237: 
        !          1238:                        sr = _T("    ");
        !          1239:                        if (dr->type == DMARECORD_COPPER)
        !          1240:                                sr = _T("COP ");
        !          1241:                        else if (dr->type == DMARECORD_BLITTER)
        !          1242:                                sr = _T("BLT ");
        !          1243:                        else if (dr->type == DMARECORD_BLITTER_LINE)
        !          1244:                                sr = _T("BLL ");
        !          1245:                        else if (dr->type == DMARECORD_REFRESH)
        !          1246:                                sr = _T("RFS ");
        !          1247:                        else if (dr->type == DMARECORD_AUDIO)
        !          1248:                                sr = _T("AUD ");
        !          1249:                        else if (dr->type == DMARECORD_DISK)
        !          1250:                                sr = _T("DSK ");
        !          1251:                        else if (dr->type == DMARECORD_SPRITE)
        !          1252:                                sr = _T("SPR ");
        !          1253:                        _stprintf (l1 + cl, _T("[%02X %3d]"), h, h);
        !          1254:                        _tcscpy (l4 + cl, _T("        "));
        !          1255:                        if (r != 0xffff) {
        !          1256:                                if (r & 0x1000) {
        !          1257:                                        if ((r & 0x0100) == 0x0000)
        !          1258:                                                _tcscpy (l2 + cl, _T("  CPU-R  "));
        !          1259:                                        else if ((r & 0x0100) == 0x0100)
        !          1260:                                                _tcscpy (l2 + cl, _T("  CPU-W  "));
        !          1261:                                        if ((r & 0xff) == 4) {
        !          1262:                                                l2[cl + 7] = 'L';
        !          1263:                                                longsize = true;
        !          1264:                                        }
        !          1265:                                        if ((r & 0xff) == 2)
        !          1266:                                                l2[cl + 7] = 'W';
        !          1267:                                        if ((r & 0xff) == 1)
        !          1268:                                                l2[cl + 7] = 'B';
        !          1269:                                } else {
        !          1270:                                        _stprintf (l2 + cl, _T("%4s %03X"), sr, r);
        !          1271:                                }
        !          1272:                                _stprintf (l3 + cl, longsize ? _T("%08X") : _T("    %04X"), dr->dat);
        !          1273:                                if (dr->addr != 0xffffffff)
        !          1274:                                        _stprintf (l4 + cl, _T("%08X"), dr->addr & 0x00ffffff);
        !          1275:                        } else {
        !          1276:                                _tcscpy (l2 + cl, _T("        "));
        !          1277:                                _tcscpy (l3 + cl, _T("        "));
        !          1278:                        }
        !          1279:                        cl2 = cl;
        !          1280:                        if (dr->evt & DMA_EVENT_BLITNASTY)
        !          1281:                                l3[cl2++] = 'N';
        !          1282:                        if (dr->evt & DMA_EVENT_BLITSTARTFINISH)
        !          1283:                                l3[cl2++] = 'B';
        !          1284:                        if (dr->evt & DMA_EVENT_BLITIRQ)
        !          1285:                                l3[cl2++] = 'b';
        !          1286:                        if (dr->evt & DMA_EVENT_BPLFETCHUPDATE)
        !          1287:                                l3[cl2++] = 'p';
        !          1288:                        if (dr->evt & DMA_EVENT_COPPERWAKE)
        !          1289:                                l3[cl2++] = 'W';
        !          1290:                        if (dr->evt & DMA_EVENT_COPPERWANTED)
        !          1291:                                l3[cl2++] = 'c';
        !          1292:                        if (dr->evt & DMA_EVENT_CPUIRQ)
        !          1293:                                l3[cl2++] = 'I';
        !          1294:                        if (dr->evt & DMA_EVENT_INTREQ)
        !          1295:                                l3[cl2++] = 'i';
        !          1296:                        _stprintf (l5 + cl, _T("%08X"), cycles + (vpos * maxhpos + (hpos + cnt)) * CYCLE_UNIT);
        !          1297:                        if (i < cols - 1 && h < maxh - 1) {
        !          1298:                                l1[cl + col - 1] = 32;
        !          1299:                                l2[cl + col - 1] = 32;
        !          1300:                                l3[cl + col - 1] = 32;
        !          1301:                                l4[cl + col - 1] = 32;
        !          1302:                                l5[cl + col - 1] = 32;
        !          1303:                        }
        !          1304:                        cnt++;
        !          1305:                }
        !          1306:                if (logfile) {
        !          1307:                        write_dlog (_T("%s\n"), l1);
        !          1308:                        write_dlog (_T("%s\n"), l2);
        !          1309:                        write_dlog (_T("%s\n"), l3);
        !          1310:                        write_dlog (_T("%s\n"), l4);
        !          1311:                        write_dlog (_T("%s\n"), l5);
        !          1312:                        write_dlog (_T("\n"));
        !          1313:                } else {
        !          1314:                        console_out_f (_T("%s\n"), l1);
        !          1315:                        console_out_f (_T("%s\n"), l2);
        !          1316:                        console_out_f (_T("%s\n"), l3);
        !          1317:                        console_out_f (_T("%s\n"), l4);
        !          1318:                        console_out_f (_T("%s\n"), l5);
        !          1319:                        console_out_f (_T("\n"));
        !          1320:                }
        !          1321:        }
        !          1322: }
        !          1323: void log_dma_record (void)
        !          1324: {
        !          1325:        if (!input_record && !input_play)
        !          1326:                return;
        !          1327:        if (!debug_dma)
        !          1328:                debug_dma = 1;
        !          1329:        decode_dma_record (0, 0, 0, true);
        !          1330: }
        !          1331: 
        !          1332: static void init_record_copper(void)
        !          1333: {
        !          1334:        if (!cop_record[0]) {
        !          1335:                cop_record[0] = xmalloc(struct cop_rec, NR_COPPER_RECORDS);
        !          1336:                cop_record[1] = xmalloc(struct cop_rec, NR_COPPER_RECORDS);
        !          1337:        }
        !          1338: }
        !          1339: 
        !          1340: void record_copper_blitwait (uaecptr addr, int hpos, int vpos)
        !          1341: {
        !          1342:        int t = nr_cop_records[curr_cop_set];
        !          1343:        init_record_copper();
        !          1344:        cop_record[curr_cop_set][t].bhpos = hpos;
        !          1345:        cop_record[curr_cop_set][t].bvpos = vpos;
        !          1346: }
        !          1347: 
        !          1348: void record_copper (uaecptr addr, uae_u16 word1, uae_u16 word2, int hpos, int vpos)
        !          1349: {
        !          1350:        int t = nr_cop_records[curr_cop_set];
        !          1351:        init_record_copper();
        !          1352:        if (t < NR_COPPER_RECORDS) {
        !          1353:                cop_record[curr_cop_set][t].addr = addr;
        !          1354:                cop_record[curr_cop_set][t].w1 = word1;
        !          1355:                cop_record[curr_cop_set][t].w2 = word2;
        !          1356:                cop_record[curr_cop_set][t].hpos = hpos;
        !          1357:                cop_record[curr_cop_set][t].vpos = vpos;
        !          1358:                cop_record[curr_cop_set][t].bvpos = -1;
        !          1359:                nr_cop_records[curr_cop_set] = t + 1;
        !          1360:        }
        !          1361:        if (debug_copper & 2) { /* trace */
        !          1362:                debug_copper &= ~2;
        !          1363:                activate_debugger ();
        !          1364:        }
        !          1365:        if ((debug_copper & 4) && addr >= debug_copper_pc && addr <= debug_copper_pc + 3) {
        !          1366:                debug_copper &= ~4;
        !          1367:                activate_debugger ();
        !          1368:        }
        !          1369: }
        !          1370: 
        !          1371: static struct cop_rec *find_copper_records (uaecptr addr)
        !          1372: {
        !          1373:        int s = curr_cop_set ^ 1;
        !          1374:        int t = nr_cop_records[s];
        !          1375:        int i;
        !          1376:        for (i = 0; i < t; i++) {
        !          1377:                if (cop_record[s][i].addr == addr)
        !          1378:                        return &cop_record[s][i];
        !          1379:        }
        !          1380:        return 0;
        !          1381: }
        !          1382: 
        !          1383: /* simple decode copper by Mark Cox */
        !          1384: static void decode_copper_insn (FILE* file, uae_u16 mword1, uae_u16 mword2, unsigned long addr)
        !          1385: {
        !          1386:        struct cop_rec *cr = NULL;
        !          1387:        uae_u32 insn_type, insn;
        !          1388:        TCHAR here = ' ';
        !          1389:        TCHAR record[] = _T("          ");
        !          1390: 
        !          1391:        if ((cr = find_copper_records (addr))) {
        !          1392:                _stprintf (record, _T(" [%03x %03x]"), cr->vpos, cr->hpos);
        !          1393:                insn = (cr->w1 << 16) | cr->w2;
        !          1394:        } else {
        !          1395:                insn = (mword1 << 16) | mword2;
        !          1396:        }
        !          1397: 
        !          1398:        insn_type = insn & 0x00010001;
        !          1399: 
        !          1400:        if (get_copper_address (-1) >= addr && get_copper_address(-1) <= addr + 3)
        !          1401:                here = '*';
        !          1402: 
        !          1403:        console_out_f (_T("%c%08x: %04x %04x%s\t;%c "), here, addr, insn >> 16, insn & 0xFFFF, record, insn != ((mword1 << 16) | mword2) ? '!' : ' ');
        !          1404: 
        !          1405:        switch (insn_type) {
        !          1406:        case 0x00010000: /* WAIT insn */
        !          1407:                console_out (_T("Wait for "));
        !          1408:                disassemble_wait (file, insn);
        !          1409: 
        !          1410:                if (insn == 0xfffffffe)
        !          1411:                        console_out (_T("                           \t;  End of Copperlist\n"));
        !          1412: 
        !          1413:                break;
        !          1414: 
        !          1415:        case 0x00010001: /* SKIP insn */
        !          1416:                console_out (_T("Skip if "));
        !          1417:                disassemble_wait (file, insn);
        !          1418:                break;
        !          1419: 
        !          1420:        case 0x00000000:
        !          1421:        case 0x00000001: /* MOVE insn */
        !          1422:                {
        !          1423:                        int addr = (insn >> 16) & 0x1fe;
        !          1424:                        int i = 0;
        !          1425:                        while (custd[i].name) {
        !          1426:                                if (custd[i].adr == addr + 0xdff000)
        !          1427:                                        break;
        !          1428:                                i++;
        !          1429:                        }
        !          1430:                        if (custd[i].name)
        !          1431:                                console_out_f (_T("%s := 0x%04x\n"), custd[i].name, insn & 0xffff);
        !          1432:                        else
        !          1433:                                console_out_f (_T("%04x := 0x%04x\n"), addr, insn & 0xffff);
        !          1434:                }
        !          1435:                break;
        !          1436: 
        !          1437:        default:
        !          1438:                abort ();
        !          1439:        }
        !          1440: 
        !          1441:        if (cr && cr->bvpos >= 0) {
        !          1442:                console_out_f (_T("                 BLT [%03x %03x]\n"), cr->bvpos, cr->bhpos);
        !          1443:        }
        !          1444: }
        !          1445: 
        !          1446: static uaecptr decode_copperlist (FILE* file, uaecptr address, int nolines)
        !          1447: {
        !          1448:        while (nolines-- > 0) {
        !          1449:                decode_copper_insn (file, chipmem_wget_indirect (address), chipmem_wget_indirect (address + 2), address);
        !          1450:                address += 4;
        !          1451:        }
        !          1452:        return address;
        !          1453:        /* You may wonder why I don't stop this at the end of the copperlist?
        !          1454:        * Well, often nice things are hidden at the end and it is debatable the actual
        !          1455:        * values that mean the end of the copperlist */
        !          1456: }
        !          1457: 
        !          1458: static int copper_debugger (TCHAR **c)
        !          1459: {
        !          1460:        static uaecptr nxcopper;
        !          1461:        uae_u32 maddr;
        !          1462:        int lines;
        !          1463: 
        !          1464:        if (**c == 'd') {
        !          1465:                next_char (c);
        !          1466:                if (debug_copper)
        !          1467:                        debug_copper = 0;
        !          1468:                else
        !          1469:                        debug_copper = 1;
        !          1470:                console_out_f (_T("Copper debugger %s.\n"), debug_copper ? _T("enabled") : _T("disabled"));
        !          1471:        } else if (**c == 't') {
        !          1472:                debug_copper = 1|2;
        !          1473:                return 1;
        !          1474:        } else if (**c == 'b') {
        !          1475:                (*c)++;
        !          1476:                debug_copper = 1|4;
        !          1477:                if (more_params (c)) {
        !          1478:                        debug_copper_pc = readhex (c);
        !          1479:                        console_out_f (_T("Copper breakpoint @0x%08x\n"), debug_copper_pc);
        !          1480:                } else {
        !          1481:                        debug_copper &= ~4;
        !          1482:                }
        !          1483:        } else {
        !          1484:                if (more_params (c)) {
        !          1485:                        maddr = readhex (c);
        !          1486:                        if (maddr == 1 || maddr == 2)
        !          1487:                                maddr = get_copper_address (maddr);
        !          1488:                        else if (maddr == 0)
        !          1489:                                maddr = get_copper_address (-1);
        !          1490:                } else
        !          1491:                        maddr = nxcopper;
        !          1492: 
        !          1493:                if (more_params (c))
        !          1494:                        lines = readhex (c);
        !          1495:                else
        !          1496:                        lines = 20;
        !          1497: 
        !          1498:                nxcopper = decode_copperlist (stdout, maddr, lines);
        !          1499:        }
        !          1500:        return 0;
        !          1501: }
        !          1502: 
        !          1503: #define MAX_CHEAT_VIEW 100
        !          1504: struct trainerstruct {
        !          1505:        uaecptr addr;
        !          1506:        int size;
        !          1507: };
        !          1508: 
        !          1509: static struct trainerstruct *trainerdata;
        !          1510: static int totaltrainers;
        !          1511: 
        !          1512: static void clearcheater(void)
        !          1513: {
        !          1514:        if (!trainerdata)
        !          1515:                trainerdata =  xmalloc(struct trainerstruct, MAX_CHEAT_VIEW);
        !          1516:        memset(trainerdata, 0, sizeof (struct trainerstruct) * MAX_CHEAT_VIEW);
        !          1517:        totaltrainers = 0;
        !          1518: }
        !          1519: static int addcheater(uaecptr addr, int size)
        !          1520: {
        !          1521:        if (totaltrainers >= MAX_CHEAT_VIEW)
        !          1522:                return 0;
        !          1523:        trainerdata[totaltrainers].addr = addr;
        !          1524:        trainerdata[totaltrainers].size = size;
        !          1525:        totaltrainers++;
        !          1526:        return 1;
        !          1527: }
        !          1528: static void listcheater(int mode, int size)
        !          1529: {
        !          1530:        int i, skip;
        !          1531: 
        !          1532:        if (!trainerdata)
        !          1533:                return;
        !          1534:        if (mode)
        !          1535:                skip = 6;
        !          1536:        else
        !          1537:                skip = 8;
        !          1538:        for(i = 0; i < totaltrainers; i++) {
        !          1539:                struct trainerstruct *ts = &trainerdata[i];
        !          1540:                uae_u16 b;
        !          1541: 
        !          1542:                if (size) {
        !          1543:                        b = get_byte_debug (ts->addr);
        !          1544:                } else {
        !          1545:                        b = get_word_debug (ts->addr);
        !          1546:                }
        !          1547:                if (mode)
        !          1548:                        console_out_f (_T("%08X=%04X "), ts->addr, b);
        !          1549:                else
        !          1550:                        console_out_f (_T("%08X "), ts->addr);
        !          1551:                if ((i % skip) == skip)
        !          1552:                        console_out (_T("\n"));
        !          1553:        }
        !          1554: }
        !          1555: 
        !          1556: static void deepcheatsearch (TCHAR **c)
        !          1557: {
        !          1558:        static int first = 1;
        !          1559:        static uae_u8 *memtmp;
        !          1560:        static int memsize, memsize2;
        !          1561:        uae_u8 *p1, *p2;
        !          1562:        uaecptr addr, end;
        !          1563:        int i, wasmodified, nonmodified;
        !          1564:        static int size;
        !          1565:        static int inconly, deconly, maxdiff;
        !          1566:        int addrcnt, cnt;
        !          1567:        TCHAR v;
        !          1568: 
        !          1569:        v = _totupper (**c);
        !          1570: 
        !          1571:        if(!memtmp || v == 'S') {
        !          1572:                maxdiff = 0x10000;
        !          1573:                inconly = 0;
        !          1574:                deconly = 0;
        !          1575:                size = 1;
        !          1576:        }
        !          1577: 
        !          1578:        if (**c)
        !          1579:                (*c)++;
        !          1580:        ignore_ws (c);
        !          1581:        if ((**c) == '1' || (**c) == '2') {
        !          1582:                size = **c - '0';
        !          1583:                (*c)++;
        !          1584:        }
        !          1585:        if (more_params (c))
        !          1586:                maxdiff = readint (c);
        !          1587: 
        !          1588:        if (!memtmp || v == 'S') {
        !          1589:                first = 1;
        !          1590:                xfree (memtmp);
        !          1591:                memsize = 0;
        !          1592:                addr = 0xffffffff;
        !          1593:                while ((addr = nextaddr (addr, 0, &end)) != 0xffffffff)  {
        !          1594:                        memsize += end - addr;
        !          1595:                        addr = end - 1;
        !          1596:                }
        !          1597:                memsize2 = (memsize + 7) / 8;
        !          1598:                memtmp = xmalloc (uae_u8, memsize + memsize2);
        !          1599:                if (!memtmp)
        !          1600:                        return;
        !          1601:                memset (memtmp + memsize, 0xff, memsize2);
        !          1602:                p1 = memtmp;
        !          1603:                addr = 0xffffffff;
        !          1604:                while ((addr = nextaddr (addr, 0, &end)) != 0xffffffff) {
        !          1605:                        for (i = addr; i < end; i++)
        !          1606:                                *p1++ = get_byte_debug (i);
        !          1607:                        addr = end - 1;
        !          1608:                }
        !          1609:                console_out (_T("Deep trainer first pass complete.\n"));
        !          1610:                return;
        !          1611:        }
        !          1612:        inconly = deconly = 0;
        !          1613:        wasmodified = v == 'X' ? 0 : 1;
        !          1614:        nonmodified = v == 'Z' ? 1 : 0;
        !          1615:        if (v == 'I')
        !          1616:                inconly = 1;
        !          1617:        if (v == 'D')
        !          1618:                deconly = 1;
        !          1619:        p1 = memtmp;
        !          1620:        p2 = memtmp + memsize;
        !          1621:        addrcnt = 0;
        !          1622:        cnt = 0;
        !          1623:        addr = 0xffffffff;
        !          1624:        while ((addr = nextaddr (addr, 0, NULL)) != 0xffffffff) {
        !          1625:                uae_s32 b, b2;
        !          1626:                int doremove = 0;
        !          1627:                int addroff = addrcnt >> 3;
        !          1628:                int addrmask ;
        !          1629: 
        !          1630:                if (size == 1) {
        !          1631:                        b = (uae_s8)get_byte_debug (addr);
        !          1632:                        b2 = (uae_s8)p1[addrcnt];
        !          1633:                        addrmask = 1 << (addrcnt & 7);
        !          1634:                } else {
        !          1635:                        b = (uae_s16)get_word_debug (addr);
        !          1636:                        b2 = (uae_s16)((p1[addrcnt] << 8) | p1[addrcnt + 1]);
        !          1637:                        addrmask = 3 << (addrcnt & 7);
        !          1638:                }
        !          1639: 
        !          1640:                if (p2[addroff] & addrmask) {
        !          1641:                        if (wasmodified && !nonmodified) {
        !          1642:                                int diff = b - b2;
        !          1643:                                if (b == b2)
        !          1644:                                        doremove = 1;
        !          1645:                                if (abs(diff) > maxdiff)
        !          1646:                                        doremove = 1;
        !          1647:                                if (inconly && diff < 0)
        !          1648:                                        doremove = 1;
        !          1649:                                if (deconly && diff > 0)
        !          1650:                                        doremove = 1;
        !          1651:                        } else if (nonmodified && b == b2) {
        !          1652:                                doremove = 1;
        !          1653:                        } else if (!wasmodified && b != b2) {
        !          1654:                                doremove = 1;
        !          1655:                        }
        !          1656:                        if (doremove)
        !          1657:                                p2[addroff] &= ~addrmask;
        !          1658:                        else
        !          1659:                                cnt++;
        !          1660:                }
        !          1661:                if (size == 1) {
        !          1662:                        p1[addrcnt] = b;
        !          1663:                        addrcnt++;
        !          1664:                } else {
        !          1665:                        p1[addrcnt] = b >> 8;
        !          1666:                        p1[addrcnt + 1] = b >> 0;
        !          1667:                        addr = nextaddr (addr, 0, NULL);
        !          1668:                        if (addr == 0xffffffff)
        !          1669:                                break;
        !          1670:                        addrcnt += 2;
        !          1671:                }
        !          1672:                if  (iscancel (65536)) {
        !          1673:                        console_out_f (_T("Aborted at %08X\n"), addr);
        !          1674:                        break;
        !          1675:                }
        !          1676:        }
        !          1677: 
        !          1678:        console_out_f (_T("%d addresses found\n"), cnt);
        !          1679:        if (cnt <= MAX_CHEAT_VIEW) {
        !          1680:                clearcheater ();
        !          1681:                cnt = 0;
        !          1682:                addrcnt = 0;
        !          1683:                addr = 0xffffffff;
        !          1684:                while ((addr = nextaddr(addr, 0, NULL)) != 0xffffffff) {
        !          1685:                        int addroff = addrcnt >> 3;
        !          1686:                        int addrmask = (size == 1 ? 1 : 3) << (addrcnt & 7);
        !          1687:                        if (p2[addroff] & addrmask)
        !          1688:                                addcheater (addr, size);
        !          1689:                        addrcnt += size;
        !          1690:                        cnt++;
        !          1691:                }
        !          1692:                if (cnt > 0)
        !          1693:                        console_out (_T("\n"));
        !          1694:                listcheater (1, size);
        !          1695:        } else {
        !          1696:                console_out (_T("Now continue with 'g' and use 'D' again after you have lost another life\n"));
        !          1697:        }
        !          1698: }
        !          1699: 
        !          1700: /* cheat-search by Toni Wilen (originally by Holger Jakob) */
        !          1701: static void cheatsearch (TCHAR **c)
        !          1702: {
        !          1703:        static uae_u8 *vlist;
        !          1704:        static int listsize;
        !          1705:        static int first = 1;
        !          1706:        static int size = 1;
        !          1707:        uae_u32 val, memcnt, prevmemcnt;
        !          1708:        int i, count, vcnt, memsize;
        !          1709:        uaecptr addr, end;
        !          1710: 
        !          1711:        memsize = 0;
        !          1712:        addr = 0xffffffff;
        !          1713:        while ((addr = nextaddr (addr, 0, &end)) != 0xffffffff)  {
        !          1714:                memsize += end - addr;
        !          1715:                addr = end - 1;
        !          1716:        }
        !          1717: 
        !          1718:        if (_totupper (**c) == 'L') {
        !          1719:                listcheater (1, size);
        !          1720:                return;
        !          1721:        }
        !          1722:        ignore_ws (c);
        !          1723:        if (!more_params (c)) {
        !          1724:                first = 1;
        !          1725:                console_out (_T("Search reset\n"));
        !          1726:                xfree (vlist);
        !          1727:                listsize = memsize;
        !          1728:                vlist = xcalloc (uae_u8, listsize >> 3);
        !          1729:                return;
        !          1730:        }
        !          1731:        if (first)
        !          1732:                val = readint (c, &size);
        !          1733:        else
        !          1734:                val = readint (c);
        !          1735: 
        !          1736:        if (vlist == NULL) {
        !          1737:                listsize = memsize;
        !          1738:                vlist = xcalloc (uae_u8, listsize >> 3);
        !          1739:        }
        !          1740: 
        !          1741:        count = 0;
        !          1742:        vcnt = 0;
        !          1743: 
        !          1744:        clearcheater ();
        !          1745:        addr = 0xffffffff;
        !          1746:        prevmemcnt = memcnt = 0;
        !          1747:        while ((addr = nextaddr (addr, 0, &end)) != 0xffffffff) {
        !          1748:                if (addr + size < end) {
        !          1749:                        for (i = 0; i < size; i++) {
        !          1750:                                int shift = (size - i - 1) * 8;
        !          1751:                                if (get_byte_debug (addr + i) != ((val >> shift) & 0xff))
        !          1752:                                        break;
        !          1753:                        }
        !          1754:                        if (i == size) {
        !          1755:                                int voffset = memcnt >> 3;
        !          1756:                                int vmask = 1 << (memcnt & 7);
        !          1757:                                if (!first) {
        !          1758:                                        while (prevmemcnt < memcnt) {
        !          1759:                                                vlist[prevmemcnt >> 3] &= ~(1 << (prevmemcnt & 7));
        !          1760:                                                prevmemcnt++;
        !          1761:                                        }
        !          1762:                                        if (vlist[voffset] & vmask) {
        !          1763:                                                count++;
        !          1764:                                                addcheater(addr, size);
        !          1765:                                        } else {
        !          1766:                                                vlist[voffset] &= ~vmask;
        !          1767:                                        }
        !          1768:                                        prevmemcnt = memcnt + 1;
        !          1769:                                } else {
        !          1770:                                        vlist[voffset] |= vmask;
        !          1771:                                        count++;
        !          1772:                                }
        !          1773:                        }
        !          1774:                }
        !          1775:                memcnt++;
        !          1776:                if  (iscancel (65536)) {
        !          1777:                        console_out_f (_T("Aborted at %08X\n"), addr);
        !          1778:                        break;
        !          1779:                }
        !          1780:        }
        !          1781:        if (!first) {
        !          1782:                while (prevmemcnt < memcnt) {
        !          1783:                        vlist[prevmemcnt >> 3] &= ~(1 << (prevmemcnt & 7));
        !          1784:                        prevmemcnt++;
        !          1785:                }
        !          1786:                listcheater (0, size);
        !          1787:        }
        !          1788:        console_out_f (_T("Found %d possible addresses with 0x%X (%u) (%d bytes)\n"), count, val, val, size);
        !          1789:        if (count > 0)
        !          1790:                console_out (_T("Now continue with 'g' and use 'C' with a different value\n"));
        !          1791:        first = 0;
        !          1792: }
        !          1793: 
        !          1794: struct breakpoint_node bpnodes[BREAKPOINT_TOTAL];
        !          1795: static addrbank **debug_mem_banks;
        !          1796: static addrbank *debug_mem_area;
        !          1797: struct memwatch_node mwnodes[MEMWATCH_TOTAL];
        !          1798: static struct memwatch_node mwhit;
        !          1799: static int addressspaceheatmap;
        !          1800: 
        !          1801: static uae_u8 *illgdebug, *illghdebug;
        !          1802: static int illgdebug_break;
        !          1803: 
        !          1804: static void illg_free (void)
        !          1805: {
        !          1806:        xfree (illgdebug);
        !          1807:        illgdebug = NULL;
        !          1808:        xfree (illghdebug);
        !          1809:        illghdebug = NULL;
        !          1810: }
        !          1811: 
        !          1812: static void illg_init (void)
        !          1813: {
        !          1814:        int i;
        !          1815:        uae_u8 c = 3;
        !          1816:        uaecptr addr, end;
        !          1817: 
        !          1818:        illgdebug = xcalloc (uae_u8, 0x01000000);
        !          1819:        illghdebug = xcalloc (uae_u8, 65536);
        !          1820:        if (!illgdebug || !illghdebug) {
        !          1821:                illg_free();
        !          1822:                return;
        !          1823:        }
        !          1824:        addr = 0xffffffff;
        !          1825:        while ((addr = nextaddr (addr, 0, &end)) != 0xffffffff)  {
        !          1826:                if (end < 0x01000000) {
        !          1827:                        memset (illgdebug + addr, c, end - addr);
        !          1828:                } else {
        !          1829:                        uae_u32 s = addr >> 16;
        !          1830:                        uae_u32 e = end >> 16;
        !          1831:                        memset (illghdebug + s, c, e - s);
        !          1832:                }
        !          1833:                addr = end - 1;
        !          1834:        }
        !          1835:        if (currprefs.rtgmem_size)
        !          1836:                memset (illghdebug + (gfxmem_bank.start >> 16), 3, currprefs.rtgmem_size >> 16);
        !          1837: 
        !          1838:        i = 0;
        !          1839:        while (custd[i].name) {
        !          1840:                int rw = custd[i].rw;
        !          1841:                illgdebug[custd[i].adr] = rw;
        !          1842:                illgdebug[custd[i].adr + 1] = rw;
        !          1843:                i++;
        !          1844:        }
        !          1845:        for (i = 0; i < 16; i++) { /* CIAs */
        !          1846:                if (i == 11)
        !          1847:                        continue;
        !          1848:                illgdebug[0xbfe001 + i * 0x100] = c;
        !          1849:                illgdebug[0xbfd000 + i * 0x100] = c;
        !          1850:        }
        !          1851:        memset (illgdebug + 0xf80000, 1, 512 * 1024); /* KS ROM */
        !          1852:        memset (illgdebug + 0xdc0000, c, 0x3f); /* clock */
        !          1853: #ifdef CDTV
        !          1854:        if (currprefs.cs_cdtvram) {
        !          1855:                memset (illgdebug + 0xdc8000, c, 4096); /* CDTV batt RAM */
        !          1856:                memset (illgdebug + 0xf00000, 1, 256 * 1024); /* CDTV ext ROM */
        !          1857:        }
        !          1858: #endif
        !          1859: #ifdef CD32
        !          1860:        if (currprefs.cs_cd32cd) {
        !          1861:                memset (illgdebug + AKIKO_BASE, c, AKIKO_BASE_END - AKIKO_BASE);
        !          1862:                memset (illgdebug + 0xe00000, 1, 512 * 1024); /* CD32 ext ROM */
        !          1863:        }
        !          1864: #endif
        !          1865:        if (currprefs.cs_ksmirror_e0)
        !          1866:                memset (illgdebug + 0xe00000, 1, 512 * 1024);
        !          1867:        if (currprefs.cs_ksmirror_a8)
        !          1868:                memset (illgdebug + 0xa80000, 1, 2 * 512 * 1024);
        !          1869: #ifdef FILESYS
        !          1870:        if (uae_boot_rom_type) /* filesys "rom" */
        !          1871:                memset (illgdebug + rtarea_base, 1, 0x10000);
        !          1872: #endif
        !          1873:        if (currprefs.cs_ide > 0)
        !          1874:                memset (illgdebug + 0xdd0000, 3, 65536);
        !          1875: }
        !          1876: 
        !          1877: /* add special custom register check here */
        !          1878: static void illg_debug_check (uaecptr addr, int rwi, int size, uae_u32 val)
        !          1879: {
        !          1880:        return;
        !          1881: }
        !          1882: 
        !          1883: static void illg_debug_do (uaecptr addr, int rwi, int size, uae_u32 val)
        !          1884: {
        !          1885:        uae_u8 mask;
        !          1886:        uae_u32 pc = m68k_getpc ();
        !          1887:        int i;
        !          1888: 
        !          1889:        for (i = size - 1; i >= 0; i--) {
        !          1890:                uae_u8 v = val >> (i * 8);
        !          1891:                uae_u32 ad = addr + i;
        !          1892:                if (ad >= 0x01000000)
        !          1893:                        mask = illghdebug[ad >> 16];
        !          1894:                else
        !          1895:                        mask = illgdebug[ad];
        !          1896:                if ((mask & 3) == 3)
        !          1897:                        return;
        !          1898:                if (mask & 0x80) {
        !          1899:                        illg_debug_check (ad, rwi, size, val);
        !          1900:                } else if ((mask & 3) == 0) {
        !          1901:                        if (rwi & 2)
        !          1902:                                console_out_f (_T("W: %08X=%02X PC=%08X\n"), ad, v, pc);
        !          1903:                        else if (rwi & 1)
        !          1904:                                console_out_f (_T("R: %08X    PC=%08X\n"), ad, pc);
        !          1905:                        if (illgdebug_break)
        !          1906:                                activate_debugger ();
        !          1907:                } else if (!(mask & 1) && (rwi & 1)) {
        !          1908:                        console_out_f (_T("RO: %08X=%02X PC=%08X\n"), ad, v, pc);
        !          1909:                        if (illgdebug_break)
        !          1910:                                activate_debugger ();
        !          1911:                } else if (!(mask & 2) && (rwi & 2)) {
        !          1912:                        console_out_f (_T("WO: %08X    PC=%08X\n"), ad, pc);
        !          1913:                        if (illgdebug_break)
        !          1914:                                activate_debugger ();
        !          1915:                }
        !          1916:        }
        !          1917: }
        !          1918: 
        !          1919: static int debug_mem_off (uaecptr *addrp)
        !          1920: {
        !          1921:        uaecptr addr = *addrp;
        !          1922:        addrbank *ba;
        !          1923:        int offset = munge24 (addr) >> 16;
        !          1924:        if (!debug_mem_banks)
        !          1925:                return offset;
        !          1926:        ba = debug_mem_banks[offset];
        !          1927:        if (!ba)
        !          1928:                return offset;
        !          1929:        if (ba->mask || ba->startmask)
        !          1930:                addr = (addr & ba->mask) | ba->startmask;
        !          1931:        *addrp = addr;
        !          1932:        return offset;
        !          1933: }
        !          1934: 
        !          1935: struct smc_item {
        !          1936:        uae_u32 addr;
        !          1937:        uae_u8 cnt;
        !          1938: };
        !          1939: 
        !          1940: static int smc_size, smc_mode;
        !          1941: static struct smc_item *smc_table;
        !          1942: 
        !          1943: static void smc_free (void)
        !          1944: {
        !          1945:        if (smc_table)
        !          1946:                console_out (_T("SMCD disabled\n"));
        !          1947:        xfree(smc_table);
        !          1948:        smc_mode = 0;
        !          1949:        smc_table = NULL;
        !          1950: }
        !          1951: 
        !          1952: static void initialize_memwatch (int mode);
        !          1953: static void smc_detect_init (TCHAR **c)
        !          1954: {
        !          1955:        int v, i;
        !          1956: 
        !          1957:        ignore_ws (c);
        !          1958:        v = readint (c);
        !          1959:        smc_free ();
        !          1960:        smc_size = 1 << 24;
        !          1961:        if (currprefs.z3fastmem_size)
        !          1962:                smc_size = currprefs.z3autoconfig_start + currprefs.z3fastmem_size;
        !          1963:        smc_size += 4;
        !          1964:        smc_table = xmalloc (struct smc_item, smc_size);
        !          1965:        if (!smc_table)
        !          1966:                return;
        !          1967:        for (i = 0; i < smc_size; i++) {
        !          1968:                smc_table[i].addr = 0xffffffff;
        !          1969:                smc_table[i].cnt = 0;
        !          1970:        }
        !          1971:        if (!memwatch_enabled)
        !          1972:                initialize_memwatch (0);
        !          1973:        if (v)
        !          1974:                smc_mode = 1;
        !          1975:        console_out_f (_T("SMCD enabled. Break=%d\n"), smc_mode);
        !          1976: }
        !          1977: 
        !          1978: #define SMC_MAXHITS 8
        !          1979: static void smc_detector (uaecptr addr, int rwi, int size, uae_u32 *valp)
        !          1980: {
        !          1981:        int i, hitcnt;
        !          1982:        uaecptr hitaddr, hitpc;
        !          1983: 
        !          1984:        if (!smc_table)
        !          1985:                return;
        !          1986:        if (addr >= smc_size)
        !          1987:                return;
        !          1988:        if (rwi == 2) {
        !          1989:                for (i = 0; i < size; i++) {
        !          1990:                        if (smc_table[addr + i].cnt < SMC_MAXHITS) {
        !          1991:                                smc_table[addr + i].addr = m68k_getpc ();
        !          1992:                        }
        !          1993:                }
        !          1994:                return;
        !          1995:        }
        !          1996:        hitpc = smc_table[addr].addr;
        !          1997:        if (hitpc == 0xffffffff)
        !          1998:                return;
        !          1999:        hitaddr = addr;
        !          2000:        hitcnt = 0;
        !          2001:        while (addr < smc_size && smc_table[addr].addr != 0xffffffff) {
        !          2002:                smc_table[addr++].addr = 0xffffffff;
        !          2003:                hitcnt++;
        !          2004:        }
        !          2005:        if ((hitpc & 0xFFF80000) == 0xF80000)
        !          2006:                return;
        !          2007:        if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) {
        !          2008:                /* ignore single-word unconditional jump instructions
        !          2009:                * (instruction prefetch from PC+2 can cause false positives) */
        !          2010:                if (regs.irc == 0x4e75 || regs.irc == 4e74 || regs.irc == 0x4e72 || regs.irc == 0x4e77)
        !          2011:                        return; /* RTS, RTD, RTE, RTR */
        !          2012:                if ((regs.irc & 0xff00) == 0x6000 && (regs.irc & 0x00ff) != 0 && (regs.irc & 0x00ff) != 0xff)
        !          2013:                        return; /* BRA.B */
        !          2014:        }
        !          2015:        if (hitcnt < 100) {
        !          2016:                smc_table[hitaddr].cnt++;
        !          2017:                console_out_f (_T("SMC at %08X - %08X (%d) from %08X\n"),
        !          2018:                        hitaddr, hitaddr + hitcnt, hitcnt, hitpc);
        !          2019:                if (smc_mode)
        !          2020:                        activate_debugger ();
        !          2021:                if (smc_table[hitaddr].cnt >= SMC_MAXHITS)
        !          2022:                        console_out_f (_T("* hit count >= %d, future hits ignored\n"), SMC_MAXHITS);
        !          2023:        }
        !          2024: }
        !          2025: 
        !          2026: uae_u8 *save_debug_memwatch (int *len, uae_u8 *dstptr)
        !          2027: {
        !          2028:        uae_u8 *dstbak, *dst;
        !          2029:        int total;
        !          2030: 
        !          2031:        total = 0;
        !          2032:        for (int i = 0; i < MEMWATCH_TOTAL; i++) {
        !          2033:                if (mwnodes[i].size > 0)
        !          2034:                        total++;
        !          2035:        }
        !          2036:        if (!total)
        !          2037:                return NULL;
        !          2038: 
        !          2039:        if (dstptr)
        !          2040:                dstbak = dst = dstptr;
        !          2041:        else
        !          2042:                dstbak = dst = xmalloc (uae_u8, 1000);
        !          2043:        save_u32 (1);
        !          2044:        save_u8 (total);
        !          2045:        for (int i = 0; i < MEMWATCH_TOTAL; i++) {
        !          2046:                struct memwatch_node *m = &mwnodes[i];
        !          2047:                if (m->size <= 0)
        !          2048:                        continue;
        !          2049:                save_store_pos ();
        !          2050:                save_u8 (i);
        !          2051:                save_u8 (m->modval_written);
        !          2052:                save_u8 (m->mustchange);
        !          2053:                save_u8 (m->frozen);
        !          2054:                save_u8 (m->val_enabled);
        !          2055:                save_u8 (m->rwi);
        !          2056:                save_u32 (m->addr);
        !          2057:                save_u32 (m->size);
        !          2058:                save_u32 (m->modval);
        !          2059:                save_u32 (m->val_mask);
        !          2060:                save_u32 (m->val_size);
        !          2061:                save_u32 (m->val);
        !          2062:                save_u32 (m->pc);
        !          2063:                save_u32 (m->access_mask);
        !          2064:                save_u32 (m->reg);
        !          2065:                save_store_size ();
        !          2066:        }
        !          2067:        *len = dst - dstbak;
        !          2068:        return dstbak;
        !          2069: }
        !          2070: 
        !          2071: uae_u8 *restore_debug_memwatch (uae_u8 *src)
        !          2072: {
        !          2073:        if (restore_u32 () != 1)
        !          2074:                return src;
        !          2075:        int total = restore_u8 ();
        !          2076:        for (int i = 0; i < total; i++) {
        !          2077:                restore_store_pos ();
        !          2078:                int idx = restore_u8 ();
        !          2079:                struct memwatch_node *m = &mwnodes[idx];
        !          2080:                m->modval_written = restore_u8 ();
        !          2081:                m->mustchange = restore_u8 ();
        !          2082:                m->frozen = restore_u8 ();
        !          2083:                m->val_enabled = restore_u8 ();
        !          2084:                m->rwi = restore_u8 ();
        !          2085:                m->addr = restore_u32 ();
        !          2086:                m->size = restore_u32 ();
        !          2087:                m->modval = restore_u32 ();
        !          2088:                m->val_mask = restore_u32 ();
        !          2089:                m->val_size = restore_u32 ();
        !          2090:                m->val = restore_u32 ();
        !          2091:                m->pc = restore_u32 ();
        !          2092:                m->access_mask = restore_u32();
        !          2093:                m->reg = restore_u32();
        !          2094:                restore_store_size ();
        !          2095:        }
        !          2096:        return src;
        !          2097: }
        !          2098: 
        !          2099: void restore_debug_memwatch_finish (void)
        !          2100: {
        !          2101:        for (int i = 0; i < MEMWATCH_TOTAL; i++) {
        !          2102:                struct memwatch_node *m = &mwnodes[i];
        !          2103:                if (m->size) {
        !          2104:                        if (!memwatch_enabled)
        !          2105:                                initialize_memwatch (0);
        !          2106:                        return;
        !          2107:                }
        !          2108:        }
        !          2109: }
        !          2110: 
        !          2111: static int memwatch_func (uaecptr addr, int rwi, int size, uae_u32 *valp, uae_u32 accessmask, uae_u32 reg)
        !          2112: {
        !          2113:        int i, brk;
        !          2114:        uae_u32 val = *valp;
        !          2115: 
        !          2116:        if (illgdebug)
        !          2117:                illg_debug_do (addr, rwi, size, val);
        !          2118: 
        !          2119:        if (addressspaceheatmap)
        !          2120:                memwatch_heatmap (addr, rwi, size);
        !          2121: 
        !          2122:        addr = munge24 (addr);
        !          2123:        if (smc_table && (rwi >= 2))
        !          2124:                smc_detector (addr, rwi, size, valp);
        !          2125:        for (i = 0; i < MEMWATCH_TOTAL; i++) {
        !          2126:                struct memwatch_node *m = &mwnodes[i];
        !          2127:                uaecptr addr2 = m->addr;
        !          2128:                uaecptr addr3 = addr2 + m->size;
        !          2129:                int rwi2 = m->rwi;
        !          2130:                uae_u32 oldval = 0;
        !          2131:                int isoldval = 0;
        !          2132: 
        !          2133:                brk = 0;
        !          2134:                if (m->size == 0)
        !          2135:                        continue;
        !          2136:                if (!(rwi & rwi2))
        !          2137:                        continue;
        !          2138:                if (!(m->access_mask & accessmask))
        !          2139:                        continue;
        !          2140: 
        !          2141:                if (addr >= addr2 && addr < addr3)
        !          2142:                        brk = 1;
        !          2143:                if (!brk && size == 2 && (addr + 1 >= addr2 && addr + 1 < addr3))
        !          2144:                        brk = 1;
        !          2145:                if (!brk && size == 4 && ((addr + 2 >= addr2 && addr + 2 < addr3) || (addr + 3 >= addr2 && addr + 3 < addr3)))
        !          2146:                        brk = 1;
        !          2147: 
        !          2148:                if (!brk)
        !          2149:                        continue;
        !          2150:                if (mem_banks[addr >> 16]->check (addr, size)) {
        !          2151:                        uae_u8 *p = mem_banks[addr >> 16]->xlateaddr (addr);
        !          2152:                        if (size == 1)
        !          2153:                                oldval = p[0];
        !          2154:                        else if (size == 2)
        !          2155:                                oldval = (p[0] << 8) | p[1];
        !          2156:                        else
        !          2157:                                oldval = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
        !          2158:                        isoldval = 1;
        !          2159:                }
        !          2160: 
        !          2161:                if (!m->frozen && m->val_enabled) {
        !          2162:                        int trigger = 0;
        !          2163:                        uae_u32 mask = m->size == 4 ? 0xffffffff : (1 << (m->size * 8)) - 1;
        !          2164:                        uae_u32 mval = m->val;
        !          2165:                        int scnt = size;
        !          2166:                        for (;;) {
        !          2167:                                if (((mval & mask) & m->val_mask) == ((val & mask) & m->val_mask))
        !          2168:                                        trigger = 1;
        !          2169:                                if (mask & 0x80000000)
        !          2170:                                        break;
        !          2171:                                if (m->size == 1) {
        !          2172:                                        mask <<= 8;
        !          2173:                                        mval <<= 8;
        !          2174:                                        scnt--;
        !          2175:                                } else if (m->size == 2) {
        !          2176:                                        mask <<= 16;
        !          2177:                                        scnt -= 2;
        !          2178:                                        mval <<= 16;
        !          2179:                                } else {
        !          2180:                                        scnt -= 4;
        !          2181:                                }
        !          2182:                                if (scnt <= 0)
        !          2183:                                        break;
        !          2184:                        }
        !          2185:                        if (!trigger)
        !          2186:                                continue;
        !          2187:                }
        !          2188: 
        !          2189:                if (m->mustchange && rwi == 2 && isoldval) {
        !          2190:                        if (oldval == *valp)
        !          2191:                                continue;
        !          2192:                }
        !          2193: 
        !          2194:                if (m->modval_written) {
        !          2195:                        if (!rwi) {
        !          2196:                                brk = 0;
        !          2197:                        } else if (m->modval_written == 1) {
        !          2198:                                m->modval_written = 2;
        !          2199:                                m->modval = val;
        !          2200:                                brk = 0;
        !          2201:                        } else if (m->modval == val) {
        !          2202:                                brk = 0;
        !          2203:                        }
        !          2204:                }
        !          2205:                if (m->frozen) {
        !          2206:                        if (m->val_enabled) {
        !          2207:                                int shift = (addr + size - 1) - (m->addr + m->val_size - 1);
        !          2208:                                uae_u32 sval;
        !          2209:                                uae_u32 mask;
        !          2210: 
        !          2211:                                if (m->val_size == 4)
        !          2212:                                        mask = 0xffffffff;
        !          2213:                                else if (m->val_size == 2)
        !          2214:                                        mask = 0x0000ffff;
        !          2215:                                else
        !          2216:                                        mask = 0x000000ff;
        !          2217: 
        !          2218:                                sval = m->val;
        !          2219:                                if (shift < 0) {
        !          2220:                                        shift = -8 * shift;
        !          2221:                                        sval >>= shift;
        !          2222:                                        mask >>= shift;
        !          2223:                                } else {
        !          2224:                                        shift = 8 * shift;
        !          2225:                                        sval <<= shift;
        !          2226:                                        mask <<= shift;
        !          2227:                                }
        !          2228:                                *valp = (sval & mask) | ((*valp) & ~mask);
        !          2229:                                write_log (_T("%p %p %08x %08x %d\n"), addr, m->addr, *valp, mask, shift);
        !          2230:                                return 1;
        !          2231:                        }
        !          2232:                        return 0;
        !          2233:                }
        !          2234:                //      if (!notinrom ())
        !          2235:                //          return 1;
        !          2236:                mwhit.pc = M68K_GETPC;
        !          2237:                mwhit.addr = addr;
        !          2238:                mwhit.rwi = rwi;
        !          2239:                mwhit.size = size;
        !          2240:                mwhit.val = 0;
        !          2241:                mwhit.access_mask = accessmask;
        !          2242:                mwhit.reg = reg;
        !          2243:                if (mwhit.rwi & 2)
        !          2244:                        mwhit.val = val;
        !          2245:                memwatch_triggered = i + 1;
        !          2246:                debugging = 1;
        !          2247:                set_special (SPCFLAG_BRK);
        !          2248:                return 1;
        !          2249:        }
        !          2250:        return 1;
        !          2251: }
        !          2252: 
        !          2253: #endif /* WINUAE_FOR_HATARI */
        !          2254: #if 0
        !          2255: 
        !          2256: static int mmu_hit (uaecptr addr, int size, int rwi, uae_u32 *v);
        !          2257: 
        !          2258: static uae_u32 REGPARAM2 mmu_lget (uaecptr addr)
        !          2259: {
        !          2260:        int off = debug_mem_off (&addr);
        !          2261:        uae_u32 v = 0;
        !          2262:        if (!mmu_hit (addr, 4, 0, &v))
        !          2263:                v = debug_mem_banks[off]->lget (addr);
        !          2264:        return v;
        !          2265: }
        !          2266: static uae_u32 REGPARAM2 mmu_wget (uaecptr addr)
        !          2267: {
        !          2268:        int off = debug_mem_off (&addr);
        !          2269:        uae_u32 v = 0;
        !          2270:        if (!mmu_hit (addr, 2, 0, &v))
        !          2271:                v = debug_mem_banks[off]->wget (addr);
        !          2272:        return v;
        !          2273: }
        !          2274: static uae_u32 REGPARAM2 mmu_bget (uaecptr addr)
        !          2275: {
        !          2276:        int off = debug_mem_off (&addr);
        !          2277:        uae_u32 v = 0;
        !          2278:        if (!mmu_hit(addr, 1, 0, &v))
        !          2279:                v = debug_mem_banks[off]->bget (addr);
        !          2280:        return v;
        !          2281: }
        !          2282: static void REGPARAM2 mmu_lput (uaecptr addr, uae_u32 v)
        !          2283: {
        !          2284:        int off = debug_mem_off (&addr);
        !          2285:        if (!mmu_hit (addr, 4, 1, &v))
        !          2286:                debug_mem_banks[off]->lput (addr, v);
        !          2287: }
        !          2288: static void REGPARAM2 mmu_wput (uaecptr addr, uae_u32 v)
        !          2289: {
        !          2290:        int off = debug_mem_off (&addr);
        !          2291:        if (!mmu_hit (addr, 2, 1, &v))
        !          2292:                debug_mem_banks[off]->wput (addr, v);
        !          2293: }
        !          2294: static void REGPARAM2 mmu_bput (uaecptr addr, uae_u32 v)
        !          2295: {
        !          2296:        int off = debug_mem_off (&addr);
        !          2297:        if (!mmu_hit (addr, 1, 1, &v))
        !          2298:                debug_mem_banks[off]->bput (addr, v);
        !          2299: }
        !          2300: 
        !          2301: static uae_u32 REGPARAM2 debug_lget (uaecptr addr)
        !          2302: {
        !          2303:        uae_u32 off = debug_mem_off (&addr);
        !          2304:        uae_u32 v;
        !          2305:        v = debug_mem_banks[off]->lget (addr);
        !          2306:        memwatch_func (addr, 1, 4, &v, MW_MASK_CPU, 0);
        !          2307:        return v;
        !          2308: }
        !          2309: static uae_u32 REGPARAM2 mmu_lgeti (uaecptr addr)
        !          2310: {
        !          2311:        int off = debug_mem_off (&addr);
        !          2312:        uae_u32 v = 0;
        !          2313:        if (!mmu_hit (addr, 4, 4, &v))
        !          2314:                v = debug_mem_banks[off]->lgeti (addr);
        !          2315:        return v;
        !          2316: }
        !          2317: static uae_u32 REGPARAM2 mmu_wgeti (uaecptr addr)
        !          2318: {
        !          2319:        int off = debug_mem_off (&addr);
        !          2320:        uae_u32 v = 0;
        !          2321:        if (!mmu_hit (addr, 2, 4, &v))
        !          2322:                v = debug_mem_banks[off]->wgeti (addr);
        !          2323:        return v;
        !          2324: }
        !          2325: 
        !          2326: static uae_u32 REGPARAM2 debug_wget (uaecptr addr)
        !          2327: {
        !          2328:        int off = debug_mem_off (&addr);
        !          2329:        uae_u32 v;
        !          2330:        v = debug_mem_banks[off]->wget (addr);
        !          2331:        memwatch_func (addr, 1, 2, &v, MW_MASK_CPU, 0);
        !          2332:        return v;
        !          2333: }
        !          2334: static uae_u32 REGPARAM2 debug_bget (uaecptr addr)
        !          2335: {
        !          2336:        int off = debug_mem_off (&addr);
        !          2337:        uae_u32 v;
        !          2338:        v = debug_mem_banks[off]->bget (addr);
        !          2339:        memwatch_func (addr, 1, 1, &v, MW_MASK_CPU, 0);
        !          2340:        return v;
        !          2341: }
        !          2342: static uae_u32 REGPARAM2 debug_lgeti (uaecptr addr)
        !          2343: {
        !          2344:        int off = debug_mem_off (&addr);
        !          2345:        uae_u32 v;
        !          2346:        v = debug_mem_banks[off]->lgeti (addr);
        !          2347:        memwatch_func (addr, 4, 4, &v, MW_MASK_CPU, 0);
        !          2348:        return v;
        !          2349: }
        !          2350: static uae_u32 REGPARAM2 debug_wgeti (uaecptr addr)
        !          2351: {
        !          2352:        int off = debug_mem_off (&addr);
        !          2353:        uae_u32 v;
        !          2354:        v = debug_mem_banks[off]->wgeti (addr);
        !          2355:        memwatch_func (addr, 4, 2, &v, MW_MASK_CPU, 0);
        !          2356:        return v;
        !          2357: }
        !          2358: static void REGPARAM2 debug_lput (uaecptr addr, uae_u32 v)
        !          2359: {
        !          2360:        int off = debug_mem_off (&addr);
        !          2361:        if (memwatch_func (addr, 2, 4, &v, MW_MASK_CPU, 0))
        !          2362:                debug_mem_banks[off]->lput (addr, v);
        !          2363: }
        !          2364: static void REGPARAM2 debug_wput (uaecptr addr, uae_u32 v)
        !          2365: {
        !          2366:        int off = debug_mem_off (&addr);
        !          2367:        if (memwatch_func (addr, 2, 2, &v, MW_MASK_CPU, 0))
        !          2368:                debug_mem_banks[off]->wput (addr, v);
        !          2369: }
        !          2370: static void REGPARAM2 debug_bput (uaecptr addr, uae_u32 v)
        !          2371: {
        !          2372:        int off = debug_mem_off (&addr);
        !          2373:        if (memwatch_func (addr, 2, 1, &v, MW_MASK_CPU, 0))
        !          2374:                debug_mem_banks[off]->bput (addr, v);
        !          2375: }
        !          2376: static int REGPARAM2 debug_check (uaecptr addr, uae_u32 size)
        !          2377: {
        !          2378:        return debug_mem_banks[munge24 (addr) >> 16]->check (addr, size);
        !          2379: }
        !          2380: static uae_u8 *REGPARAM2 debug_xlate (uaecptr addr)
        !          2381: {
        !          2382:        return debug_mem_banks[munge24 (addr) >> 16]->xlateaddr (addr);
        !          2383: }
        !          2384: 
        !          2385: uae_u16 debug_wputpeekdma_chipset (uaecptr addr, uae_u32 v, uae_u32 mask, int reg)
        !          2386: {
        !          2387:        if (!memwatch_enabled)
        !          2388:                return v;
        !          2389:        addr &= 0x1fe;
        !          2390:        addr += 0xdff000;
        !          2391:        memwatch_func (addr, 2, 2, &v, mask, reg);
        !          2392:        return v;
        !          2393: }
        !          2394: uae_u16 debug_wputpeekdma_chipram (uaecptr addr, uae_u32 v, uae_u32 mask, int reg)
        !          2395: {
        !          2396:        if (!memwatch_enabled)
        !          2397:                return v;
        !          2398:        if (debug_mem_banks[addr >> 16] == NULL)
        !          2399:                return v;
        !          2400:        if (!currprefs.z3chipmem_size)
        !          2401:                addr &= chipmem_bank.mask;
        !          2402:        memwatch_func (addr & chipmem_bank.mask, 2, 2, &v, mask, reg);
        !          2403:        return v;
        !          2404: }
        !          2405: uae_u16 debug_wgetpeekdma_chipram (uaecptr addr, uae_u32 v, uae_u32 mask, int reg)
        !          2406: {
        !          2407:        uae_u32 vv = v;
        !          2408:        if (!memwatch_enabled)
        !          2409:                return v;
        !          2410:        if (debug_mem_banks[addr >> 16] == NULL)
        !          2411:                return v;
        !          2412:        if (!currprefs.z3chipmem_size)
        !          2413:                addr &= chipmem_bank.mask;
        !          2414:        memwatch_func (addr, 1, 2, &vv, mask, reg);
        !          2415:        return vv;
        !          2416: }
        !          2417: 
        !          2418: void debug_putlpeek (uaecptr addr, uae_u32 v)
        !          2419: {
        !          2420:        if (!memwatch_enabled)
        !          2421:                return;
        !          2422:        memwatch_func (addr, 2, 4, &v, MW_MASK_CPU, 0);
        !          2423: }
        !          2424: void debug_wputpeek (uaecptr addr, uae_u32 v)
        !          2425: {
        !          2426:        if (!memwatch_enabled)
        !          2427:                return;
        !          2428:        memwatch_func (addr, 2, 2, &v, MW_MASK_CPU, 0);
        !          2429: }
        !          2430: void debug_bputpeek (uaecptr addr, uae_u32 v)
        !          2431: {
        !          2432:        if (!memwatch_enabled)
        !          2433:                return;
        !          2434:        memwatch_func (addr, 2, 1, &v, MW_MASK_CPU, 0);
        !          2435: }
        !          2436: void debug_bgetpeek (uaecptr addr, uae_u32 v)
        !          2437: {
        !          2438:        uae_u32 vv = v;
        !          2439:        if (!memwatch_enabled)
        !          2440:                return;
        !          2441:        memwatch_func (addr, 1, 1, &vv, MW_MASK_CPU, 0);
        !          2442: }
        !          2443: void debug_wgetpeek (uaecptr addr, uae_u32 v)
        !          2444: {
        !          2445:        uae_u32 vv = v;
        !          2446:        if (!memwatch_enabled)
        !          2447:                return;
        !          2448:        memwatch_func (addr, 1, 2, &vv, MW_MASK_CPU, 0);
        !          2449: }
        !          2450: void debug_lgetpeek (uaecptr addr, uae_u32 v)
        !          2451: {
        !          2452:        uae_u32 vv = v;
        !          2453:        if (!memwatch_enabled)
        !          2454:                return;
        !          2455:        memwatch_func (addr, 1, 4, &vv, MW_MASK_CPU, 0);
        !          2456: }
        !          2457: 
        !          2458: #ifndef WINUAE_FOR_HATARI
        !          2459: 
        !          2460: struct membank_store
        !          2461: {
        !          2462:        addrbank *addr;
        !          2463:        addrbank newbank;
        !          2464:        int banknr;
        !          2465: };
        !          2466: 
        !          2467: static struct membank_store *membank_stores;
        !          2468: static int membank_total;
        !          2469: #define MEMWATCH_STORE_SLOTS 32
        !          2470: 
        !          2471: static void memwatch_reset (void)
        !          2472: {
        !          2473:        for (int i = 0; i < membank_total; i++) {
        !          2474:                addrbank *ab = debug_mem_banks[i];
        !          2475:                if (!ab)
        !          2476:                        continue;
        !          2477:                map_banks_quick (ab, i, 1, 1);
        !          2478:        }
        !          2479:        for (int i = 0; membank_stores[i].addr; i++) {
        !          2480:                struct membank_store *ms = &membank_stores[i];
        !          2481:                xfree ((char*)ms->newbank.name);
        !          2482:                memset (ms, 0, sizeof (struct membank_store));
        !          2483:                ms->addr = NULL;
        !          2484:        }
        !          2485:        memset (debug_mem_banks, 0, membank_total * sizeof (addrbank*));
        !          2486: }
        !          2487: 
        !          2488: static void memwatch_remap (uaecptr addr)
        !          2489: {
        !          2490:        int mode = 0;
        !          2491:        int i;
        !          2492:        int banknr;
        !          2493:        struct membank_store *ms;
        !          2494:        addrbank *bank;
        !          2495:        addrbank *newbank = NULL;
        !          2496: 
        !          2497:        addr &= ~65535;
        !          2498:        banknr = addr >> 16;
        !          2499:        if (debug_mem_banks[banknr])
        !          2500:                return;
        !          2501:        bank = mem_banks[banknr];
        !          2502:        for (i = 0 ; i < MEMWATCH_STORE_SLOTS; i++) {
        !          2503:                ms = &membank_stores[i];
        !          2504:                if (ms->addr == NULL)
        !          2505:                        break;
        !          2506:                if (ms->addr == bank) {
        !          2507:                        newbank = &ms->newbank;
        !          2508:                        break;
        !          2509:                }
        !          2510:        }
        !          2511:        if (i >= MEMWATCH_STORE_SLOTS)
        !          2512:                return;
        !          2513:        if (!newbank) {
        !          2514:                TCHAR tmp[200];
        !          2515:                _stprintf (tmp, _T("%s [D]"), bank->name);
        !          2516:                ms->addr = bank;
        !          2517:                ms->banknr = banknr;
        !          2518:                newbank = &ms->newbank;
        !          2519:                memcpy (newbank, bank, sizeof addrbank);
        !          2520:                newbank->bget = mode ? mmu_bget : debug_bget;
        !          2521:                newbank->wget = mode ? mmu_wget : debug_wget;
        !          2522:                newbank->lget = mode ? mmu_lget : debug_lget;
        !          2523:                newbank->bput = mode ? mmu_bput : debug_bput;
        !          2524:                newbank->wput = mode ? mmu_wput : debug_wput;
        !          2525:                newbank->lput = mode ? mmu_lput : debug_lput;
        !          2526:                newbank->check = debug_check;
        !          2527:                newbank->xlateaddr = debug_xlate;
        !          2528:                newbank->wgeti = mode ? mmu_wgeti : debug_wgeti;
        !          2529:                newbank->lgeti = mode ? mmu_lgeti : debug_lgeti;
        !          2530:                newbank->name = my_strdup (tmp);
        !          2531:                if (!newbank->mask)
        !          2532:                        newbank->mask = -1;
        !          2533:        }
        !          2534:        debug_mem_banks[banknr] = bank;
        !          2535:        map_banks_quick (newbank, banknr, 1, 1);
        !          2536:        // map aliases
        !          2537:        for (i = 0; i < membank_total; i++) {
        !          2538:                uaecptr addr2 = i << 16;
        !          2539:                addrbank *ab = &get_mem_bank(addr2);
        !          2540:                if (ab != ms->addr)
        !          2541:                        continue;
        !          2542:                if ((addr2 & ab->mask) == (addr & bank->mask)) {
        !          2543:                        debug_mem_banks[i] = ms->addr;
        !          2544:                        map_banks_quick (newbank, i, 1, 1);
        !          2545:                }
        !          2546:        }
        !          2547: }
        !          2548: 
        !          2549: static void memwatch_setup (void)
        !          2550: {
        !          2551:        memwatch_reset ();
        !          2552:        for (int i = 0; i < MEMWATCH_TOTAL; i++) {
        !          2553:                struct memwatch_node *m = &mwnodes[i];
        !          2554:                uae_u32 size = 0;
        !          2555:                if (!m->size)
        !          2556:                        continue;
        !          2557:                while (size < m->size) {
        !          2558:                        memwatch_remap (m->addr + size);
        !          2559:                        size += 65536;
        !          2560:                }
        !          2561:        }
        !          2562: }
        !          2563: 
        !          2564: static int deinitialize_memwatch (void)
        !          2565: {
        !          2566:        int oldmode;
        !          2567: 
        !          2568:        if (!memwatch_enabled && !mmu_enabled)
        !          2569:                return -1;
        !          2570:        memwatch_reset ();
        !          2571:        oldmode = mmu_enabled ? 1 : 0;
        !          2572:        xfree (debug_mem_banks);
        !          2573:        debug_mem_banks = NULL;
        !          2574:        xfree (debug_mem_area);
        !          2575:        debug_mem_area = NULL;
        !          2576:        xfree (membank_stores);
        !          2577:        membank_stores = NULL;
        !          2578:        memwatch_enabled = 0;
        !          2579:        mmu_enabled = 0;
        !          2580:        xfree (illgdebug);
        !          2581:        illgdebug = 0;
        !          2582:        return oldmode;
        !          2583: }
        !          2584: 
        !          2585: static void initialize_memwatch (int mode)
        !          2586: {
        !          2587:        membank_total = currprefs.address_space_24 ? 256 : 65536;
        !          2588:        deinitialize_memwatch ();
        !          2589:        debug_mem_banks = xcalloc (addrbank*, membank_total);
        !          2590:        debug_mem_area = xcalloc (addrbank, membank_total);
        !          2591:        membank_stores = xcalloc (struct membank_store, MEMWATCH_STORE_SLOTS);
        !          2592: #if 0
        !          2593:        int i, j, as;
        !          2594:        addrbank *a1, *a2, *oa;
        !          2595:        oa = NULL;
        !          2596:        for (i = 0; i < as; i++) {
        !          2597:                a1 = debug_mem_banks[i] = debug_mem_area + i;
        !          2598:                a2 = mem_banks[i];
        !          2599:                if (a2 != oa) {
        !          2600:                        for (j = 0; membank_stores[j].addr; j++) {
        !          2601:                                if (membank_stores[j].addr == a2)
        !          2602:                                        break;
        !          2603:                        }
        !          2604:                        if (membank_stores[j].addr == NULL) {
        !          2605:                                membank_stores[j].addr = a2;
        !          2606:                                memcpy (&membank_stores[j].store, a2, sizeof (addrbank));
        !          2607:                        }
        !          2608:                }
        !          2609:                memcpy (a1, a2, sizeof (addrbank));
        !          2610:        }
        !          2611:        for (i = 0; i < as; i++) {
        !          2612:                a2 = mem_banks[i];
        !          2613:                a2->bget = mode ? mmu_bget : debug_bget;
        !          2614:                a2->wget = mode ? mmu_wget : debug_wget;
        !          2615:                a2->lget = mode ? mmu_lget : debug_lget;
        !          2616:                a2->bput = mode ? mmu_bput : debug_bput;
        !          2617:                a2->wput = mode ? mmu_wput : debug_wput;
        !          2618:                a2->lput = mode ? mmu_lput : debug_lput;
        !          2619:                a2->check = debug_check;
        !          2620:                a2->xlateaddr = debug_xlate;
        !          2621:                a2->wgeti = mode ? mmu_wgeti : debug_wgeti;
        !          2622:                a2->lgeti = mode ? mmu_lgeti : debug_lgeti;
        !          2623:        }
        !          2624: #endif
        !          2625:        if (mode)
        !          2626:                mmu_enabled = 1;
        !          2627:        else
        !          2628:                memwatch_enabled = 1;
        !          2629: }
        !          2630: 
        !          2631: int debug_bankchange (int mode)
        !          2632: {
        !          2633:        if (mode == -1) {
        !          2634:                int v = deinitialize_memwatch ();
        !          2635:                if (v < 0)
        !          2636:                        return -2;
        !          2637:                return v;
        !          2638:        }
        !          2639:        if (mode >= 0) {
        !          2640:                initialize_memwatch (mode);
        !          2641:                memwatch_setup ();
        !          2642:        }
        !          2643:        return -1;
        !          2644: }
        !          2645: 
        !          2646: addrbank *get_mem_bank_real(uaecptr addr)
        !          2647: {
        !          2648:        addrbank *ab = &get_mem_bank(addr);
        !          2649:        if (!memwatch_enabled)
        !          2650:                return ab;
        !          2651:        addrbank *ab2 = debug_mem_banks[addr >> 16];
        !          2652:        if (ab2)
        !          2653:                return ab2;
        !          2654:        return ab;
        !          2655: }
        !          2656: 
        !          2657: struct mw_acc
        !          2658: {
        !          2659:        uae_u32 mask;
        !          2660:        const TCHAR *name;
        !          2661: };
        !          2662: 
        !          2663: static const struct mw_acc memwatch_access_masks[] =
        !          2664: {
        !          2665:        { MW_MASK_ALL, _T("ALL") },
        !          2666:        { MW_MASK_ALL & ~MW_MASK_CPU, _T("DMA") },
        !          2667:        { MW_MASK_BLITTER_A | MW_MASK_BLITTER_B | MW_MASK_BLITTER_C | MW_MASK_BLITTER_D, _T("BLT") },
        !          2668:        { MW_MASK_AUDIO_0 | MW_MASK_AUDIO_1 | MW_MASK_AUDIO_2 | MW_MASK_AUDIO_3, _T("AUD") },
        !          2669:        { MW_MASK_BPL_0 | MW_MASK_BPL_1 | MW_MASK_BPL_2 | MW_MASK_BPL_3 | 
        !          2670:          MW_MASK_BPL_4 | MW_MASK_BPL_5 | MW_MASK_BPL_6 | MW_MASK_BPL_7 , _T("BPL") },
        !          2671:        { MW_MASK_SPR_0 | MW_MASK_SPR_1 | MW_MASK_SPR_2 | MW_MASK_SPR_3 |
        !          2672:          MW_MASK_SPR_4 | MW_MASK_SPR_5 | MW_MASK_SPR_6 | MW_MASK_SPR_7, _T("SPR") },
        !          2673:        
        !          2674:        { MW_MASK_CPU, _T("CPU") },
        !          2675:        { MW_MASK_COPPER, _T("COP") },
        !          2676:        { MW_MASK_BLITTER_A, _T("BLTA") },
        !          2677:        { MW_MASK_BLITTER_B, _T("BLTB") },
        !          2678:        { MW_MASK_BLITTER_C, _T("BLTC") },
        !          2679:        { MW_MASK_BLITTER_D, _T("BLTD") },
        !          2680:        { MW_MASK_DISK, _T("DSK") },
        !          2681:        { MW_MASK_AUDIO_0, _T("AUD0") },
        !          2682:        { MW_MASK_AUDIO_1, _T("AUD1") },
        !          2683:        { MW_MASK_AUDIO_2, _T("AUD2") },
        !          2684:        { MW_MASK_AUDIO_3, _T("AUD3") },
        !          2685:        { MW_MASK_BPL_0, _T("BPL0") },
        !          2686:        { MW_MASK_BPL_1, _T("BPL1") },
        !          2687:        { MW_MASK_BPL_2, _T("BPL2") },
        !          2688:        { MW_MASK_BPL_3, _T("BPL3") },
        !          2689:        { MW_MASK_BPL_4, _T("BPL4") },
        !          2690:        { MW_MASK_BPL_5, _T("BPL5") },
        !          2691:        { MW_MASK_BPL_6, _T("BPL6") },
        !          2692:        { MW_MASK_BPL_7, _T("BPL7") },
        !          2693:        { MW_MASK_SPR_0, _T("SPR0") },
        !          2694:        { MW_MASK_SPR_1, _T("SPR1") },
        !          2695:        { MW_MASK_SPR_2, _T("SPR2") },
        !          2696:        { MW_MASK_SPR_3, _T("SPR3") },
        !          2697:        { MW_MASK_SPR_4, _T("SPR4") },
        !          2698:        { MW_MASK_SPR_5, _T("SPR5") },
        !          2699:        { MW_MASK_SPR_6, _T("SPR6") },
        !          2700:        { MW_MASK_SPR_7, _T("SPR7") },
        !          2701:        NULL
        !          2702: };
        !          2703: 
        !          2704: static TCHAR *getsizechar (int size)
        !          2705: {
        !          2706:        if (size == 4)
        !          2707:                return _T(".l");
        !          2708:        if (size == 3)
        !          2709:                return _T(".3");
        !          2710:        if (size == 2)
        !          2711:                return _T(".w");
        !          2712:        if (size == 1)
        !          2713:                return _T(".b");
        !          2714:        return _T("");
        !          2715: }
        !          2716: 
        !          2717: void memwatch_dump2 (TCHAR *buf, int bufsize, int num)
        !          2718: {
        !          2719:        int i;
        !          2720:        struct memwatch_node *mwn;
        !          2721: 
        !          2722:        if (buf)
        !          2723:                memset (buf, 0, bufsize * sizeof (TCHAR));
        !          2724:        for (i = 0; i < MEMWATCH_TOTAL; i++) {
        !          2725:                if ((num >= 0 && num == i) || (num < 0)) {
        !          2726:                        uae_u32 usedmask = 0;
        !          2727:                        mwn = &mwnodes[i];
        !          2728:                        if (mwn->size == 0)
        !          2729:                                continue;
        !          2730:                        buf = buf_out (buf, &bufsize, _T("%2d: %08X - %08X (%d) %c%c%c"),
        !          2731:                                i, mwn->addr, mwn->addr + (mwn->size - 1), mwn->size,
        !          2732:                                (mwn->rwi & 1) ? 'R' : ' ', (mwn->rwi & 2) ? 'W' : ' ', (mwn->rwi & 4) ? 'I' : ' ');
        !          2733:                        if (mwn->frozen)
        !          2734:                                buf = buf_out (buf, &bufsize, _T(" F"));
        !          2735:                        if (mwn->val_enabled)
        !          2736:                                buf = buf_out (buf, &bufsize, _T(" =%X%s"), mwn->val, getsizechar (mwn->val_size));
        !          2737:                        if (mwn->modval_written)
        !          2738:                                buf = buf_out (buf, &bufsize, _T(" =M"));
        !          2739:                        if (mwn->mustchange)
        !          2740:                                buf = buf_out (buf, &bufsize, _T(" C"));
        !          2741:                        for (int j = 0; memwatch_access_masks[j].mask; j++) {
        !          2742:                                uae_u32 mask = memwatch_access_masks[j].mask;
        !          2743:                                if ((mwn->access_mask & mask) == mask && (usedmask & mask) == 0) {
        !          2744:                                        buf = buf_out(buf, &bufsize, _T(" "));
        !          2745:                                        buf = buf_out(buf, &bufsize, memwatch_access_masks[j].name);
        !          2746:                                        usedmask |= mask;
        !          2747:                                }
        !          2748:                        }
        !          2749:                        buf = buf_out (buf, &bufsize, _T("\n"));
        !          2750:                }
        !          2751:        }
        !          2752: }
        !          2753: 
        !          2754: static void memwatch_dump (int num)
        !          2755: {
        !          2756:        TCHAR *buf;
        !          2757:        int multiplier = num < 0 ? MEMWATCH_TOTAL : 1;
        !          2758: 
        !          2759:        buf = xmalloc (TCHAR, 50 * multiplier);
        !          2760:        if (!buf)
        !          2761:                return;
        !          2762:        memwatch_dump2 (buf, 50 * multiplier, num);
        !          2763:        f_out (stdout, _T("%s"), buf);
        !          2764:        xfree (buf);
        !          2765: }
        !          2766: 
        !          2767: static void memwatch (TCHAR **c)
        !          2768: {
        !          2769:        int num;
        !          2770:        struct memwatch_node *mwn;
        !          2771:        TCHAR nc, *cp;
        !          2772: 
        !          2773:        if (!memwatch_enabled) {
        !          2774:                initialize_memwatch (0);
        !          2775:                console_out (_T("Memwatch breakpoints enabled\n"));
        !          2776:        }
        !          2777: 
        !          2778:        cp = *c;
        !          2779:        ignore_ws (c);
        !          2780:        if (!more_params (c)) {
        !          2781:                memwatch_dump (-1);
        !          2782:                return;
        !          2783:        }
        !          2784:        nc = next_char (c);
        !          2785:        if (nc == '-') {
        !          2786:                deinitialize_memwatch ();
        !          2787:                console_out (_T("Memwatch breakpoints disabled\n"));
        !          2788:                return;
        !          2789:        }
        !          2790:        if (nc == 'd') {
        !          2791:                if (illgdebug) {
        !          2792:                        ignore_ws (c);
        !          2793:                        if (more_params (c)) {
        !          2794:                                uae_u32 addr = readhex (c);
        !          2795:                                uae_u32 len = 1;
        !          2796:                                if (more_params (c))
        !          2797:                                        len = readhex (c);
        !          2798:                                console_out_f (_T("Cleared logging addresses %08X - %08X\n"), addr, addr + len);
        !          2799:                                while (len > 0) {
        !          2800:                                        addr &= 0xffffff;
        !          2801:                                        illgdebug[addr] = 7;
        !          2802:                                        addr++;
        !          2803:                                        len--;
        !          2804:                                }
        !          2805:                        } else {
        !          2806:                                illg_free();
        !          2807:                                console_out (_T("Illegal memory access logging disabled\n"));
        !          2808:                        }
        !          2809:                } else {
        !          2810:                        illg_init ();
        !          2811:                        ignore_ws (c);
        !          2812:                        illgdebug_break = 0;
        !          2813:                        if (more_params (c))
        !          2814:                                illgdebug_break = 1;
        !          2815:                        console_out_f (_T("Illegal memory access logging enabled. Break=%d\n"), illgdebug_break);
        !          2816:                }
        !          2817:                return;
        !          2818:        }
        !          2819:        *c = cp;
        !          2820:        num = readint (c);
        !          2821:        if (num < 0 || num >= MEMWATCH_TOTAL)
        !          2822:                return;
        !          2823:        mwn = &mwnodes[num];
        !          2824:        mwn->size = 0;
        !          2825:        ignore_ws (c);
        !          2826:        if (!more_params (c)) {
        !          2827:                console_out_f (_T("Memwatch %d removed\n"), num);
        !          2828:                memwatch_setup ();
        !          2829:                return;
        !          2830:        }
        !          2831:        mwn->addr = readhex (c);
        !          2832:        mwn->size = 1;
        !          2833:        mwn->rwi = 7;
        !          2834:        mwn->val_enabled = 0;
        !          2835:        mwn->val_mask = 0xffffffff;
        !          2836:        mwn->val = 0;
        !          2837:        mwn->access_mask = 0;
        !          2838:        mwn->reg = 0xffffffff;
        !          2839:        mwn->frozen = 0;
        !          2840:        mwn->modval_written = 0;
        !          2841:        ignore_ws (c);
        !          2842:        if (more_params (c)) {
        !          2843:                mwn->size = readhex (c);
        !          2844:                ignore_ws (c);
        !          2845:                if (more_params (c)) {
        !          2846:                        TCHAR *cs = *c;
        !          2847:                        while (*cs) {
        !          2848:                                for (int i = 0; memwatch_access_masks[i].mask; i++) {
        !          2849:                                        const TCHAR *n = memwatch_access_masks[i].name;
        !          2850:                                        int len = _tcslen(n);
        !          2851:                                        if (!_tcsnicmp(cs, n, len)) {
        !          2852:                                                if (cs[len] == 0 || cs[len] == 10 || cs[len] == 13) {
        !          2853:                                                        mwn->access_mask |= memwatch_access_masks[i].mask;
        !          2854:                                                        while (len > 0) {
        !          2855:                                                                len--;
        !          2856:                                                                cs[len] = ' ';
        !          2857:                                                        }
        !          2858:                                                }
        !          2859:                                        }
        !          2860:                                }
        !          2861:                                cs++;
        !          2862:                        }
        !          2863:                        ignore_ws (c);
        !          2864:                        if (more_params(c)) {
        !          2865:                                for (;;) {
        !          2866:                                        TCHAR ncc = peek_next_char(c);
        !          2867:                                        TCHAR nc = _totupper (next_char (c));
        !          2868:                                        if (mwn->rwi == 7)
        !          2869:                                                mwn->rwi = 0;
        !          2870:                                        if (nc == 'F')
        !          2871:                                                mwn->frozen = 1;
        !          2872:                                        if (nc == 'W')
        !          2873:                                                mwn->rwi |= 2;
        !          2874:                                        if (nc == 'I')
        !          2875:                                                mwn->rwi |= 4;
        !          2876:                                        if (nc == 'R')
        !          2877:                                                mwn->rwi |= 1;
        !          2878:                                        if (ncc == ' ')
        !          2879:                                                break;
        !          2880:                                        if (!more_params(c))
        !          2881:                                                break;
        !          2882:                                }
        !          2883:                                ignore_ws (c);
        !          2884:                        }
        !          2885:                        if (more_params (c)) {
        !          2886:                                if (_totupper (**c) == 'M') {
        !          2887:                                        mwn->modval_written = 1;
        !          2888:                                } else if (_totupper (**c) == 'C') {
        !          2889:                                        mwn->mustchange = 1;
        !          2890:                                } else {
        !          2891:                                        mwn->val = readhex (c, &mwn->val_size);
        !          2892:                                        mwn->val_enabled = 1;
        !          2893:                                }
        !          2894:                        }
        !          2895:                }
        !          2896:        }
        !          2897:        if (!mwn->access_mask)
        !          2898:                mwn->access_mask = MW_MASK_CPU;
        !          2899:        if (mwn->frozen && mwn->rwi == 0)
        !          2900:                mwn->rwi = 3;
        !          2901:        memwatch_setup ();
        !          2902:        memwatch_dump (num);
        !          2903: }
        !          2904: 
        !          2905: static void writeintomem (TCHAR **c)
        !          2906: {
        !          2907:        uae_u32 addr = 0;
        !          2908:        uae_u32 val = 0;
        !          2909:        TCHAR cc;
        !          2910:        int len = 1;
        !          2911: 
        !          2912:        ignore_ws(c);
        !          2913:        addr = readhex (c);
        !          2914: 
        !          2915:        ignore_ws (c);
        !          2916:        if (!more_params (c))
        !          2917:                return;
        !          2918:        cc = peekchar (c);
        !          2919:        if (cc == '\'' || cc == '\"') {
        !          2920:                next_char (c);
        !          2921:                while (more_params (c)) {
        !          2922:                        TCHAR str[2];
        !          2923:                        char *astr;
        !          2924:                        cc = next_char (c);
        !          2925:                        if (cc == '\'' || cc == '\"')
        !          2926:                                break;
        !          2927:                        str[0] = cc;
        !          2928:                        str[1] = 0;
        !          2929:                        astr = ua (str);
        !          2930:                        put_byte (addr, astr[0]);
        !          2931:                        xfree (astr);
        !          2932:                        addr++;
        !          2933:                }
        !          2934:        } else {
        !          2935:                for (;;) {
        !          2936:                        ignore_ws (c);
        !          2937:                        if (!more_params (c))
        !          2938:                                break;
        !          2939:                        val = readhex (c, &len);
        !          2940:                
        !          2941:                        if (len == 4) {
        !          2942:                                put_long (addr, val);
        !          2943:                                cc = 'L';
        !          2944:                        } else if (len == 2) {
        !          2945:                                put_word (addr, val);
        !          2946:                                cc = 'W';
        !          2947:                        } else if (len == 1) {
        !          2948:                                put_byte (addr, val);
        !          2949:                                cc = 'B';
        !          2950:                        } else {
        !          2951:                                break;
        !          2952:                        }
        !          2953:                        console_out_f (_T("Wrote %X (%u) at %08X.%c\n"), val, val, addr, cc);
        !          2954:                        addr += len;
        !          2955:                }
        !          2956:        }
        !          2957: }
        !          2958: 
        !          2959: static uae_u8 *dump_xlate (uae_u32 addr)
        !          2960: {
        !          2961:        if (!mem_banks[addr >> 16]->check (addr, 1))
        !          2962:                return NULL;
        !          2963:        return mem_banks[addr >> 16]->xlateaddr (addr);
        !          2964: }
        !          2965: 
        !          2966: #if 0
        !          2967: #define UAE_MEMORY_REGIONS_MAX 64
        !          2968: #define UAE_MEMORY_REGION_NAME_LENGTH 64
        !          2969: 
        !          2970: #define UAE_MEMORY_REGION_RAM (1 << 0)
        !          2971: #define UAE_MEMORY_REGION_ALIAS (1 << 1)
        !          2972: #define UAE_MEMORY_REGION_MIRROR (1 << 2)
        !          2973: 
        !          2974: typedef struct UaeMemoryRegion {
        !          2975:        uaecptr start;
        !          2976:        int size;
        !          2977:        TCHAR name[UAE_MEMORY_REGION_NAME_LENGTH];
        !          2978:        TCHAR rom_name[UAE_MEMORY_REGION_NAME_LENGTH];
        !          2979:        uaecptr alias;
        !          2980:        int flags;
        !          2981: } UaeMemoryRegion;
        !          2982: 
        !          2983: typedef struct UaeMemoryMap {
        !          2984:        UaeMemoryRegion regions[UAE_MEMORY_REGIONS_MAX];
        !          2985:        int num_regions;
        !          2986: } UaeMemoryMap;
        !          2987: #endif
        !          2988: 
        !          2989: static void memory_map_dump_3(UaeMemoryMap *map, int log)
        !          2990: {
        !          2991:        bool imold;
        !          2992:        int i, j, max;
        !          2993:        addrbank *a1 = mem_banks[0];
        !          2994:        TCHAR txt[256];
        !          2995: 
        !          2996:        map->num_regions = 0;
        !          2997:        imold = currprefs.illegal_mem;
        !          2998:        currprefs.illegal_mem = false;
        !          2999:        max = currprefs.address_space_24 ? 256 : 65536;
        !          3000:        j = 0;
        !          3001:        for (i = 0; i < max + 1; i++) {
        !          3002:                addrbank *a2 = NULL;
        !          3003:                if (i < max)
        !          3004:                        a2 = mem_banks[i];
        !          3005:                if (a1 != a2) {
        !          3006:                        int k, mirrored, mirrored2, size, size_out;
        !          3007:                        TCHAR size_ext;
        !          3008:                        uae_u8 *caddr;
        !          3009:                        TCHAR tmp[MAX_DPATH];
        !          3010:                        const TCHAR *name = a1->name;
        !          3011:                        struct addrbank_sub *sb = a1->sub_banks;
        !          3012:                        int bankoffset = 0;
        !          3013:                        int region_size;
        !          3014: 
        !          3015:                        k = j;
        !          3016:                        caddr = dump_xlate (k << 16);
        !          3017:                        mirrored = caddr ? 1 : 0;
        !          3018:                        k++;
        !          3019:                        while (k < i && caddr) {
        !          3020:                                if (dump_xlate (k << 16) == caddr)
        !          3021:                                        mirrored++;
        !          3022:                                k++;
        !          3023:                        }
        !          3024:                        mirrored2 = mirrored;
        !          3025:                        if (mirrored2 == 0)
        !          3026:                                mirrored2 = 1;
        !          3027: 
        !          3028:                        while (bankoffset < 65536) {
        !          3029:                                int bankoffset2 = bankoffset;
        !          3030:                                if (sb) {
        !          3031:                                        uaecptr daddr;
        !          3032:                                        if (!sb->bank)
        !          3033:                                                break;
        !          3034:                                        daddr = (j << 16) | bankoffset;
        !          3035:                                        a1 = get_sub_bank(&daddr);
        !          3036:                                        name = a1->name;
        !          3037:                                        for (;;) {
        !          3038:                                                bankoffset2 += MEMORY_MIN_SUBBANK;
        !          3039:                                                if (bankoffset2 >= 65536)
        !          3040:                                                        break;
        !          3041:                                                daddr = (j << 16) | bankoffset2;
        !          3042:                                                addrbank *dab = get_sub_bank(&daddr);
        !          3043:                                                if (dab != a1)
        !          3044:                                                        break;
        !          3045:                                        }
        !          3046:                                        sb++;
        !          3047:                                        size = (bankoffset2 - bankoffset) / 1024;
        !          3048:                                        region_size = size * 1024;
        !          3049:                                } else {
        !          3050:                                        size = (i - j) << (16 - 10);
        !          3051:                                        region_size = ((i - j) << 16) / mirrored2;
        !          3052:                                }
        !          3053: 
        !          3054:                                if (name == NULL)
        !          3055:                                        name = _T("<none>");
        !          3056: 
        !          3057:                                size_out = size;
        !          3058:                                size_ext = 'K';
        !          3059:                                if (j >= 256 && (size_out / mirrored2 >= 1024) && !((size_out / mirrored2) & 1023)) {
        !          3060:                                        size_out /= 1024;
        !          3061:                                        size_ext = 'M';
        !          3062:                                }
        !          3063: #if 1
        !          3064:                                _stprintf (txt, _T("%08X %7d%c/%d = %7d%c %s"), (j << 16) | bankoffset, size_out, size_ext,
        !          3065:                                        mirrored, mirrored ? size_out / mirrored : size_out, size_ext, name);
        !          3066: #endif
        !          3067:                                tmp[0] = 0;
        !          3068:                                if ((a1->flags & ABFLAG_ROM) && mirrored) {
        !          3069:                                        TCHAR *p = txt + _tcslen (txt);
        !          3070:                                        uae_u32 crc = 0xffffffff;
        !          3071:                                        if (a1->check(((j << 16) | bankoffset), (size * 1024) / mirrored))
        !          3072:                                                crc = get_crc32 (a1->xlateaddr((j << 16) | bankoffset), (size * 1024) / mirrored);
        !          3073:                                        struct romdata *rd = getromdatabycrc (crc);
        !          3074:                                        _stprintf (p, _T(" (%08X)"), crc);
        !          3075:                                        if (rd) {
        !          3076:                                                tmp[0] = '=';
        !          3077:                                                getromname (rd, tmp + 1);
        !          3078:                                                _tcscat (tmp, _T("\n"));
        !          3079:                                        }
        !          3080:                                }
        !          3081: 
        !          3082:                                if (a1 != &dummy_bank) {
        !          3083:                                        for (int m = 0; m < mirrored2; m++) {
        !          3084:                                                UaeMemoryRegion *r = &map->regions[map->num_regions];
        !          3085:                                                r->start = (j << 16) + bankoffset + region_size * m;
        !          3086:                                                r->size = region_size;
        !          3087:                                                r->flags = 0;
        !          3088:                                                r->memory = NULL;
        !          3089:                                                r->memory = dump_xlate((j << 16) | bankoffset);
        !          3090:                                                if (r->memory)
        !          3091:                                                        r->flags |= UAE_MEMORY_REGION_RAM;
        !          3092:                                                /* just to make it easier to spot in debugger */
        !          3093:                                                r->alias = 0xffffffff;
        !          3094:                                                if (m >= 0) {
        !          3095:                                                        r->alias = j << 16;
        !          3096:                                                        r->flags |= UAE_MEMORY_REGION_ALIAS | UAE_MEMORY_REGION_MIRROR;
        !          3097:                                                }
        !          3098:                                                _stprintf(r->name, _T("%s"), name);
        !          3099:                                                _stprintf(r->rom_name, _T("%s"), tmp);
        !          3100:                                                map->num_regions += 1;
        !          3101:                                        }
        !          3102:                                }
        !          3103: 
        !          3104: #if 1
        !          3105:                                _tcscat (txt, _T("\n"));
        !          3106:                                if (log > 0)
        !          3107:                                        write_log (txt);
        !          3108:                                else if (log == 0)
        !          3109:                                        console_out (txt);
        !          3110:                                if (tmp[0]) {
        !          3111:                                        if (log > 0)
        !          3112:                                                write_log (tmp);
        !          3113:                                        else if (log == 0)
        !          3114:                                                console_out (tmp);
        !          3115:                                }
        !          3116: #endif
        !          3117:                                if (!sb)
        !          3118:                                        break;
        !          3119:                                bankoffset = bankoffset2;
        !          3120:                        }
        !          3121:                        j = i;
        !          3122:                        a1 = a2;
        !          3123:                }
        !          3124:        }
        !          3125:        currprefs.illegal_mem = imold;
        !          3126: }
        !          3127: 
        !          3128: void uae_memory_map(UaeMemoryMap *map)
        !          3129: {
        !          3130:        memory_map_dump_3(map, -1);
        !          3131: }
        !          3132: 
        !          3133: static void memory_map_dump_2 (int log)
        !          3134: {
        !          3135:        UaeMemoryMap map;
        !          3136:        memory_map_dump_3(&map, log);
        !          3137: #if 0
        !          3138:        for (int i = 0; i < map.num_regions; i++) {
        !          3139:                TCHAR txt[256];
        !          3140:                UaeMemoryRegion *r = &map.regions[i];
        !          3141:                int size = r->size / 1024;
        !          3142:                TCHAR size_ext = 'K';
        !          3143:                int mirrored = 1;
        !          3144:                int size_out = 0;
        !          3145:                _stprintf (txt, _T("%08X %7u%c/%d = %7u%c %s\n"), r->start, size, size_ext,
        !          3146:                        r->flags & UAE_MEMORY_REGION_RAM, size, size_ext, r->name);
        !          3147:                if (log)
        !          3148:                        write_log (_T("%s"), txt);
        !          3149:                else
        !          3150:                        console_out (txt);
        !          3151:                if (r->rom_name[0]) {
        !          3152:                        if (log)
        !          3153:                                write_log (_T("%s"), r->rom_name);
        !          3154:                        else
        !          3155:                                console_out (r->rom_name);
        !          3156:                }
        !          3157:        }
        !          3158: #endif
        !          3159: }
        !          3160: 
        !          3161: void memory_map_dump (void)
        !          3162:  {
        !          3163:        memory_map_dump_2 (1);
        !          3164: }
        !          3165: 
        !          3166: STATIC_INLINE uaecptr BPTR2APTR (uaecptr addr)
        !          3167: {
        !          3168:        return addr << 2;
        !          3169: }
        !          3170: static TCHAR *BSTR2CSTR (uae_u8 *bstr)
        !          3171: {
        !          3172:        TCHAR *s;
        !          3173:        char *cstr = xmalloc (char, bstr[0] + 1);
        !          3174:        if (cstr) {
        !          3175:                memcpy (cstr, bstr + 1, bstr[0]);
        !          3176:                cstr[bstr[0]] = 0;
        !          3177:        }
        !          3178:        s = au (cstr);
        !          3179:        xfree (cstr);
        !          3180:        return s;
        !          3181: }
        !          3182: 
        !          3183: static void print_task_info (uaecptr node, bool nonactive)
        !          3184: {
        !          3185:        TCHAR *s;
        !          3186:        int process = get_byte_debug (node + 8) == 13 ? 1 : 0;
        !          3187: 
        !          3188:        console_out_f (_T("%08X: "), node);
        !          3189:        s = au ((char*)get_real_address (get_long_debug (node + 10)));
        !          3190:        console_out_f (process ? _T("PROCESS '%s'\n") : _T("TASK    '%s'\n"), s);
        !          3191:        xfree (s);
        !          3192:        if (process) {
        !          3193:                uaecptr cli = BPTR2APTR (get_long_debug (node + 172));
        !          3194:                int tasknum = get_long_debug (node + 140);
        !          3195:                if (cli && tasknum) {
        !          3196:                        uae_u8 *command_bstr = get_real_address (BPTR2APTR (get_long_debug (cli + 16)));
        !          3197:                        TCHAR *command = BSTR2CSTR (command_bstr);
        !          3198:                        console_out_f (_T(" [%d, '%s']\n"), tasknum, command);
        !          3199:                        xfree (command);
        !          3200:                } else {
        !          3201:                        console_out (_T("\n"));
        !          3202:                }
        !          3203:        }
        !          3204:        if (nonactive) {
        !          3205:                uae_u32 sigwait = get_long_debug(node + 22);
        !          3206:                if (sigwait)
        !          3207:                        console_out_f(_T("          Waiting signals: %08x\n"), sigwait);
        !          3208:                uae_u32 sp = get_long_debug(node + 54) + 70;
        !          3209:                uae_u32 pc = get_long_debug(sp);
        !          3210:                console_out_f(_T("          SP: %08x PC: %08x\n"), sp, pc);
        !          3211:        }
        !          3212: }
        !          3213: 
        !          3214: static void show_exec_tasks (void)
        !          3215: {
        !          3216:        uaecptr execbase = get_long_debug (4);
        !          3217:        uaecptr taskready = execbase + 406;
        !          3218:        uaecptr taskwait = execbase + 420;
        !          3219:        uaecptr node;
        !          3220:        console_out_f (_T("Execbase at 0x%08X\n"), execbase);
        !          3221:        console_out (_T("Current:\n"));
        !          3222:        node = get_long_debug (execbase + 276);
        !          3223:        print_task_info (node, false);
        !          3224:        console_out_f (_T("Ready:\n"));
        !          3225:        node = get_long_debug (taskready);
        !          3226:        while (node && get_long_debug(node)) {
        !          3227:                print_task_info (node, true);
        !          3228:                node = get_long_debug (node);
        !          3229:        }
        !          3230:        console_out (_T("Waiting:\n"));
        !          3231:        node = get_long_debug (taskwait);
        !          3232:        while (node && get_long_debug(node)) {
        !          3233:                print_task_info (node, true);
        !          3234:                node = get_long_debug (node);
        !          3235:        }
        !          3236: }
        !          3237: 
        !          3238: static uaecptr get_base (const uae_char *name, int offset)
        !          3239: {
        !          3240:        uaecptr v = get_long_debug (4);
        !          3241:        addrbank *b = &get_mem_bank(v);
        !          3242: 
        !          3243:        if (!b || !b->check (v, 400) || !(b->flags & ABFLAG_RAM))
        !          3244:                return 0;
        !          3245:        v += offset;
        !          3246:        while (v = get_long_debug (v)) {
        !          3247:                uae_u32 v2;
        !          3248:                uae_u8 *p;
        !          3249:                b = &get_mem_bank (v);
        !          3250:                if (!b || !b->check (v, 32) || (!(b->flags & ABFLAG_RAM) && !(b->flags & ABFLAG_ROMIN)))
        !          3251:                        goto fail;
        !          3252:                v2 = get_long_debug (v + 10); // name
        !          3253:                b = &get_mem_bank (v2);
        !          3254:                if (!b || !b->check (v2, 20))
        !          3255:                        goto fail;
        !          3256:                if ((b->flags & ABFLAG_ROM) || (b->flags & ABFLAG_RAM) || (b->flags & ABFLAG_ROMIN)) {
        !          3257:                        p = b->xlateaddr (v2);
        !          3258:                        if (!memcmp (p, name, strlen (name) + 1))
        !          3259:                                return v;
        !          3260:                }
        !          3261:        }
        !          3262:        return 0;
        !          3263: fail:
        !          3264:        return 0xffffffff;
        !          3265: }
        !          3266: 
        !          3267: static TCHAR *getfrombstr(uaecptr pp)
        !          3268: {
        !          3269:        uae_u8 *p = get_real_address ((uaecptr)(pp << 2));
        !          3270:        TCHAR *s = xmalloc (TCHAR, p[0] + 1);
        !          3271:        return au_copy (s, p[0] + 1, (char*)p + 1);
        !          3272: }
        !          3273: 
        !          3274: // read one byte from expansion autoconfig ROM
        !          3275: static void copyromdata(uae_u8 bustype, uaecptr rom, int offset, uae_u8 *out, int size)
        !          3276: {
        !          3277:        switch (bustype & 0xc0)
        !          3278:        {
        !          3279:        case 0x00: // nibble
        !          3280:                while (size-- > 0) {
        !          3281:                        *out++ = (get_byte_debug(rom + offset * 4 + 0) & 0xf0) | ((get_byte_debug(rom + offset * 4 + 2) & 0xf0) >> 4);
        !          3282:                        offset++;
        !          3283:                }
        !          3284:                break;
        !          3285:        case 0x40: // byte
        !          3286:                while (size-- > 0) {
        !          3287:                        *out++ = get_byte_debug(rom + offset * 2);
        !          3288:                        offset++;
        !          3289:                }
        !          3290:                break;
        !          3291:        case 0x80: // word
        !          3292:        default:
        !          3293:                while (size-- > 0) {
        !          3294:                        *out++ = get_byte_debug(rom + offset);
        !          3295:                        offset++;
        !          3296:                }
        !          3297:                break;
        !          3298:        }
        !          3299: }
        !          3300: 
        !          3301: static void show_exec_lists (TCHAR *t)
        !          3302: {
        !          3303:        uaecptr execbase = get_long_debug (4);
        !          3304:        uaecptr list = 0, node;
        !          3305:        TCHAR c = t[0];
        !          3306:        TCHAR c2 = t[1];
        !          3307: 
        !          3308:        if (c == 'o' || c == 'O') { // doslist
        !          3309:                uaecptr dosbase = get_base ("dos.library", 378);
        !          3310:                if (dosbase) {
        !          3311:                        uaecptr rootnode = get_long_debug (dosbase + 34);
        !          3312:                        uaecptr dosinfo = get_long_debug (rootnode + 24) << 2;
        !          3313:                        console_out_f (_T("ROOTNODE: %08x DOSINFO: %08x\n"), rootnode, dosinfo);
        !          3314:                        uaecptr doslist = get_long_debug (dosinfo + 4) << 2;
        !          3315:                        while (doslist) {
        !          3316:                                int type = get_long_debug (doslist + 4);
        !          3317:                                uaecptr msgport = get_long_debug (doslist + 8);
        !          3318:                                TCHAR *name = getfrombstr (get_long_debug (doslist + 40));
        !          3319:                                console_out_f (_T("%08x: %d %08x '%s'\n"), doslist, type, msgport, name);
        !          3320:                                if (type == 0) {
        !          3321:                                        uaecptr fssm = get_long_debug(doslist + 28) << 2;
        !          3322:                                        console_out_f (_T(" - H=%08x Stack=%5d Pri=%2d Start=%08x Seg=%08x GV=%08x\n"),
        !          3323:                                                get_long_debug (doslist + 16) << 2, get_long_debug (doslist + 20),
        !          3324:                                                get_long_debug (doslist + 24), fssm,
        !          3325:                                                get_long_debug (doslist + 32) << 2, get_long_debug (doslist + 36));
        !          3326:                                        if (fssm >= 0x100 && (fssm & 3) == 0) {
        !          3327:                                                TCHAR *unitname = getfrombstr(get_long_debug(fssm + 4));
        !          3328:                                                console_out_f (_T("   %s:%d %08x\n"), unitname, get_long_debug(fssm), get_long_debug(fssm + 8));
        !          3329:                                                uaecptr de = get_long_debug(fssm + 8) << 2;
        !          3330:                                                if (de) {
        !          3331:                                                        console_out_f (_T("    TableSize       %u\n"), get_long_debug(de + 0));
        !          3332:                                                        console_out_f (_T("    SizeBlock       %u\n"), get_long_debug(de + 4));
        !          3333:                                                        console_out_f (_T("    SecOrg          %u\n"), get_long_debug(de + 8));
        !          3334:                                                        console_out_f (_T("    Surfaces        %u\n"), get_long_debug(de + 12));
        !          3335:                                                        console_out_f (_T("    SectorPerBlock  %u\n"), get_long_debug(de + 16));
        !          3336:                                                        console_out_f (_T("    BlocksPerTrack  %u\n"), get_long_debug(de + 20));
        !          3337:                                                        console_out_f (_T("    Reserved        %u\n"), get_long_debug(de + 24));
        !          3338:                                                        console_out_f (_T("    PreAlloc        %u\n"), get_long_debug(de + 28));
        !          3339:                                                        console_out_f (_T("    Interleave      %u\n"), get_long_debug(de + 32));
        !          3340:                                                        console_out_f (_T("    LowCyl          %u\n"), get_long_debug(de + 36));
        !          3341:                                                        console_out_f (_T("    HighCyl         %u (Total %u)\n"), get_long_debug(de + 40), get_long_debug(de + 40) - get_long_debug(de + 36) + 1);
        !          3342:                                                        console_out_f (_T("    NumBuffers      %u\n"), get_long_debug(de + 44));
        !          3343:                                                        console_out_f (_T("    BufMemType      0x%08x\n"), get_long_debug(de + 48));
        !          3344:                                                        console_out_f (_T("    MaxTransfer     0x%08x\n"), get_long_debug(de + 52));
        !          3345:                                                        console_out_f (_T("    Mask            0x%08x\n"), get_long_debug(de + 56));
        !          3346:                                                        console_out_f (_T("    BootPri         %d\n"), get_long_debug(de + 60));
        !          3347:                                                        console_out_f (_T("    DosType         0x%08x\n"), get_long_debug(de + 64));
        !          3348:                                                }
        !          3349:                                                xfree(unitname);
        !          3350:                                        }
        !          3351:                                }
        !          3352:                                xfree (name);
        !          3353:                                doslist = get_long_debug (doslist) << 2;
        !          3354:                        }
        !          3355:                } else {
        !          3356:                        console_out_f (_T("can't find dos.library\n"));
        !          3357:                }
        !          3358:                return;
        !          3359:        } else if (c == 'i' || c == 'I') { // interrupts
        !          3360:                static const int it[] = {  1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0 };
        !          3361:                static const int it2[] = { 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7 };
        !          3362:                list = execbase + 84;
        !          3363:                for (int i = 0; i < 16; i++) {
        !          3364:                        console_out_f (_T("%2d %d: %08x\n"), i + 1, it2[i], list);
        !          3365:                        if (it[i]) {
        !          3366:                                console_out_f (_T("  [H] %08x\n"), get_long_debug (list));
        !          3367:                                node = get_long_debug (list + 8);
        !          3368:                                if (node) {
        !          3369:                                        uae_u8 *addr = get_real_address (get_long_debug (node + 10));
        !          3370:                                        TCHAR *name = addr ? au ((char*)addr) : au("<null>");
        !          3371:                                        console_out_f (_T("      %08x (C=%08X D=%08X) '%s'\n"), node, get_long_debug (list + 4), get_long_debug (list), name);
        !          3372:                                        xfree (name);
        !          3373:                                }
        !          3374:                        } else {
        !          3375:                                int cnt = 0;
        !          3376:                                node = get_long_debug (list);
        !          3377:                                node = get_long_debug (node);
        !          3378:                                while (get_long_debug (node)) {
        !          3379:                                        uae_u8 *addr = get_real_address (get_long_debug (node + 10));
        !          3380:                                        TCHAR *name = addr ? au ((char*)addr) : au("<null>");
        !          3381:                                        console_out_f (_T("  [S] %08x (C=%08x D=%08X) '%s'\n"), node, get_long_debug (node + 18), get_long_debug (node + 14), name);
        !          3382:                                        if (i == 4 - 1 || i == 14 - 1) {
        !          3383:                                                if (!_tcsicmp (name, _T("cia-a")) || !_tcsicmp (name, _T("cia-b"))) {
        !          3384:                                                        static const TCHAR *ciai[] = { _T("A"), _T("B"), _T("ALRM"), _T("SP"), _T("FLG") };
        !          3385:                                                        uaecptr cia = node + 22;
        !          3386:                                                        for (int j = 0; j < 5; j++) {
        !          3387:                                                                uaecptr ciap = get_long_debug (cia);
        !          3388:                                                                console_out_f (_T("        %5s: %08x"), ciai[j], ciap);
        !          3389:                                                                if (ciap) {
        !          3390:                                                                        uae_u8 *addr2 = get_real_address (get_long_debug (ciap + 10));
        !          3391:                                                                        TCHAR *name2 = addr ? au ((char*)addr2) : au("<null>");
        !          3392:                                                                        console_out_f (_T(" (C=%08x D=%08X) '%s'"), get_long_debug (ciap + 18), get_long_debug (ciap + 14), name2);
        !          3393:                                                                        xfree (name2);
        !          3394:                                                                }
        !          3395:                                                                console_out_f (_T("\n"));
        !          3396:                                                                cia += 4;
        !          3397:                                                        }
        !          3398:                                                }
        !          3399:                                        }
        !          3400:                                        xfree (name);
        !          3401:                                        node = get_long_debug (node);
        !          3402:                                        cnt++;
        !          3403:                                }
        !          3404:                                if (!cnt)
        !          3405:                                        console_out_f (_T("  [S] <none>\n"));
        !          3406:                        }
        !          3407:                        list += 12;
        !          3408:                }
        !          3409:                return;
        !          3410:        } else if (c == 'e') { // expansion
        !          3411:                uaecptr expbase = get_base("expansion.library", 378);
        !          3412:                if (expbase) {
        !          3413:                        list = get_long_debug(expbase + 60);
        !          3414:                        while (list && get_long_debug(list)) {
        !          3415:                                uae_u32 addr = get_long_debug(list + 32);
        !          3416:                                uae_u16 rom_vector = get_word_debug(list + 16 + 10);
        !          3417:                                uae_u8 type = get_byte_debug(list + 16 + 0);
        !          3418:                                console_out_f(_T("%02x %02x %08x %08x %04x %02x %08x %04x (%u/%u)\n"),
        !          3419:                                        type, get_byte_debug(list + 16 + 2),
        !          3420:                                        addr, get_long_debug(list + 36),
        !          3421:                                        get_word_debug(list + 16 + 4), get_byte_debug(list + 16 + 1),
        !          3422:                                        get_long_debug(list + 16 + 6), rom_vector,
        !          3423:                                        get_word_debug(list + 16 + 4), get_byte_debug(list + 16 + 1));
        !          3424:                                if ((type & 0x10)) {
        !          3425:                                        uae_u8 diagarea[256];
        !          3426:                                        uae_u16 nameoffset;
        !          3427:                                        uaecptr rom = addr + rom_vector;
        !          3428:                                        uae_u8 config = get_byte_debug(rom);
        !          3429:                                        copyromdata(config, rom, 0, diagarea, 16);
        !          3430:                                        nameoffset = (diagarea[8] << 8) | diagarea[9];
        !          3431:                                        console_out_f(_T(" %02x %02x Size %04x Diag %04x Boot %04x Name %04x %04x %04x\n"),
        !          3432:                                                diagarea[0], diagarea[1],
        !          3433:                                                (diagarea[2] << 8) | diagarea[3],
        !          3434:                                                (diagarea[4] << 8) | diagarea[5],
        !          3435:                                                (diagarea[6] << 8) | diagarea[7],
        !          3436:                                                nameoffset,
        !          3437:                                                (diagarea[10] << 8) | diagarea[11],
        !          3438:                                                (diagarea[12] << 8) | diagarea[13]);
        !          3439:                                        if (nameoffset != 0 && nameoffset != 0xffff) {
        !          3440:                                                copyromdata(config, rom, nameoffset, diagarea, 256);
        !          3441:                                                diagarea[sizeof diagarea - 1] = 0;
        !          3442:                                                TCHAR *str = au((char*)diagarea);
        !          3443:                                                console_out_f(_T(" '%s'\n"), str);
        !          3444:                                                xfree(str);
        !          3445:                                        }
        !          3446:                                }
        !          3447:                                list = get_long_debug(list);
        !          3448:                        }
        !          3449:                }
        !          3450:        } else if (c == 'R') { // residents
        !          3451:                list = get_long_debug(execbase + 300);
        !          3452:                while (list) {
        !          3453:                        uaecptr resident = get_long_debug (list);
        !          3454:                        if (!resident)
        !          3455:                                break;
        !          3456:                        if (resident & 0x80000000) {
        !          3457:                                console_out_f (_T("-> %08X\n"), resident & 0x7fffffff);
        !          3458:                                list = resident & 0x7fffffff;
        !          3459:                                continue;
        !          3460:                        }
        !          3461:                        uae_u8 *addr;
        !          3462:                        addr = get_real_address (get_long_debug (resident + 14));
        !          3463:                        TCHAR *name1 = addr ? au ((char*)addr) : au("<null>");
        !          3464:                        my_trim (name1);
        !          3465:                        addr = get_real_address (get_long_debug (resident + 18));
        !          3466:                        TCHAR *name2 = addr ? au ((char*)addr) : au("<null>");
        !          3467:                        my_trim (name2);
        !          3468:                        console_out_f (_T("%08X %08X: %02X %3d %02X %+3.3d '%s' ('%s')\n"),
        !          3469:                                list, resident,
        !          3470:                                get_byte_debug (resident + 10), get_byte_debug (resident + 11),
        !          3471:                                get_byte_debug (resident + 12), (uae_s8)get_byte_debug (resident + 13),
        !          3472:                                name1, name2);
        !          3473:                        xfree (name2);
        !          3474:                        xfree (name1);
        !          3475:                        list += 4;
        !          3476:                }
        !          3477:                return;
        !          3478:        } else if (c == 'f' || c== 'F') { // filesystem.resource
        !          3479:                uaecptr fs = get_base ("FileSystem.resource", 336);
        !          3480:                if (fs) {
        !          3481:                        static const TCHAR *fsnames[] = {
        !          3482:                                _T("DosType"),
        !          3483:                                _T("Version"),
        !          3484:                                _T("PatchFlags"),
        !          3485:                                _T("Type"),
        !          3486:                                _T("Task"),
        !          3487:                                _T("Lock"),
        !          3488:                                _T("Handler"),
        !          3489:                                _T("StackSize"),
        !          3490:                                _T("Priority"),
        !          3491:                                _T("Startup"),
        !          3492:                                _T("SegList"),
        !          3493:                                _T("GlobalVec"),
        !          3494:                                NULL
        !          3495:                        };
        !          3496:                        uae_u8 *addr = get_real_address (get_long_debug (fs + 14));
        !          3497:                        TCHAR *name = addr ? au ((char*)addr) : au ("<null>");
        !          3498:                        my_trim (name);
        !          3499:                        console_out_f (_T("%08x: '%s'\n"), fs, name);
        !          3500:                        xfree (name);
        !          3501:                        node = get_long_debug (fs + 18);
        !          3502:                        while (get_long_debug (node)) {
        !          3503:                                TCHAR *name = au ((char*)get_real_address (get_long_debug (node + 10)));
        !          3504:                                my_trim (name);
        !          3505:                                console_out_f (_T("%08x: '%s'\n"), node, name);
        !          3506:                                xfree (name);
        !          3507:                                for (int i = 0; fsnames[i]; i++) {
        !          3508:                                        uae_u32 v = get_long_debug (node + 14 + i * 4);
        !          3509:                                        console_out_f (_T("%16s = %08x %d\n"), fsnames[i], v, v);
        !          3510:                                }
        !          3511:                                console_out_f (_T("\n"));
        !          3512:                                node = get_long_debug (node);
        !          3513:                        }
        !          3514: 
        !          3515:                } else {
        !          3516:                        console_out_f (_T("FileSystem.resource not found.\n"));
        !          3517:                }
        !          3518:                return;
        !          3519:        } else if (c == 'm' || c == 'M') { // memory
        !          3520:                list = execbase + 322;
        !          3521:                node = get_long_debug (list);
        !          3522:                while (get_long_debug (node)) {
        !          3523:                        TCHAR *name = au ((char*)get_real_address (get_long_debug (node + 10)));
        !          3524:                        uae_u16 v = get_word_debug (node + 8);
        !          3525:                        console_out_f (_T("%08x %d %d %s\n"), node, (int)((v >> 8) & 0xff), (uae_s8)(v & 0xff), name);
        !          3526:                        xfree (name);
        !          3527:                        console_out_f (_T("Attributes %04x First %08x Lower %08x Upper %08x Free %d\n"),
        !          3528:                                get_word_debug (node + 14), get_long_debug (node + 16), get_long_debug (node + 20), 
        !          3529:                                get_long_debug (node + 24), get_long_debug (node + 28));
        !          3530:                        uaecptr mc = get_long_debug (node + 16);
        !          3531:                        while (mc) {
        !          3532:                                uae_u32 mc1 = get_long_debug (mc);
        !          3533:                                uae_u32 mc2 = get_long_debug (mc + 4);
        !          3534:                                console_out_f (_T(" %08x: %08x-%08x,%08x,%08x (%d)\n"), mc, mc, mc + mc2, mc1, mc2, mc2);
        !          3535:                                mc = mc1;
        !          3536:                        }
        !          3537:                        console_out_f (_T("\n"));
        !          3538:                        node = get_long_debug (node);
        !          3539:                }
        !          3540:                return;
        !          3541:        }
        !          3542: 
        !          3543:        bool full = false;
        !          3544:        switch (c)
        !          3545:        {
        !          3546:        case 'r': // resources
        !          3547:                list = execbase + 336;
        !          3548:                break;
        !          3549:        case 'd': // devices
        !          3550:                list = execbase + 350;
        !          3551:                full = true;
        !          3552:                break;
        !          3553:        case 'l': // libraries
        !          3554:                list = execbase + 378;
        !          3555:                full = true;
        !          3556:                break;
        !          3557:        case 'p': // ports
        !          3558:                list = execbase + 392;
        !          3559:                break;
        !          3560:        case 's': // semaphores
        !          3561:                list = execbase + 532;
        !          3562:                break;
        !          3563:        }
        !          3564:        if (list == 0)
        !          3565:                return;
        !          3566:        node = get_long_debug (list);
        !          3567:        while (get_long_debug (node)) {
        !          3568:                TCHAR *name = au ((char*)get_real_address (get_long_debug (node + 10)));
        !          3569:                uae_u16 v = get_word_debug (node + 8);
        !          3570:                console_out_f (_T("%08x %d %d"), node, (int)((v >> 8) & 0xff), (uae_s8)(v & 0xff));
        !          3571:                if (full) {
        !          3572:                        uae_u16 ver = get_word_debug(node + 20);
        !          3573:                        uae_u16 rev = get_word_debug(node + 22);
        !          3574:                        uae_u32 op = get_word_debug(node + 32);
        !          3575:                        console_out_f(_T(" %d.%d %d"), ver, rev, op);
        !          3576:                }
        !          3577:                console_out_f(_T(" %s"), name);
        !          3578:                xfree (name);
        !          3579:                if (full) {
        !          3580:                        uaecptr idstring = get_long_debug(node + 24);
        !          3581:                        if (idstring) {
        !          3582:                                name = au((char*)get_real_address(idstring));
        !          3583:                                console_out_f(_T(" (%s)"), name);
        !          3584:                                xfree(name);
        !          3585:                        }
        !          3586:                }
        !          3587:                console_out_f(_T("\n"));
        !          3588:                node = get_long_debug (node);
        !          3589:        }
        !          3590: }
        !          3591: 
        !          3592: static void breakfunc(uae_u32 v)
        !          3593: {
        !          3594:        write_log(_T("Cycle breakpoint hit\n"));
        !          3595:        debugging = 1;
        !          3596:        set_special (SPCFLAG_BRK);
        !          3597: }
        !          3598: 
        !          3599: static int cycle_breakpoint(TCHAR **c)
        !          3600: {
        !          3601:        TCHAR nc = (*c)[0];
        !          3602:        next_char(c);
        !          3603:        if (more_params(c)) {
        !          3604:                int count = readint(c);
        !          3605:                if (nc == 's') {
        !          3606:                        if (more_params(c)) {
        !          3607:                                int hp = readint(c);
        !          3608:                                if (count >= vpos) {
        !          3609:                                        count = vpos - count;
        !          3610:                                } else {
        !          3611:                                        count += maxvpos - vpos;
        !          3612:                                }
        !          3613:                                count *= maxhpos;
        !          3614:                                if (hp >= current_hpos()) {
        !          3615:                                        count += hp - current_hpos();
        !          3616:                                } else {
        !          3617:                                        count += maxhpos - current_hpos();
        !          3618:                                }
        !          3619:                        } else {
        !          3620:                                count *= maxhpos;
        !          3621:                        }
        !          3622:                }
        !          3623:                event2_newevent_x(-1, count, 0, breakfunc);
        !          3624:                return 1;
        !          3625:        }
        !          3626:        return 0;
        !          3627: }
        !          3628: 
        !          3629: #if 0
        !          3630: static int trace_same_insn_count;
        !          3631: static uae_u8 trace_insn_copy[10];
        !          3632: static struct regstruct trace_prev_regs;
        !          3633: #endif
        !          3634: static uaecptr nextpc;
        !          3635: 
        !          3636: int instruction_breakpoint (TCHAR **c)
        !          3637: {
        !          3638:        struct breakpoint_node *bpn;
        !          3639:        int i;
        !          3640: 
        !          3641:        if (more_params (c)) {
        !          3642:                TCHAR nc = _totupper ((*c)[0]);
        !          3643:                if (nc == 'S') {
        !          3644:                        next_char (c);
        !          3645:                        sr_bpvalue = sr_bpmask = 0;
        !          3646:                        if (more_params (c)) {
        !          3647:                                sr_bpmask = 0xffff;
        !          3648:                                sr_bpvalue = readhex (c);
        !          3649:                                if (more_params (c))
        !          3650:                                        sr_bpmask = readhex (c);
        !          3651:                        }
        !          3652:                        console_out_f (_T("SR breakpoint, value=%04X, mask=%04X\n"), sr_bpvalue, sr_bpmask);
        !          3653:                        return 0;
        !          3654:                } else if (nc == 'I') {
        !          3655:                        next_char (c);
        !          3656:                        if (more_params (c))
        !          3657:                                skipins = readhex (c);
        !          3658:                        else
        !          3659:                                skipins = 0x10000;
        !          3660:                        do_skip = 1;
        !          3661:                        skipaddr_doskip = 1;
        !          3662:                        return 1;
        !          3663:                } else if (nc == 'D' && (*c)[1] == 0) {
        !          3664:                        for (i = 0; i < BREAKPOINT_TOTAL; i++)
        !          3665:                                bpnodes[i].enabled = 0;
        !          3666:                        console_out (_T("All breakpoints removed\n"));
        !          3667:                        return 0;
        !          3668:                } else if (nc == 'L') {
        !          3669:                        int got = 0;
        !          3670:                        for (i = 0; i < BREAKPOINT_TOTAL; i++) {
        !          3671:                                bpn = &bpnodes[i];
        !          3672:                                if (!bpn->enabled)
        !          3673:                                        continue;
        !          3674:                                console_out_f (_T("%8X "), bpn->addr);
        !          3675:                                got = 1;
        !          3676:                        }
        !          3677:                        if (!got)
        !          3678:                                console_out (_T("No breakpoints\n"));
        !          3679:                        else
        !          3680:                                console_out (_T("\n"));
        !          3681:                        return 0;
        !          3682:                }
        !          3683:                skipaddr_doskip = 1;
        !          3684:                skipaddr_start = readhex (c);
        !          3685:                if (more_params (c)) {
        !          3686:                        skipaddr_end = readhex (c);
        !          3687:                } else {
        !          3688:                        for (i = 0; i < BREAKPOINT_TOTAL; i++) {
        !          3689:                                bpn = &bpnodes[i];
        !          3690:                                if (bpn->enabled && bpn->addr == skipaddr_start) {
        !          3691:                                        bpn->enabled = 0;
        !          3692:                                        console_out (_T("Breakpoint removed\n"));
        !          3693:                                        skipaddr_start = 0xffffffff;
        !          3694:                                        skipaddr_doskip = 0;
        !          3695:                                        return 0;
        !          3696:                                }
        !          3697:                        }
        !          3698:                        for (i = 0; i < BREAKPOINT_TOTAL; i++) {
        !          3699:                                bpn = &bpnodes[i];
        !          3700:                                if (bpn->enabled)
        !          3701:                                        continue;
        !          3702:                                bpn->addr = skipaddr_start;
        !          3703:                                bpn->enabled = 1;
        !          3704:                                console_out (_T("Breakpoint added\n"));
        !          3705:                                skipaddr_start = 0xffffffff;
        !          3706:                                skipaddr_doskip = 0;
        !          3707:                                break;
        !          3708:                        }
        !          3709:                        return 0;
        !          3710:                }
        !          3711:        }
        !          3712: #if 0
        !          3713:        if (skipaddr_start == 0xC0DEDBAD) {
        !          3714:                trace_same_insn_count = 0;
        !          3715:                logfile = fopen ("uae.trace", "w");
        !          3716:                memcpy (trace_insn_copy, regs.pc_p, 10);
        !          3717:                memcpy (&trace_prev_regs, &regs, sizeof regs);
        !          3718:        }
        !          3719: #endif
        !          3720:        do_skip = 1;
        !          3721:        skipaddr_doskip = -1;
        !          3722:        return 1;
        !          3723: }
        !          3724: 
        !          3725: static int process_breakpoint (TCHAR **c)
        !          3726: {
        !          3727:        processptr = 0;
        !          3728:        xfree (processname);
        !          3729:        processname = NULL;
        !          3730:        if (!more_params (c))
        !          3731:                return 0;
        !          3732:        if (**c == '\"') {
        !          3733:                TCHAR pn[200];
        !          3734:                next_string (c, pn, 200, 0);
        !          3735:                processname = ua (pn);
        !          3736:        } else {
        !          3737:                processptr = readhex (c);
        !          3738:        }
        !          3739:        do_skip = 1;
        !          3740:        skipaddr_doskip = 1;
        !          3741:        skipaddr_start = 0;
        !          3742:        return 1;
        !          3743: }
        !          3744: 
        !          3745: static void savemem (TCHAR **cc)
        !          3746: {
        !          3747:        uae_u8 b;
        !          3748:        uae_u32 src, src2, len, len2;
        !          3749:        TCHAR *name;
        !          3750:        FILE *fp;
        !          3751: 
        !          3752:        if (!more_params (cc))
        !          3753:                goto S_argh;
        !          3754: 
        !          3755:        name = *cc;
        !          3756:        while (**cc != '\0' && !isspace (**cc))
        !          3757:                (*cc)++;
        !          3758:        if (!isspace (**cc))
        !          3759:                goto S_argh;
        !          3760: 
        !          3761:        **cc = '\0';
        !          3762:        (*cc)++;
        !          3763:        if (!more_params (cc))
        !          3764:                goto S_argh;
        !          3765:        src2 = src = readhex (cc);
        !          3766:        if (!more_params (cc))
        !          3767:                goto S_argh;
        !          3768:        len2 = len = readhex (cc);
        !          3769:        fp = _tfopen (name, _T("wb"));
        !          3770:        if (fp == NULL) {
        !          3771:                console_out_f (_T("Couldn't open file '%s'\n"), name);
        !          3772:                return;
        !          3773:        }
        !          3774:        while (len > 0) {
        !          3775:                b = get_byte_debug (src);
        !          3776:                src++;
        !          3777:                len--;
        !          3778:                if (fwrite (&b, 1, 1, fp) != 1) {
        !          3779:                        console_out (_T("Error writing file\n"));
        !          3780:                        break;
        !          3781:                }
        !          3782:        }
        !          3783:        fclose (fp);
        !          3784:        if (len == 0)
        !          3785:                console_out_f (_T("Wrote %08X - %08X (%d bytes) to '%s'\n"),
        !          3786:                src2, src2 + len2, len2, name);
        !          3787:        return;
        !          3788: S_argh:
        !          3789:        console_out (_T("S-command needs more arguments!\n"));
        !          3790: }
        !          3791: 
        !          3792: static void searchmem (TCHAR **cc)
        !          3793: {
        !          3794:        int i, sslen, got, val, stringmode;
        !          3795:        uae_u8 ss[256];
        !          3796:        uae_u32 addr, endaddr;
        !          3797:        TCHAR nc;
        !          3798: 
        !          3799:        got = 0;
        !          3800:        sslen = 0;
        !          3801:        stringmode = 0;
        !          3802:        ignore_ws (cc);
        !          3803:        if (**cc == '"') {
        !          3804:                stringmode = 1;
        !          3805:                (*cc)++;
        !          3806:                while (**cc != '"' && **cc != 0) {
        !          3807:                        ss[sslen++] = tolower (**cc);
        !          3808:                        (*cc)++;
        !          3809:                }
        !          3810:                if (**cc != 0)
        !          3811:                        (*cc)++;
        !          3812:        } else {
        !          3813:                for (;;) {
        !          3814:                        if (**cc == 32 || **cc == 0)
        !          3815:                                break;
        !          3816:                        nc = _totupper (next_char (cc));
        !          3817:                        if (isspace (nc))
        !          3818:                                break;
        !          3819:                        if (isdigit(nc))
        !          3820:                                val = nc - '0';
        !          3821:                        else
        !          3822:                                val = nc - 'A' + 10;
        !          3823:                        if (val < 0 || val > 15)
        !          3824:                                return;
        !          3825:                        val *= 16;
        !          3826:                        if (**cc == 32 || **cc == 0)
        !          3827:                                break;
        !          3828:                        nc = _totupper (next_char (cc));
        !          3829:                        if (isspace (nc))
        !          3830:                                break;
        !          3831:                        if (isdigit(nc))
        !          3832:                                val += nc - '0';
        !          3833:                        else
        !          3834:                                val += nc - 'A' + 10;
        !          3835:                        if (val < 0 || val > 255)
        !          3836:                                return;
        !          3837:                        ss[sslen++] = (uae_u8)val;
        !          3838:                }
        !          3839:        }
        !          3840:        if (sslen == 0)
        !          3841:                return;
        !          3842:        ignore_ws (cc);
        !          3843:        addr = 0;
        !          3844:        endaddr = lastaddr ();
        !          3845:        if (more_params (cc)) {
        !          3846:                addr = readhex (cc);
        !          3847:                if (more_params (cc))
        !          3848:                        endaddr = readhex (cc);
        !          3849:        }
        !          3850:        console_out_f (_T("Searching from %08X to %08X..\n"), addr, endaddr);
        !          3851:        while ((addr = nextaddr (addr, endaddr, NULL)) != 0xffffffff) {
        !          3852:                if (addr == endaddr)
        !          3853:                        break;
        !          3854:                for (i = 0; i < sslen; i++) {
        !          3855:                        uae_u8 b = get_byte_debug (addr + i);
        !          3856:                        if (stringmode) {
        !          3857:                                if (tolower (b) != ss[i])
        !          3858:                                        break;
        !          3859:                        } else {
        !          3860:                                if (b != ss[i])
        !          3861:                                        break;
        !          3862:                        }
        !          3863:                }
        !          3864:                if (i == sslen) {
        !          3865:                        got++;
        !          3866:                        console_out_f (_T(" %08X"), addr);
        !          3867:                        if (got > 100) {
        !          3868:                                console_out (_T("\nMore than 100 results, aborting.."));
        !          3869:                                break;
        !          3870:                        }
        !          3871:                }
        !          3872:                if  (iscancel (65536)) {
        !          3873:                        console_out_f (_T("Aborted at %08X\n"), addr);
        !          3874:                        break;
        !          3875:                }
        !          3876:        }
        !          3877:        if (!got)
        !          3878:                console_out (_T("nothing found"));
        !          3879:        console_out (_T("\n"));
        !          3880: }
        !          3881: 
        !          3882: static int staterecorder (TCHAR **cc)
        !          3883: {
        !          3884: #if 0
        !          3885:        TCHAR nc;
        !          3886: 
        !          3887:        if (!more_params (cc)) {
        !          3888:                if (savestate_dorewind (1)) {
        !          3889:                        debug_rewind = 1;
        !          3890:                        return 1;
        !          3891:                }
        !          3892:                return 0;
        !          3893:        }
        !          3894:        nc = next_char (cc);
        !          3895:        if (nc == 'l') {
        !          3896:                savestate_listrewind ();
        !          3897:                return 0;
        !          3898:        }
        !          3899: #endif
        !          3900:        return 0;
        !          3901: }
        !          3902: 
        !          3903: static int debugtest_modes[DEBUGTEST_MAX];
        !          3904: static const TCHAR *debugtest_names[] = {
        !          3905:        _T("Blitter"), _T("Keyboard"), _T("Floppy")
        !          3906: };
        !          3907: 
        !          3908: void debugtest (enum debugtest_item di, const TCHAR *format, ...)
        !          3909: {
        !          3910:        va_list parms;
        !          3911:        TCHAR buffer[1000];
        !          3912: 
        !          3913:        if (!debugtest_modes[di])
        !          3914:                return;
        !          3915:        va_start (parms, format);
        !          3916:        _vsntprintf (buffer, 1000 - 1, format, parms);
        !          3917:        va_end (parms);
        !          3918:        write_log (_T("%s PC=%08X: %s\n"), debugtest_names[di], M68K_GETPC, buffer);
        !          3919:        if (debugtest_modes[di] == 2)
        !          3920:                activate_debugger ();
        !          3921: }
        !          3922: 
        !          3923: static void debugtest_set (TCHAR **inptr)
        !          3924: {
        !          3925:        int i, val, val2;
        !          3926:        ignore_ws (inptr);
        !          3927: 
        !          3928:        val2 = 1;
        !          3929:        if (!more_params (inptr)) {
        !          3930:                for (i = 0; i < DEBUGTEST_MAX; i++)
        !          3931:                        debugtest_modes[i] = 0;
        !          3932:                console_out (_T("All debugtests disabled\n"));
        !          3933:                return;
        !          3934:        }
        !          3935:        val = readint (inptr);
        !          3936:        if (more_params (inptr)) {
        !          3937:                val2 = readint (inptr);
        !          3938:                if (val2 > 0)
        !          3939:                        val2 = 2;
        !          3940:        }
        !          3941:        if (val < 0) {
        !          3942:                for (i = 0; i < DEBUGTEST_MAX; i++)
        !          3943:                        debugtest_modes[i] = val2;
        !          3944:                console_out (_T("All debugtests enabled\n"));
        !          3945:                return;
        !          3946:        }
        !          3947:        if (val >= 0 && val < DEBUGTEST_MAX) {
        !          3948:                if (debugtest_modes[val])
        !          3949:                        debugtest_modes[val] = 0;
        !          3950:                else
        !          3951:                        debugtest_modes[val] = val2;
        !          3952:                console_out_f (_T("Debugtest '%s': %s. break = %s\n"),
        !          3953:                        debugtest_names[val], debugtest_modes[val] ? _T("on") :_T("off"), val2 == 2 ? _T("on") : _T("off"));
        !          3954:        }
        !          3955: }
        !          3956: 
        !          3957: static void debug_sprite (TCHAR **inptr)
        !          3958: {
        !          3959:        uaecptr saddr, addr, addr2;
        !          3960:        int xpos, xpos_ecs;
        !          3961:        int ypos, ypos_ecs;
        !          3962:        int ypose, ypose_ecs;
        !          3963:        int attach;
        !          3964:        uae_u64 w1, w2, ww1, ww2;
        !          3965:        int size = 1, width;
        !          3966:        int ecs, sh10;
        !          3967:        int y, i;
        !          3968:        TCHAR tmp[80];
        !          3969:        int max = 2;
        !          3970: 
        !          3971:        addr2 = 0;
        !          3972:        ignore_ws (inptr);
        !          3973:        addr = readhex (inptr);
        !          3974:        ignore_ws (inptr);
        !          3975:        if (more_params (inptr))
        !          3976:                size = readhex (inptr);
        !          3977:        if (size != 1 && size != 2 && size != 4) {
        !          3978:                addr2 = size;
        !          3979:                ignore_ws (inptr);
        !          3980:                if (more_params (inptr))
        !          3981:                        size = readint (inptr);
        !          3982:                if (size != 1 && size != 2 && size != 4)
        !          3983:                        size = 1;
        !          3984:        }
        !          3985:        for (;;) {
        !          3986:                ecs = 0;
        !          3987:                sh10 = 0;
        !          3988:                saddr = addr;
        !          3989:                width = size * 16;
        !          3990:                w1 = get_word_debug (addr);
        !          3991:                w2 = get_word_debug (addr + size * 2);
        !          3992:                console_out_f (_T("    %06X "), addr);
        !          3993:                for (i = 0; i < size * 2; i++)
        !          3994:                        console_out_f (_T("%04X "), get_word_debug (addr + i * 2));
        !          3995:                console_out_f (_T("\n"));
        !          3996: 
        !          3997:                ypos = w1 >> 8;
        !          3998:                xpos = w1 & 255;
        !          3999:                ypose = w2 >> 8;
        !          4000:                attach = (w2 & 0x80) ? 1 : 0;
        !          4001:                if (w2 & 4)
        !          4002:                        ypos |= 256;
        !          4003:                if (w2 & 2)
        !          4004:                        ypose |= 256;
        !          4005:                ypos_ecs = ypos;
        !          4006:                ypose_ecs = ypose;
        !          4007:                if (w2 & 0x40)
        !          4008:                        ypos_ecs |= 512;
        !          4009:                if (w2 & 0x20)
        !          4010:                        ypose_ecs |= 512;
        !          4011:                xpos <<= 1;
        !          4012:                if (w2 & 0x01)
        !          4013:                        xpos |= 1;
        !          4014:                xpos_ecs = xpos << 2;
        !          4015:                if (w2 & 0x10)
        !          4016:                        xpos_ecs |= 2;
        !          4017:                if (w2 & 0x08)
        !          4018:                        xpos_ecs |= 1;
        !          4019:                if (w2 & (0x40 | 0x20 | 0x10 | 0x08))
        !          4020:                        ecs = 1;
        !          4021:                if (w1 & 0x80)
        !          4022:                        sh10 = 1;
        !          4023:                if (ypose < ypos)
        !          4024:                        ypose += 256;
        !          4025: 
        !          4026:                for (y = ypos; y < ypose; y++) {
        !          4027:                        int x;
        !          4028:                        addr += size * 4;
        !          4029:                        if (addr2)
        !          4030:                                addr2 += size * 4;
        !          4031:                        if (size == 1) {
        !          4032:                                w1 = get_word_debug (addr);
        !          4033:                                w2 = get_word_debug (addr + 2);
        !          4034:                                if (addr2) {
        !          4035:                                        ww1 = get_word_debug (addr2);
        !          4036:                                        ww2 = get_word_debug (addr2 + 2);
        !          4037:                                }
        !          4038:                        } else if (size == 2) {
        !          4039:                                w1 = get_long_debug (addr);
        !          4040:                                w2 = get_long_debug (addr + 4);
        !          4041:                                if (addr2) {
        !          4042:                                        ww1 = get_long_debug (addr2);
        !          4043:                                        ww2 = get_long_debug (addr2 + 4);
        !          4044:                                }
        !          4045:                        } else if (size == 4) {
        !          4046:                                w1 = get_long_debug (addr + 0);
        !          4047:                                w2 = get_long_debug (addr + 8);
        !          4048:                                w1 <<= 32;
        !          4049:                                w2 <<= 32;
        !          4050:                                w1 |= get_long_debug (addr + 4);
        !          4051:                                w2 |= get_long_debug (addr + 12);
        !          4052:                                if (addr2) {
        !          4053:                                        ww1 = get_long_debug (addr2 + 0);
        !          4054:                                        ww2 = get_long_debug (addr2 + 8);
        !          4055:                                        ww1 <<= 32;
        !          4056:                                        ww2 <<= 32;
        !          4057:                                        ww1 |= get_long_debug (addr2 + 4);
        !          4058:                                        ww2 |= get_long_debug (addr2 + 12);
        !          4059:                                }
        !          4060:                        }
        !          4061:                        width = size * 16;
        !          4062:                        for (x = 0; x < width; x++) {
        !          4063:                                int v1 = w1 & 1;
        !          4064:                                int v2 = w2 & 1;
        !          4065:                                int v = v1 * 2 + v2;
        !          4066:                                w1 >>= 1;
        !          4067:                                w2 >>= 1;
        !          4068:                                if (addr2) {
        !          4069:                                        int vv1 = ww1 & 1;
        !          4070:                                        int vv2 = ww2 & 1;
        !          4071:                                        int vv = vv1 * 2 + vv2;
        !          4072:                                        vv1 >>= 1;
        !          4073:                                        vv2 >>= 1;
        !          4074:                                        v *= 4;
        !          4075:                                        v += vv;
        !          4076:                                        tmp[width - (x + 1)] = v >= 10 ? 'A' + v - 10 : v + '0';
        !          4077:                                } else {
        !          4078:                                        tmp[width - (x + 1)] = v + '0';
        !          4079:                                }
        !          4080:                        }
        !          4081:                        tmp[width] = 0;
        !          4082:                        console_out_f (_T("%3d %06X %s\n"), y, addr, tmp);
        !          4083:                }
        !          4084: 
        !          4085:                console_out_f (_T("Sprite address %08X, width = %d\n"), saddr, size * 16);
        !          4086:                console_out_f (_T("OCS: StartX=%d StartY=%d EndY=%d\n"), xpos, ypos, ypose);
        !          4087:                console_out_f (_T("ECS: StartX=%d (%d.%d) StartY=%d EndY=%d%s\n"), xpos_ecs, xpos_ecs / 4, xpos_ecs & 3, ypos_ecs, ypose_ecs, ecs ? _T(" (*)") : _T(""));
        !          4088:                console_out_f (_T("Attach: %d. AGA SSCAN/SH10 bit: %d\n"), attach, sh10);
        !          4089: 
        !          4090:                addr += size * 4;
        !          4091:                if (get_word_debug (addr) == 0 && get_word_debug (addr + size * 4) == 0)
        !          4092:                        break;
        !          4093:                max--;
        !          4094:                if (max <= 0)
        !          4095:                        break;
        !          4096:        }
        !          4097: 
        !          4098: }
        !          4099: 
        !          4100: int debug_write_memory_16 (uaecptr addr, uae_u16 v)
        !          4101: {
        !          4102:        addrbank *ad;
        !          4103:        
        !          4104:        ad = &get_mem_bank (addr);
        !          4105:        if (ad) {
        !          4106:                ad->wput (addr, v);
        !          4107:                return 1;
        !          4108:        }
        !          4109:        return -1;
        !          4110: }
        !          4111: int debug_write_memory_8 (uaecptr addr, uae_u8 v)
        !          4112: {
        !          4113:        addrbank *ad;
        !          4114:        
        !          4115:        ad = &get_mem_bank (addr);
        !          4116:        if (ad) {
        !          4117:                ad->bput (addr, v);
        !          4118:                return 1;
        !          4119:        }
        !          4120:        return -1;
        !          4121: }
        !          4122: int debug_peek_memory_16 (uaecptr addr)
        !          4123: {
        !          4124:        addrbank *ad;
        !          4125:        
        !          4126:        ad = &get_mem_bank (addr);
        !          4127:        if (ad->flags & (ABFLAG_RAM | ABFLAG_ROM | ABFLAG_ROMIN | ABFLAG_SAFE))
        !          4128:                return ad->wget (addr);
        !          4129:        if (ad == &custom_bank) {
        !          4130:                addr &= 0x1fe;
        !          4131:                return (ar_custom[addr + 0] << 8) | ar_custom[addr + 1];
        !          4132:        }
        !          4133:        return -1;
        !          4134: }
        !          4135: int debug_read_memory_16 (uaecptr addr)
        !          4136: {
        !          4137:        addrbank *ad;
        !          4138:        
        !          4139:        ad = &get_mem_bank (addr);
        !          4140:        if (ad)
        !          4141:                return ad->wget (addr);
        !          4142:        return -1;
        !          4143: }
        !          4144: int debug_read_memory_8 (uaecptr addr)
        !          4145: {
        !          4146:        addrbank *ad;
        !          4147:        
        !          4148:        ad = &get_mem_bank (addr);
        !          4149:        if (ad)
        !          4150:                return ad->bget (addr);
        !          4151:        return -1;
        !          4152: }
        !          4153: 
        !          4154: static void disk_debug (TCHAR **inptr)
        !          4155: {
        !          4156:        TCHAR parm[10];
        !          4157:        int i;
        !          4158: 
        !          4159:        if (**inptr == 'd') {
        !          4160:                (*inptr)++;
        !          4161:                ignore_ws (inptr);
        !          4162:                disk_debug_logging = readint (inptr);
        !          4163:                console_out_f (_T("Disk logging level %d\n"), disk_debug_logging);
        !          4164:                return;
        !          4165:        }
        !          4166:        disk_debug_mode = 0;
        !          4167:        disk_debug_track = -1;
        !          4168:        ignore_ws (inptr);
        !          4169:        if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1))
        !          4170:                goto end;
        !          4171:        for (i = 0; i < _tcslen(parm); i++) {
        !          4172:                if (parm[i] == 'R')
        !          4173:                        disk_debug_mode |= DISK_DEBUG_DMA_READ;
        !          4174:                if (parm[i] == 'W')
        !          4175:                        disk_debug_mode |= DISK_DEBUG_DMA_WRITE;
        !          4176:                if (parm[i] == 'P')
        !          4177:                        disk_debug_mode |= DISK_DEBUG_PIO;
        !          4178:        }
        !          4179:        if (more_params(inptr))
        !          4180:                disk_debug_track = readint (inptr);
        !          4181:        if (disk_debug_track < 0 || disk_debug_track > 2 * 83)
        !          4182:                disk_debug_track = -1;
        !          4183:        if (disk_debug_logging == 0)
        !          4184:                disk_debug_logging = 1;
        !          4185: end:
        !          4186:        console_out_f (_T("Disk breakpoint mode %c%c%c track %d\n"),
        !          4187:                disk_debug_mode & DISK_DEBUG_DMA_READ ? 'R' : '-',
        !          4188:                disk_debug_mode & DISK_DEBUG_DMA_WRITE ? 'W' : '-',
        !          4189:                disk_debug_mode & DISK_DEBUG_PIO ? 'P' : '-',
        !          4190:                disk_debug_track);
        !          4191: }
        !          4192: 
        !          4193: static void find_ea (TCHAR **inptr)
        !          4194: {
        !          4195:        uae_u32 ea, sea, dea;
        !          4196:        uaecptr addr, end;
        !          4197:        int hits = 0;
        !          4198: 
        !          4199:        addr = 0;
        !          4200:        end = lastaddr ();
        !          4201:        ea = readhex (inptr);
        !          4202:        if (more_params(inptr)) {
        !          4203:                addr = readhex (inptr);
        !          4204:                if (more_params(inptr))
        !          4205:                        end = readhex (inptr);
        !          4206:        }
        !          4207:        console_out_f (_T("Searching from %08X to %08X\n"), addr, end);
        !          4208:        while((addr = nextaddr (addr, end, &end)) != 0xffffffff) {
        !          4209:                if ((addr & 1) == 0 && addr + 6 <= end) {
        !          4210:                        sea = 0xffffffff;
        !          4211:                        dea = 0xffffffff;
        !          4212:                        m68k_disasm_ea (addr, NULL, 1, &sea, &dea);
        !          4213:                        if (ea == sea || ea == dea) {
        !          4214:                                m68k_disasm (addr, NULL, 1);
        !          4215:                                hits++;
        !          4216:                                if (hits > 100) {
        !          4217:                                        console_out_f (_T("Too many hits. End addr = %08X\n"), addr);
        !          4218:                                        break;
        !          4219:                                }
        !          4220:                        }
        !          4221:                        if  (iscancel (65536)) {
        !          4222:                                console_out_f (_T("Aborted at %08X\n"), addr);
        !          4223:                                break;
        !          4224:                        }
        !          4225:                }
        !          4226:        }
        !          4227: }
        !          4228: 
        !          4229: static void m68k_modify (TCHAR **inptr)
        !          4230: {
        !          4231:        uae_u32 v;
        !          4232:        TCHAR parm[10];
        !          4233:        TCHAR c1, c2;
        !          4234:        int i;
        !          4235: 
        !          4236:        if (!next_string (inptr, parm, sizeof (parm) / sizeof (TCHAR), 1))
        !          4237:                return;
        !          4238:        c1 = _totupper (parm[0]);
        !          4239:        c2 = 99;
        !          4240:        if (c1 == 'A' || c1 == 'D' || c1 == 'P') {
        !          4241:                c2 = _totupper (parm[1]);
        !          4242:                if (isdigit (c2))
        !          4243:                        c2 -= '0';
        !          4244:                else
        !          4245:                        c2 = 99;
        !          4246:        }
        !          4247:        v = readhex (inptr);
        !          4248:        if (c1 == 'A' && c2 < 8)
        !          4249:                regs.regs[8 + c2] = v;
        !          4250:        else if (c1 == 'D' && c2 < 8)
        !          4251:                regs.regs[c2] = v;
        !          4252:        else if (c1 == 'P' && c2 == 0)
        !          4253:                regs.irc = v;
        !          4254:        else if (c1 == 'P' && c2 == 1)
        !          4255:                regs.ir = v;
        !          4256:        else if (!_tcscmp (parm, _T("SR"))) {
        !          4257:                regs.sr = v;
        !          4258:                MakeFromSR ();
        !          4259:        } else if (!_tcscmp (parm, _T("CCR"))) {
        !          4260:                regs.sr = (regs.sr & ~31) | (v & 31);
        !          4261:                MakeFromSR ();
        !          4262:        } else if (!_tcscmp (parm, _T("USP"))) {
        !          4263:                regs.usp = v;
        !          4264:        } else if (!_tcscmp (parm, _T("ISP"))) {
        !          4265:                regs.isp = v;
        !          4266:        } else if (!_tcscmp (parm, _T("PC"))) {
        !          4267:                m68k_setpc (v);
        !          4268:                fill_prefetch ();
        !          4269:        } else {
        !          4270:                for (i = 0; m2cregs[i].regname; i++) {
        !          4271:                        if (!_tcscmp (parm, m2cregs[i].regname))
        !          4272:                                val_move2c2 (m2cregs[i].regno, v);
        !          4273:                }
        !          4274:        }
        !          4275: }
        !          4276: 
        !          4277: static void ppc_disasm(uaecptr addr, uaecptr *nextpc, int cnt)
        !          4278: {
        !          4279:        PPCD_CB disa;
        !          4280: 
        !          4281:        while(cnt-- > 0) {
        !          4282:                uae_u32 instr = get_long_debug(addr);
        !          4283:                disa.pc = addr;
        !          4284:                disa.instr = instr;
        !          4285:                PPCDisasm(&disa);
        !          4286:                TCHAR *mnemo = au(disa.mnemonic);
        !          4287:                TCHAR *ops = au(disa.operands);
        !          4288:                console_out_f(_T("%08X  %08X  %-12s%-30s\n"), addr, instr, mnemo, ops);
        !          4289:                xfree(ops);
        !          4290:                xfree(mnemo);
        !          4291:                addr += 4;
        !          4292:        }
        !          4293:        if (nextpc)
        !          4294:                *nextpc = addr;
        !          4295: }
        !          4296: 
        !          4297: static uaecptr nxdis, nxmem;
        !          4298: static bool ppcmode;
        !          4299: 
        !          4300: static BOOL debug_line (TCHAR *input)
        !          4301: {
        !          4302:        TCHAR cmd, *inptr;
        !          4303:        uaecptr addr;
        !          4304: 
        !          4305:        inptr = input;
        !          4306:        cmd = next_char (&inptr);
        !          4307: 
        !          4308:        switch (cmd)
        !          4309:        {
        !          4310:                case 'c': dumpcia (); dumpdisk (); dumpcustom (); break;
        !          4311:                case 'i':
        !          4312:                {
        !          4313:                        if (*inptr == 'l') {
        !          4314:                                next_char (&inptr);
        !          4315:                                if (more_params (&inptr)) {
        !          4316:                                        debug_illegal_mask = readhex (&inptr);
        !          4317:                                } else {
        !          4318:                                        debug_illegal_mask = debug_illegal ? 0 : -1;
        !          4319:                                        debug_illegal_mask &= ~((uae_u64)255 << 24); // mask interrupts
        !          4320:                                }
        !          4321:                                console_out_f (_T("Exception breakpoint mask: %0I64X\n"), debug_illegal_mask);
        !          4322:                                debug_illegal = debug_illegal_mask ? 1 : 0;
        !          4323:                        } else {
        !          4324:                                addr = 0xffffffff;
        !          4325:                                if (more_params (&inptr))
        !          4326:                                        addr = readhex (&inptr);
        !          4327:                                dump_vectors (addr);
        !          4328:                        }
        !          4329:                        break;
        !          4330:                }
        !          4331:                case 'e': dump_custom_regs (tolower(*inptr) == 'a'); break;
        !          4332:                case 'r':
        !          4333:                        {
        !          4334:                                if (*inptr == 'c')
        !          4335:                                        m68k_dumpcache ();
        !          4336:                                else if (more_params(&inptr))
        !          4337:                                        m68k_modify (&inptr);
        !          4338:                                else
        !          4339:                                        m68k_dumpstate (&nextpc);
        !          4340:                        }
        !          4341:                        break;
        !          4342:                case 'D': deepcheatsearch (&inptr); break;
        !          4343:                case 'C': cheatsearch (&inptr); break;
        !          4344:                case 'W': writeintomem (&inptr); break;
        !          4345:                case 'w': memwatch (&inptr); break;
        !          4346:                case 'S': savemem (&inptr); break;
        !          4347:                case 's':
        !          4348:                        if (*inptr == 'c') {
        !          4349:                                screenshot (1, 1);
        !          4350:                        } else if (*inptr == 'p') {
        !          4351:                                inptr++;
        !          4352:                                debug_sprite (&inptr);
        !          4353:                        } else if (*inptr == 'm') {
        !          4354:                                if (*(inptr + 1) == 'c') {
        !          4355:                                        next_char (&inptr);
        !          4356:                                        next_char (&inptr);
        !          4357:                                        if (!smc_table)
        !          4358:                                                smc_detect_init (&inptr);
        !          4359:                                        else
        !          4360:                                                smc_free ();
        !          4361:                                }
        !          4362:                        } else {
        !          4363:                                searchmem (&inptr);
        !          4364:                        }
        !          4365:                        break;
        !          4366:                case 'd':
        !          4367:                        {
        !          4368:                                if (*inptr == 'i') {
        !          4369:                                        next_char (&inptr);
        !          4370:                                        disk_debug (&inptr);
        !          4371:                                } else if (*inptr == 'j') {
        !          4372:                                        inptr++;
        !          4373:                                        inputdevice_logging = 1 | 2;
        !          4374:                                        if (more_params (&inptr))
        !          4375:                                                inputdevice_logging = readint (&inptr);
        !          4376:                                        console_out_f (_T("Input logging level %d\n"), inputdevice_logging);
        !          4377:                                } else if (*inptr == 'm') {
        !          4378:                                        memory_map_dump_2 (0);
        !          4379:                                } else if (*inptr == 't') {
        !          4380:                                        next_char (&inptr);
        !          4381:                                        debugtest_set (&inptr);
        !          4382: #ifdef _WIN32
        !          4383:                                } else if (*inptr == 'g') {
        !          4384:                                        extern void update_disassembly (uae_u32);
        !          4385:                                        next_char (&inptr);
        !          4386:                                        if (more_params (&inptr))
        !          4387:                                                update_disassembly (readhex (&inptr));
        !          4388: #endif
        !          4389:                                } else {
        !          4390:                                        uae_u32 daddr;
        !          4391:                                        int count;
        !          4392:                                        if (*inptr == 'p') {
        !          4393:                                                ppcmode = true;
        !          4394:                                                next_char(&inptr);
        !          4395:                                        } else if(*inptr == 'o') {
        !          4396:                                                ppcmode = false;
        !          4397:                                                next_char(&inptr);
        !          4398:                                        }
        !          4399:                                        if (more_params (&inptr))
        !          4400:                                                daddr = readhex (&inptr);
        !          4401:                                        else
        !          4402:                                                daddr = nxdis;
        !          4403:                                        if (more_params (&inptr))
        !          4404:                                                count = readhex (&inptr);
        !          4405:                                        else
        !          4406:                                                count = 10;
        !          4407:                                        if (ppcmode) {
        !          4408:                                                ppc_disasm(daddr, &nxdis, count);
        !          4409:                                        } else {
        !          4410:                                                m68k_disasm (daddr, &nxdis, count);
        !          4411:                                        }
        !          4412:                                }
        !          4413:                        }
        !          4414:                        break;
        !          4415:                case 'T':
        !          4416:                        if (inptr[0] == 't' || inptr[0] == 0)
        !          4417:                                show_exec_tasks ();
        !          4418:                        else
        !          4419:                                show_exec_lists (&inptr[0]);
        !          4420:                        break;
        !          4421:                case 't':
        !          4422:                        no_trace_exceptions = 0;
        !          4423:                        if (*inptr != 't') {
        !          4424:                                if (more_params (&inptr))
        !          4425:                                        skipaddr_doskip = readint (&inptr);
        !          4426:                                if (skipaddr_doskip <= 0 || skipaddr_doskip > 10000)
        !          4427:                                        skipaddr_doskip = 1;
        !          4428:                        } else {
        !          4429:                                no_trace_exceptions = 1;
        !          4430:                        }
        !          4431:                        set_special (SPCFLAG_BRK);
        !          4432:                        exception_debugging = 1;
        !          4433:                        return true;
        !          4434:                case 'z':
        !          4435:                        skipaddr_start = nextpc;
        !          4436:                        skipaddr_doskip = 1;
        !          4437:                        do_skip = 1;
        !          4438:                        exception_debugging = 1;
        !          4439:                        return true;
        !          4440: 
        !          4441:                case 'f':
        !          4442:                        if (inptr[0] == 'a') {
        !          4443:                                next_char (&inptr);
        !          4444:                                find_ea (&inptr);
        !          4445:                        } else if (inptr[0] == 'p') {
        !          4446:                                inptr++;
        !          4447:                                if (process_breakpoint (&inptr))
        !          4448:                                        return true;
        !          4449:                        } else if (inptr[0] == 'c' || inptr[0] == 's') {
        !          4450:                                if (cycle_breakpoint(&inptr))
        !          4451:                                        return true;
        !          4452:                        } else if (inptr[0] == 'e' && inptr[1] == 'n') {
        !          4453:                                break_if_enforcer = break_if_enforcer ? false : true;
        !          4454:                                console_out_f(_T("Break when enforcer hit: %s\n"), break_if_enforcer ? _T("enabled") : _T("disabled"));
        !          4455:                        } else {
        !          4456:                                if (instruction_breakpoint (&inptr))
        !          4457:                                        return true;
        !          4458:                        }
        !          4459:                        break;
        !          4460: 
        !          4461:                case 'q':
        !          4462:                        uae_quit();
        !          4463:                        deactivate_debugger();
        !          4464:                        return true;
        !          4465: 
        !          4466:                case 'g':
        !          4467:                        if (more_params (&inptr)) {
        !          4468:                                m68k_setpc (readhex (&inptr));
        !          4469:                                fill_prefetch ();
        !          4470:                        }
        !          4471:                        deactivate_debugger();
        !          4472:                        return true;
        !          4473: 
        !          4474:                case 'x':
        !          4475:                        if (_totupper(inptr[0]) == 'X') {
        !          4476:                                debugger_change(-1);
        !          4477:                        } else {
        !          4478:                                deactivate_debugger();
        !          4479:                                close_console();
        !          4480:                                return true;
        !          4481:                        }
        !          4482:                        break;
        !          4483: 
        !          4484:                case 'H':
        !          4485:                        {
        !          4486:                                int count, temp, badly, skip;
        !          4487:                                uae_u32 addr = 0;
        !          4488:                                uae_u32 oldpc = m68k_getpc ();
        !          4489:                                struct regstruct save_regs = regs;
        !          4490: 
        !          4491:                                badly = 0;
        !          4492:                                if (inptr[0] == 'H') {
        !          4493:                                        badly = 1;
        !          4494:                                        inptr++;
        !          4495:                                }
        !          4496: 
        !          4497:                                if (more_params(&inptr))
        !          4498:                                        count = readint (&inptr);
        !          4499:                                else
        !          4500:                                        count = 10;
        !          4501:                                if (count > 1000) {
        !          4502:                                        addr = count;
        !          4503:                                        count = MAX_HIST;
        !          4504:                                }
        !          4505:                                if (count < 0)
        !          4506:                                        break;
        !          4507:                                skip = count;
        !          4508:                                if (more_params (&inptr))
        !          4509:                                        skip = count - readint (&inptr);
        !          4510: 
        !          4511:                                temp = lasthist;
        !          4512:                                while (count-- > 0 && temp != firsthist) {
        !          4513:                                        if (temp == 0)
        !          4514:                                                temp = MAX_HIST - 1;
        !          4515:                                        else
        !          4516:                                                temp--;
        !          4517:                                }
        !          4518:                                while (temp != lasthist) {
        !          4519:                                        regs = history[temp];
        !          4520:                                        if (history[temp].pc == addr || addr == 0) {
        !          4521:                                                m68k_setpc (history[temp].pc);
        !          4522:                                                if (badly) {
        !          4523:                                                        m68k_dumpstate (NULL);
        !          4524:                                                } else {
        !          4525:                                                        console_out_f(_T("%2d "), history[temp].intmask ? history[temp].intmask : (history[temp].s ? -1 : 0));
        !          4526:                                                        m68k_disasm (history[temp].pc, NULL, 1);
        !          4527:                                                }
        !          4528:                                                if (addr && history[temp].pc == addr)
        !          4529:                                                        break;
        !          4530:                                        }
        !          4531:                                        if (skip-- < 0)
        !          4532:                                                break;
        !          4533:                                        if (++temp == MAX_HIST)
        !          4534:                                                temp = 0;
        !          4535:                                }
        !          4536:                                regs = save_regs;
        !          4537:                                m68k_setpc (oldpc);
        !          4538:                        }
        !          4539:                        break;
        !          4540:                case 'M':
        !          4541:                        if (more_params (&inptr)) {
        !          4542:                                switch (next_char (&inptr))
        !          4543:                                {
        !          4544:                                case 'a':
        !          4545:                                        if (more_params (&inptr))
        !          4546:                                                audio_channel_mask = readhex (&inptr);
        !          4547:                                        console_out_f (_T("Audio mask = %02X\n"), audio_channel_mask);
        !          4548:                                        break;
        !          4549:                                case 's':
        !          4550:                                        if (more_params (&inptr))
        !          4551:                                                debug_sprite_mask = readhex (&inptr);
        !          4552:                                        console_out_f (_T("Sprite mask: %02X\n"), debug_sprite_mask);
        !          4553:                                        break;
        !          4554:                                case 'b':
        !          4555:                                        if (more_params (&inptr)) {
        !          4556:                                                debug_bpl_mask = readhex (&inptr) & 0xff;
        !          4557:                                                if (more_params (&inptr))
        !          4558:                                                        debug_bpl_mask_one = readhex (&inptr) & 0xff;
        !          4559:                                                notice_screen_contents_lost ();
        !          4560:                                        }
        !          4561:                                        console_out_f (_T("Bitplane mask: %02X (%02X)\n"), debug_bpl_mask, debug_bpl_mask_one);
        !          4562:                                        break;
        !          4563:                                }
        !          4564:                        }
        !          4565:                        break;
        !          4566:                case 'm':
        !          4567:                        {
        !          4568:                                uae_u32 maddr;
        !          4569:                                int lines;
        !          4570: #ifdef _WIN32
        !          4571:                                if (*inptr == 'g') {
        !          4572:                                        extern void update_memdump (uae_u32);
        !          4573:                                        next_char (&inptr);
        !          4574:                                        if (more_params (&inptr))
        !          4575:                                                update_memdump (readhex (&inptr));
        !          4576:                                        break;
        !          4577:                                }
        !          4578: #endif
        !          4579:                                if (*inptr == 'm' && inptr[1] == 'u') {
        !          4580:                                        if (currprefs.mmu_model) {
        !          4581:                                                inptr += 2;
        !          4582:                                                if (more_params (&inptr))
        !          4583:                                                        debug_mmu_mode = readint (&inptr);
        !          4584:                                                else
        !          4585:                                                        debug_mmu_mode = 0;
        !          4586:                                                console_out_f (_T("MMU translation function code = %d\n"), debug_mmu_mode);
        !          4587:                                        }
        !          4588:                                        break;
        !          4589:                                }
        !          4590:                                if (more_params (&inptr)) {
        !          4591:                                        maddr = readhex (&inptr);
        !          4592:                                } else {
        !          4593:                                        maddr = nxmem;
        !          4594:                                }
        !          4595:                                if (more_params (&inptr))
        !          4596:                                        lines = readhex (&inptr);
        !          4597:                                else
        !          4598:                                        lines = 20;
        !          4599:                                dumpmem (maddr, &nxmem, lines);
        !          4600:                        }
        !          4601:                        break;
        !          4602:                case 'v':
        !          4603:                case 'V':
        !          4604:                        {
        !          4605:                                int v1 = vpos, v2 = 0;
        !          4606:                                if (more_params (&inptr))
        !          4607:                                        v1 = readint (&inptr);
        !          4608:                                if (more_params (&inptr))
        !          4609:                                        v2 = readint (&inptr);
        !          4610:                                if (debug_dma) {
        !          4611:                                        decode_dma_record (v2, v1, cmd == 'v', false);
        !          4612:                                } else {
        !          4613:                                        debug_dma = v1 < 0 ? -v1 : 1;
        !          4614:                                        console_out_f (_T("DMA debugger enabled, mode=%d.\n"), debug_dma);
        !          4615:                                }
        !          4616:                        }
        !          4617:                        break;
        !          4618:                case 'o':
        !          4619:                        {
        !          4620:                                if (copper_debugger (&inptr)) {
        !          4621:                                        debugger_active = 0;
        !          4622:                                        debugging = 0;
        !          4623:                                        return true;
        !          4624:                                }
        !          4625:                                break;
        !          4626:                        }
        !          4627:                case 'O':
        !          4628:                        break;
        !          4629:                case 'b':
        !          4630:                        if (staterecorder (&inptr))
        !          4631:                                return true;
        !          4632:                        break;
        !          4633:                case 'U':
        !          4634:                        if (currprefs.mmu_model && more_params (&inptr)) {
        !          4635:                                int i;
        !          4636:                                uaecptr addrl = readhex (&inptr);
        !          4637:                                uaecptr addrp;
        !          4638:                                console_out_f (_T("%08X translates to:\n"), addrl);
        !          4639:                                for (i = 0; i < 4; i++) {
        !          4640:                                        bool super = (i & 2) != 0;
        !          4641:                                        bool data = (i & 1) != 0;
        !          4642:                                        console_out_f (_T("S%dD%d="), super, data);
        !          4643:                                        TRY(prb) {
        !          4644:                                                if (currprefs.mmu_model >= 68040)
        !          4645:                                                        addrp = mmu_translate (addrl, super, data, false);
        !          4646:                                                else
        !          4647:                                                        addrp = mmu030_translate (addrl, super, data, false);
        !          4648:                                                console_out_f (_T("%08X"), addrp);
        !          4649:                                                TRY(prb2) {
        !          4650:                                                        if (currprefs.mmu_model >= 68040)
        !          4651:                                                                addrp = mmu_translate (addrl, super, data, true);
        !          4652:                                                        else
        !          4653:                                                                addrp = mmu030_translate (addrl, super, data, true);
        !          4654:                                                        console_out_f (_T(" RW"));
        !          4655:                                                } CATCH(prb2) {
        !          4656:                                                        console_out_f (_T(" RO"));
        !          4657:                                                } ENDTRY
        !          4658:                                        } CATCH(prb) {
        !          4659:                                                console_out_f (_T("***********"));
        !          4660:                                        } ENDTRY
        !          4661:                                        console_out_f (_T(" "));
        !          4662:                                }
        !          4663:                                console_out_f (_T("\n"));
        !          4664:                        }
        !          4665:                        break;
        !          4666:                case 'h':
        !          4667:                case '?':
        !          4668:                        if (more_params (&inptr))
        !          4669:                                converter (&inptr);
        !          4670:                        else
        !          4671:                                debug_help ();
        !          4672:                        break;
        !          4673:        }
        !          4674:        return false;
        !          4675: }
        !          4676: 
        !          4677: static void debug_1 (void)
        !          4678: {
        !          4679:        TCHAR input[MAX_LINEWIDTH];
        !          4680: 
        !          4681:        m68k_dumpstate (&nextpc);
        !          4682:        nxdis = nextpc; nxmem = 0;
        !          4683:        debugger_active = 1;
        !          4684: 
        !          4685:        for (;;) {
        !          4686:                int v;
        !          4687: 
        !          4688:                if (!debugger_active)
        !          4689:                        return;
        !          4690:                update_debug_info ();
        !          4691:                console_out (_T(">"));
        !          4692:                console_flush ();
        !          4693:                debug_linecounter = 0;
        !          4694:                v = console_get (input, MAX_LINEWIDTH);
        !          4695:                if (v < 0)
        !          4696:                        return;
        !          4697:                if (v == 0)
        !          4698:                        continue;
        !          4699:                if (debug_line (input))
        !          4700:                        return;
        !          4701:        }
        !          4702: }
        !          4703: 
        !          4704: static void addhistory (void)
        !          4705: {
        !          4706:        uae_u32 pc = m68k_getpc ();
        !          4707:        //    if (!notinrom())
        !          4708:        //      return;
        !          4709:        history[lasthist] = regs;
        !          4710:        history[lasthist].pc = m68k_getpc ();
        !          4711:        if (++lasthist == MAX_HIST)
        !          4712:                lasthist = 0;
        !          4713:        if (lasthist == firsthist) {
        !          4714:                if (++firsthist == MAX_HIST) firsthist = 0;
        !          4715:        }
        !          4716: }
        !          4717: 
        !          4718: static void debug_continue(void)
        !          4719: {
        !          4720:        set_special (SPCFLAG_BRK);
        !          4721: }
        !          4722: 
        !          4723: 
        !          4724: void debug (void)
        !          4725: {
        !          4726:        int i;
        !          4727:        int wasactive;
        !          4728: 
        !          4729:        if (savestate_state)
        !          4730:                return;
        !          4731: 
        !          4732:        bogusframe = 1;
        !          4733:        addhistory ();
        !          4734: 
        !          4735: #if 0
        !          4736:        if (do_skip && skipaddr_start == 0xC0DEDBAD) {
        !          4737:                if (trace_same_insn_count > 0) {
        !          4738:                        if (memcmp (trace_insn_copy, regs.pc_p, 10) == 0
        !          4739:                                && memcmp (trace_prev_regs.regs, regs.regs, sizeof regs.regs) == 0)
        !          4740:                        {
        !          4741:                                trace_same_insn_count++;
        !          4742:                                return;
        !          4743:                        }
        !          4744:                }
        !          4745:                if (trace_same_insn_count > 1)
        !          4746:                        fprintf (logfile, "[ repeated %d times ]\n", trace_same_insn_count);
        !          4747:                m68k_dumpstate (logfile, &nextpc);
        !          4748:                trace_same_insn_count = 1;
        !          4749:                memcpy (trace_insn_copy, regs.pc_p, 10);
        !          4750:                memcpy (&trace_prev_regs, &regs, sizeof regs);
        !          4751:        }
        !          4752: #endif
        !          4753: 
        !          4754:        if (!memwatch_triggered) {
        !          4755:                if (do_skip) {
        !          4756:                        uae_u32 pc;
        !          4757:                        uae_u16 opcode;
        !          4758:                        int bp = 0;
        !          4759: 
        !          4760:                        pc = munge24 (m68k_getpc ());
        !          4761:                        opcode = currprefs.cpu_model < 68020 && (currprefs.cpu_compatible || currprefs.cpu_cycle_exact) ? regs.ir : get_word_debug (pc);
        !          4762: 
        !          4763:                        for (i = 0; i < BREAKPOINT_TOTAL; i++) {
        !          4764:                                if (!bpnodes[i].enabled)
        !          4765:                                        continue;
        !          4766:                                if (bpnodes[i].addr == pc) {
        !          4767:                                        bp = 1;
        !          4768:                                        console_out_f (_T("Breakpoint at %08X\n"), pc);
        !          4769:                                        break;
        !          4770:                                }
        !          4771:                        }
        !          4772: 
        !          4773:                        if (skipaddr_doskip) {
        !          4774:                                if (skipaddr_start == pc)
        !          4775:                                        bp = 1;
        !          4776:                                if ((processptr || processname) && notinrom()) {
        !          4777:                                        uaecptr execbase = get_long_debug (4);
        !          4778:                                        uaecptr activetask = get_long_debug (execbase + 276);
        !          4779:                                        int process = get_byte_debug (activetask + 8) == 13 ? 1 : 0;
        !          4780:                                        char *name = (char*)get_real_address (get_long_debug (activetask + 10));
        !          4781:                                        if (process) {
        !          4782:                                                uaecptr cli = BPTR2APTR(get_long_debug (activetask + 172));
        !          4783:                                                uaecptr seglist = 0;
        !          4784: 
        !          4785:                                                uae_char *command = NULL;
        !          4786:                                                if (cli) {
        !          4787:                                                        if (processname)
        !          4788:                                                                command = (char*)get_real_address (BPTR2APTR(get_long_debug (cli + 16)));
        !          4789:                                                        seglist = BPTR2APTR(get_long_debug (cli + 60));
        !          4790:                                                } else {
        !          4791:                                                        seglist = BPTR2APTR(get_long_debug (activetask + 128));
        !          4792:                                                        seglist = BPTR2APTR(get_long_debug (seglist + 12));
        !          4793:                                                }
        !          4794:                                                if (activetask == processptr || (processname && (!stricmp (name, processname) || (command && command[0] && !strnicmp (command + 1, processname, command[0]) && processname[command[0]] == 0)))) {
        !          4795:                                                        while (seglist) {
        !          4796:                                                                uae_u32 size = get_long_debug (seglist - 4) - 4;
        !          4797:                                                                if (pc >= (seglist + 4) && pc < (seglist + size)) {
        !          4798:                                                                        bp = 1;
        !          4799:                                                                        break;
        !          4800:                                                                }
        !          4801:                                                                seglist = BPTR2APTR(get_long_debug (seglist));
        !          4802:                                                        }
        !          4803:                                                }
        !          4804:                                        }
        !          4805:                                } else if (skipins != 0xffffffff) {
        !          4806:                                        if (skipins == 0x10000) {
        !          4807:                                                if (opcode == 0x4e75 || opcode == 0x4e73 || opcode == 0x4e77)
        !          4808:                                                        bp = 1;
        !          4809:                                        } else if (opcode == skipins)
        !          4810:                                                bp = 1;
        !          4811:                                } else if (skipaddr_start == 0xffffffff && skipaddr_doskip < 0) {
        !          4812:                                        if ((pc < 0xe00000 || pc >= 0x1000000) && opcode != 0x4ef9)
        !          4813:                                                bp = 1;
        !          4814:                                } else if (skipaddr_start == 0xffffffff && skipaddr_doskip > 0) {
        !          4815:                                        bp = 1;
        !          4816:                                } else if (skipaddr_end != 0xffffffff) {
        !          4817:                                        if (pc >= skipaddr_start && pc < skipaddr_end)
        !          4818:                                                bp = 1;
        !          4819:                                }
        !          4820:                        }
        !          4821:                        if (sr_bpmask || sr_bpvalue) {
        !          4822:                                MakeSR ();
        !          4823:                                if ((regs.sr & sr_bpmask) == sr_bpvalue) {
        !          4824:                                        console_out (_T("SR breakpoint\n"));
        !          4825:                                        bp = 1;
        !          4826:                                }
        !          4827:                        }
        !          4828:                        if (!bp) {
        !          4829:                                debug_continue();
        !          4830:                                return;
        !          4831:                        }
        !          4832:                }
        !          4833:        } else {
        !          4834:                console_out_f (_T("Memwatch %d: break at %08X.%c %c%c%c %08X PC=%08X "), memwatch_triggered - 1, mwhit.addr,
        !          4835:                        mwhit.size == 1 ? 'B' : (mwhit.size == 2 ? 'W' : 'L'),
        !          4836:                        (mwhit.rwi & 1) ? 'R' : ' ', (mwhit.rwi & 2) ? 'W' : ' ', (mwhit.rwi & 4) ? 'I' : ' ',
        !          4837:                        mwhit.val, mwhit.pc);
        !          4838:                for (i = 0; memwatch_access_masks[i].mask; i++) {
        !          4839:                        if (mwhit.access_mask == memwatch_access_masks[i].mask)
        !          4840:                                console_out_f (_T("%s (%03x)\n"), memwatch_access_masks[i].name, mwhit.reg);
        !          4841:                }
        !          4842:                memwatch_triggered = 0;
        !          4843:        }
        !          4844:        if (skipaddr_doskip > 0) {
        !          4845:                skipaddr_doskip--;
        !          4846:                if (skipaddr_doskip > 0) {
        !          4847:                        debug_continue();
        !          4848:                        return;
        !          4849:                }
        !          4850:        }
        !          4851: 
        !          4852:        wasactive = ismouseactive ();
        !          4853: #ifdef WITH_PPC
        !          4854:        uae_ppc_pause(1);
        !          4855: #endif
        !          4856:        inputdevice_unacquire ();
        !          4857:        pause_sound ();
        !          4858:        setmouseactive (0);
        !          4859:        activate_console ();
        !          4860:        do_skip = 0;
        !          4861:        skipaddr_start = 0xffffffff;
        !          4862:        skipaddr_end = 0xffffffff;
        !          4863:        skipins = 0xffffffff;
        !          4864:        skipaddr_doskip = 0;
        !          4865:        exception_debugging = 0;
        !          4866:        debug_rewind = 0;
        !          4867:        processptr = 0;
        !          4868: #if 0
        !          4869:        if (!currprefs.statecapture) {
        !          4870:                changed_prefs.statecapture = currprefs.statecapture = 1;
        !          4871:                savestate_init ();
        !          4872:        }
        !          4873: #endif
        !          4874:        debug_1 ();
        !          4875:        if (!debug_rewind && !currprefs.cachesize
        !          4876: #ifdef FILESYS
        !          4877:                && nr_units () == 0
        !          4878: #endif
        !          4879:                ) {
        !          4880:                        savestate_capture (1);
        !          4881:        }
        !          4882:        for (i = 0; i < BREAKPOINT_TOTAL; i++) {
        !          4883:                if (bpnodes[i].enabled)
        !          4884:                        do_skip = 1;
        !          4885:        }
        !          4886:        if (sr_bpmask || sr_bpvalue)
        !          4887:                do_skip = 1;
        !          4888:        if (do_skip) {
        !          4889:                set_special (SPCFLAG_BRK);
        !          4890:                debugging = -1;
        !          4891:        }
        !          4892:        resume_sound ();
        !          4893:        inputdevice_acquire (TRUE);
        !          4894: #ifdef WITH_PPC
        !          4895:        uae_ppc_pause(0);
        !          4896: #endif
        !          4897:        setmouseactive (wasactive ? 2 : 0);
        !          4898: }
        !          4899: 
        !          4900: const TCHAR *debuginfo (int mode)
        !          4901: {
        !          4902:        static TCHAR txt[100];
        !          4903:        uae_u32 pc = M68K_GETPC;
        !          4904:        _stprintf (txt, _T("PC=%08X INS=%04X %04X %04X"),
        !          4905:                pc, get_word_debug (pc), get_word_debug (pc + 2), get_word_debug (pc + 4));
        !          4906:        return txt;
        !          4907: }
        !          4908: 
        !          4909: #endif /* WINUAE_FOR_HATARI */
        !          4910: 
        !          4911: void mmu_disasm (uaecptr pc, int lines)
        !          4912: {
        !          4913:        debug_mmu_mode = regs.s ? 6 : 2;
        !          4914:        m68k_dumpstate (0xffffffff, NULL);
        !          4915:        m68k_disasm (pc, NULL, lines);
        !          4916: }
        !          4917: 
        !          4918: static int mmu_logging;
        !          4919: 
        !          4920: #define MMU_PAGE_SHIFT 16
        !          4921: 
        !          4922: struct mmudata {
        !          4923:        uae_u32 flags;
        !          4924:        uae_u32 addr;
        !          4925:        uae_u32 len;
        !          4926:        uae_u32 remap;
        !          4927:        uae_u32 p_addr;
        !          4928: };
        !          4929: 
        !          4930: static struct mmudata *mmubanks;
        !          4931: static uae_u32 mmu_struct, mmu_callback, mmu_regs;
        !          4932: static uae_u32 mmu_fault_bank_addr, mmu_fault_addr;
        !          4933: static int mmu_fault_size, mmu_fault_rw;
        !          4934: static int mmu_slots;
        !          4935: static struct regstruct mmur;
        !          4936: 
        !          4937: struct mmunode {
        !          4938:        struct mmudata *mmubank;
        !          4939:        struct mmunode *next;
        !          4940: };
        !          4941: static struct mmunode **mmunl;
        !          4942: extern regstruct mmu_backup_regs;
        !          4943: 
        !          4944: #define MMU_READ_U (1 << 0)
        !          4945: #define MMU_WRITE_U (1 << 1)
        !          4946: #define MMU_READ_S (1 << 2)
        !          4947: #define MMU_WRITE_S (1 << 3)
        !          4948: #define MMU_READI_U (1 << 4)
        !          4949: #define MMU_READI_S (1 << 5)
        !          4950: 
        !          4951: #define MMU_MAP_READ_U (1 << 8)
        !          4952: #define MMU_MAP_WRITE_U (1 << 9)
        !          4953: #define MMU_MAP_READ_S (1 << 10)
        !          4954: #define MMU_MAP_WRITE_S (1 << 11)
        !          4955: #define MMU_MAP_READI_U (1 << 12)
        !          4956: #define MMU_MAP_READI_S (1 << 13)
        !          4957: 
        !          4958: void mmu_do_hit (void)
        !          4959: {
        !          4960:        int i;
        !          4961:        uaecptr p;
        !          4962:        uae_u32 pc;
        !          4963: 
        !          4964:        mmu_triggered = 0;
        !          4965:        pc = m68k_getpc ();
        !          4966:        p = mmu_regs + 18 * 4;
        !          4967:        put_long (p, pc);
        !          4968:        regs = mmu_backup_regs;
        !          4969:        regs.intmask = 7;
        !          4970:        regs.t0 = regs.t1 = 0;
        !          4971:        if (!regs.s) {
        !          4972:                regs.usp = m68k_areg (regs, 7);
        !          4973:                if (currprefs.cpu_model >= 68020)
        !          4974:                        m68k_areg (regs, 7) = regs.m ? regs.msp : regs.isp;
        !          4975:                else
        !          4976:                        m68k_areg (regs, 7) = regs.isp;
        !          4977:                regs.s = 1;
        !          4978:        }
        !          4979:        MakeSR ();
        !          4980:        m68k_setpc (mmu_callback);
        !          4981:        fill_prefetch ();
        !          4982: 
        !          4983:        if (currprefs.cpu_model > 68000) {
        !          4984:                for (i = 0 ; i < 9; i++) {
        !          4985:                        m68k_areg (regs, 7) -= 4;
        !          4986:                        put_long (m68k_areg (regs, 7), 0);
        !          4987:                }
        !          4988:                m68k_areg (regs, 7) -= 4;
        !          4989:                put_long (m68k_areg (regs, 7), mmu_fault_addr);
        !          4990:                m68k_areg (regs, 7) -= 2;
        !          4991:                put_word (m68k_areg (regs, 7), 0); /* WB1S */
        !          4992:                m68k_areg (regs, 7) -= 2;
        !          4993:                put_word (m68k_areg (regs, 7), 0); /* WB2S */
        !          4994:                m68k_areg (regs, 7) -= 2;
        !          4995:                put_word (m68k_areg (regs, 7), 0); /* WB3S */
        !          4996:                m68k_areg (regs, 7) -= 2;
        !          4997:                put_word (m68k_areg (regs, 7),
        !          4998:                        (mmu_fault_rw ? 0 : 0x100) | (mmu_fault_size << 5)); /* SSW */
        !          4999:                m68k_areg (regs, 7) -= 4;
        !          5000:                put_long (m68k_areg (regs, 7), mmu_fault_bank_addr);
        !          5001:                m68k_areg (regs, 7) -= 2;
        !          5002:                put_word (m68k_areg (regs, 7), 0x7002);
        !          5003:        }
        !          5004:        m68k_areg (regs, 7) -= 4;
        !          5005:        put_long (m68k_areg (regs, 7), get_long_debug (p - 4));
        !          5006:        m68k_areg (regs, 7) -= 2;
        !          5007:        put_word (m68k_areg (regs, 7), mmur.sr);
        !          5008: #ifdef JIT
        !          5009:        set_special(SPCFLAG_END_COMPILE);
        !          5010: #endif
        !          5011: }
        !          5012: 
        !          5013: static void mmu_do_hit_pre (struct mmudata *md, uaecptr addr, int size, int rwi, uae_u32 v)
        !          5014: {
        !          5015:        uae_u32 p, pc;
        !          5016:        int i;
        !          5017: 
        !          5018:        mmur = regs;
        !          5019:        pc = m68k_getpc ();
        !          5020:        if (mmu_logging)
        !          5021:                console_out_f (_T("MMU: hit %08X SZ=%d RW=%d V=%08X PC=%08X\n"), addr, size, rwi, v, pc);
        !          5022: 
        !          5023:        p = mmu_regs;
        !          5024:        put_long (p, 0); p += 4;
        !          5025:        for (i = 0; i < 16; i++) {
        !          5026:                put_long (p, regs.regs[i]);
        !          5027:                p += 4;
        !          5028:        }
        !          5029:        put_long (p, pc); p += 4;
        !          5030:        put_long (p, 0); p += 4;
        !          5031:        put_long (p, regs.usp); p += 4;
        !          5032:        put_long (p, regs.isp); p += 4;
        !          5033:        put_long (p, regs.msp); p += 4;
        !          5034:        put_word (p, regs.sr); p += 2;
        !          5035:        put_word (p, (size << 1) | ((rwi & 2) ? 1 : 0)); /* size and rw */ p += 2;
        !          5036:        put_long (p, addr); /* fault address */ p += 4;
        !          5037:        put_long (p, md->p_addr); /* bank address */ p += 4;
        !          5038:        put_long (p, v); p += 4;
        !          5039:        mmu_fault_addr = addr;
        !          5040:        mmu_fault_bank_addr = md->p_addr;
        !          5041:        mmu_fault_size = size;
        !          5042:        mmu_fault_rw = rwi;
        !          5043:        mmu_triggered = 1;
        !          5044: }
        !          5045: 
        !          5046: static int mmu_hit (uaecptr addr, int size, int rwi, uae_u32 *v)
        !          5047: {
        !          5048:        int s, trig;
        !          5049:        uae_u32 flags;
        !          5050:        struct mmudata *md;
        !          5051:        struct mmunode *mn;
        !          5052: 
        !          5053:        if (mmu_triggered)
        !          5054:                return 1;
        !          5055: 
        !          5056:        mn = mmunl[addr >> MMU_PAGE_SHIFT];
        !          5057:        if (mn == NULL)
        !          5058:                return 0;
        !          5059: 
        !          5060:        s = regs.s;
        !          5061:        while (mn) {
        !          5062:                md = mn->mmubank;
        !          5063:                if (addr >= md->addr && addr < md->addr + md->len) {
        !          5064:                        flags = md->flags;
        !          5065:                        if (flags & (MMU_MAP_READ_U | MMU_MAP_WRITE_U | MMU_MAP_READ_S | MMU_MAP_WRITE_S | MMU_MAP_READI_U | MMU_MAP_READI_S)) {
        !          5066:                                trig = 0;
        !          5067:                                if (!s && (flags & MMU_MAP_READ_U) && (rwi & 1))
        !          5068:                                        trig = 1;
        !          5069:                                if (!s && (flags & MMU_MAP_WRITE_U) && (rwi & 2))
        !          5070:                                        trig = 1;
        !          5071:                                if (s && (flags & MMU_MAP_READ_S) && (rwi & 1))
        !          5072:                                        trig = 1;
        !          5073:                                if (s && (flags & MMU_MAP_WRITE_S) && (rwi & 2))
        !          5074:                                        trig = 1;
        !          5075:                                if (!s && (flags & MMU_MAP_READI_U) && (rwi & 4))
        !          5076:                                        trig = 1;
        !          5077:                                if (s && (flags & MMU_MAP_READI_S) && (rwi & 4))
        !          5078:                                        trig = 1;
        !          5079:                                if (trig) {
        !          5080:                                        uaecptr maddr = md->remap + (addr - md->addr);
        !          5081:                                        if (maddr == addr) /* infinite mmu hit loop? no thanks.. */
        !          5082:                                                return 1;
        !          5083:                                        if (mmu_logging)
        !          5084:                                                console_out_f (_T("MMU: remap %08X -> %08X SZ=%d RW=%d\n"), addr, maddr, size, rwi);
        !          5085:                                        if ((rwi & 2)) {
        !          5086:                                                switch (size)
        !          5087:                                                {
        !          5088:                                                case 4:
        !          5089:                                                        put_long (maddr, *v);
        !          5090:                                                        break;
        !          5091:                                                case 2:
        !          5092:                                                        put_word (maddr, *v);
        !          5093:                                                        break;
        !          5094:                                                case 1:
        !          5095:                                                        put_byte (maddr, *v);
        !          5096:                                                        break;
        !          5097:                                                }
        !          5098:                                        } else {
        !          5099:                                                switch (size)
        !          5100:                                                {
        !          5101:                                                case 4:
        !          5102:                                                        *v = get_long_debug (maddr);
        !          5103:                                                        break;
        !          5104:                                                case 2:
        !          5105:                                                        *v = get_word_debug (maddr);
        !          5106:                                                        break;
        !          5107:                                                case 1:
        !          5108:                                                        *v = get_byte_debug (maddr);
        !          5109:                                                        break;
        !          5110:                                                }
        !          5111:                                        }
        !          5112:                                        return 1;
        !          5113:                                }
        !          5114:                        }
        !          5115:                        if (flags & (MMU_READ_U | MMU_WRITE_U | MMU_READ_S | MMU_WRITE_S | MMU_READI_U | MMU_READI_S)) {
        !          5116:                                trig = 0;
        !          5117:                                if (!s && (flags & MMU_READ_U) && (rwi & 1))
        !          5118:                                        trig = 1;
        !          5119:                                if (!s && (flags & MMU_WRITE_U) && (rwi & 2))
        !          5120:                                        trig = 1;
        !          5121:                                if (s && (flags & MMU_READ_S) && (rwi & 1))
        !          5122:                                        trig = 1;
        !          5123:                                if (s && (flags & MMU_WRITE_S) && (rwi & 2))
        !          5124:                                        trig = 1;
        !          5125:                                if (!s && (flags & MMU_READI_U) && (rwi & 4))
        !          5126:                                        trig = 1;
        !          5127:                                if (s && (flags & MMU_READI_S) && (rwi & 4))
        !          5128:                                        trig = 1;
        !          5129:                                if (trig) {
        !          5130:                                        mmu_do_hit_pre (md, addr, size, rwi, *v);
        !          5131:                                        return 1;
        !          5132:                                }
        !          5133:                        }
        !          5134:                }
        !          5135:                mn = mn->next;
        !          5136:        }
        !          5137:        return 0;
        !          5138: }
        !          5139: 
        !          5140: static void mmu_free_node(struct mmunode *mn)
        !          5141: {
        !          5142:        if (!mn)
        !          5143:                return;
        !          5144:        mmu_free_node (mn->next);
        !          5145:        xfree (mn);
        !          5146: }
        !          5147: 
        !          5148: static void mmu_free(void)
        !          5149: {
        !          5150:        struct mmunode *mn;
        !          5151:        int i;
        !          5152: 
        !          5153:        for (i = 0; i < mmu_slots; i++) {
        !          5154:                mn = mmunl[i];
        !          5155:                mmu_free_node (mn);
        !          5156:        }
        !          5157:        xfree (mmunl);
        !          5158:        mmunl = NULL;
        !          5159:        xfree (mmubanks);
        !          5160:        mmubanks = NULL;
        !          5161: }
        !          5162: 
        !          5163: static int getmmubank(struct mmudata *snptr, uaecptr p)
        !          5164: {
        !          5165:        snptr->flags = get_long_debug (p);
        !          5166:        if (snptr->flags == 0xffffffff)
        !          5167:                return 1;
        !          5168:        snptr->addr = get_long_debug (p + 4);
        !          5169:        snptr->len = get_long_debug (p + 8);
        !          5170:        snptr->remap = get_long_debug (p + 12);
        !          5171:        snptr->p_addr = p;
        !          5172:        return 0;
        !          5173: }
        !          5174: 
        !          5175: int mmu_init(int mode, uaecptr parm, uaecptr parm2)
        !          5176: {
        !          5177:        uaecptr p, p2, banks;
        !          5178:        int size;
        !          5179:        struct mmudata *snptr;
        !          5180:        struct mmunode *mn;
        !          5181:        static int wasjit;
        !          5182: #ifdef JIT
        !          5183:        if (currprefs.cachesize) {
        !          5184:                wasjit = currprefs.cachesize;
        !          5185:                changed_prefs.cachesize = 0;
        !          5186:                console_out (_T("MMU: JIT disabled\n"));
        !          5187:                check_prefs_changed_comp ();
        !          5188:        }
        !          5189:        if (mode == 0) {
        !          5190:                if (mmu_enabled) {
        !          5191:                        mmu_free ();
        !          5192:                        deinitialize_memwatch ();
        !          5193:                        console_out (_T("MMU: disabled\n"));
        !          5194:                        changed_prefs.cachesize = wasjit;
        !          5195:                }
        !          5196:                mmu_logging = 0;
        !          5197:                return 1;
        !          5198:        }
        !          5199: #endif
        !          5200: 
        !          5201:        if (mode == 1) {
        !          5202:                if (!mmu_enabled)
        !          5203:                        return 0xffffffff;
        !          5204:                return mmu_struct;
        !          5205:        }
        !          5206: 
        !          5207:        p = parm;
        !          5208:        mmu_struct = p;
        !          5209:        if (get_long_debug (p) != 1) {
        !          5210:                console_out_f (_T("MMU: version mismatch %d <> %d\n"), get_long_debug (p), 1);
        !          5211:                return 0;
        !          5212:        }
        !          5213:        p += 4;
        !          5214:        mmu_logging = get_long_debug (p) & 1;
        !          5215:        p += 4;
        !          5216:        mmu_callback = get_long_debug (p);
        !          5217:        p += 4;
        !          5218:        mmu_regs = get_long_debug (p);
        !          5219:        p += 4;
        !          5220: 
        !          5221:        if (mode == 3) {
        !          5222:                int off;
        !          5223:                uaecptr addr = get_long_debug (parm2 + 4);
        !          5224:                if (!mmu_enabled)
        !          5225:                        return 0;
        !          5226:                off = addr >> MMU_PAGE_SHIFT;
        !          5227:                mn = mmunl[off];
        !          5228:                while (mn) {
        !          5229:                        if (mn->mmubank->p_addr == parm2) {
        !          5230:                                getmmubank(mn->mmubank, parm2);
        !          5231:                                if (mmu_logging)
        !          5232:                                        console_out_f (_T("MMU: bank update %08X: %08X - %08X %08X\n"),
        !          5233:                                        mn->mmubank->flags, mn->mmubank->addr, mn->mmubank->len + mn->mmubank->addr,
        !          5234:                                        mn->mmubank->remap);
        !          5235:                        }
        !          5236:                        mn = mn->next;
        !          5237:                }
        !          5238:                return 1;
        !          5239:        }
        !          5240: 
        !          5241:        mmu_slots = 1 << ((currprefs.address_space_24 ? 24 : 32) - MMU_PAGE_SHIFT);
        !          5242:        mmunl = xcalloc (struct mmunode*, mmu_slots);
        !          5243:        size = 1;
        !          5244:        p2 = get_long_debug (p);
        !          5245:        while (get_long_debug (p2) != 0xffffffff) {
        !          5246:                p2 += 16;
        !          5247:                size++;
        !          5248:        }
        !          5249:        p = banks = get_long_debug (p);
        !          5250:        snptr = mmubanks = xmalloc (struct mmudata, size);
        !          5251:        for (;;) {
        !          5252:                int off;
        !          5253:                if (getmmubank(snptr, p))
        !          5254:                        break;
        !          5255:                p += 16;
        !          5256:                off = snptr->addr >> MMU_PAGE_SHIFT;
        !          5257:                if (mmunl[off] == NULL) {
        !          5258:                        mn = mmunl[off] = xcalloc (struct mmunode, 1);
        !          5259:                } else {
        !          5260:                        mn = mmunl[off];
        !          5261:                        while (mn->next)
        !          5262:                                mn = mn->next;
        !          5263:                        mn = mn->next = xcalloc (struct mmunode, 1);
        !          5264:                }
        !          5265:                mn->mmubank = snptr;
        !          5266:                snptr++;
        !          5267:        }
        !          5268: 
        !          5269:        initialize_memwatch (1);
        !          5270:        console_out_f (_T("MMU: enabled, %d banks, CB=%08X S=%08X BNK=%08X SF=%08X, %d*%d\n"),
        !          5271:                size - 1, mmu_callback, parm, banks, mmu_regs, mmu_slots, 1 << MMU_PAGE_SHIFT);
        !          5272:        set_special (SPCFLAG_BRK);
        !          5273:        return 1;
        !          5274: }
        !          5275: 
        !          5276: void debug_parser (const TCHAR *cmd, TCHAR *out, uae_u32 outsize)
        !          5277: {
        !          5278:        TCHAR empty[2] = { 0 };
        !          5279:        TCHAR *input = my_strdup (cmd);
        !          5280:        if (out == NULL && outsize == 0) {
        !          5281:                setconsolemode (empty, 1);
        !          5282:        } else if (out != NULL && outsize > 0) {
        !          5283:                out[0] = 0;
        !          5284:                setconsolemode (out, outsize);
        !          5285:        }
        !          5286:        debug_line (input);
        !          5287:        setconsolemode (NULL, 0);
        !          5288:        xfree (input);
        !          5289: }
        !          5290: 
        !          5291: #endif

unix.superglobalmegacorp.com

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