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

1.1     ! root        1: /*
        !             2: * UAE - The Un*x Amiga Emulator
        !             3: *
        !             4: * Custom chip emulation
        !             5: *
        !             6: * Copyright 1995-2002 Bernd Schmidt
        !             7: * Copyright 1995 Alessandro Bissacco
        !             8: * Copyright 2000-2010 Toni Wilen
        !             9: */
        !            10: 
        !            11: #include "sysconfig.h"
        !            12: #include "sysdeps.h"
        !            13: #include "compat.h"
        !            14: #include "hatari-glue.h"
        !            15: #include "options_cpu.h"
        !            16: #include "custom.h"
        !            17: #include "newcpu.h"
        !            18: #include "main.h"
        !            19: #include "cpummu.h"
        !            20: #include "cpu_prefetch.h"
        !            21: #include "m68000.h"
        !            22: #include "debugui.h"
        !            23: #include "debugcpu.h"
        !            24: 
        !            25: #define WRITE_LOG_BUF_SIZE 4096
        !            26: 
        !            27: extern struct regstruct mmu_backup_regs;
        !            28: static uae_u32 mmu_struct, mmu_callback, mmu_regs;
        !            29: static uae_u32 mmu_fault_bank_addr, mmu_fault_addr;
        !            30: static int mmu_fault_size, mmu_fault_rw;
        !            31: static int mmu_slots;
        !            32: static struct regstruct mmur;
        !            33: static int userdtsc = 0;
        !            34: int qpcdivisor = 0;
        !            35: volatile frame_time_t vsyncmintime;
        !            36: 
        !            37: void do_cycles_ce (long cycles);
        !            38: 
        !            39: unsigned long int event_cycles, nextevent, is_lastline, currcycle;
        !            40: uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode);
        !            41: void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v);
        !            42: void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v);
        !            43: uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode);
        !            44: frame_time_t read_processor_time_qpf (void);
        !            45: frame_time_t read_processor_time_rdtsc (void);
        !            46: 
        !            47: 
        !            48: typedef struct _LARGE_INTEGER
        !            49: {
        !            50:      union
        !            51:      {
        !            52:           struct
        !            53:           {
        !            54:                unsigned long LowPart;
        !            55:                long HighPart;
        !            56:           };
        !            57:           int64_t QuadPart;
        !            58:      };
        !            59: } LARGE_INTEGER, *PLARGE_INTEGER;
        !            60: 
        !            61: uae_u16 dmacon;
        !            62: uae_u8 cycle_line[256];
        !            63: 
        !            64: struct ev eventtab[ev_max];
        !            65: 
        !            66: void do_cycles_ce (long cycles)
        !            67: {
        !            68:        static int extra_cycle;
        !            69: 
        !            70:        cycles += extra_cycle;
        !            71: /*
        !            72:        while (cycles >= CYCLE_UNIT) {
        !            73:                int hpos = current_hpos () + 1;
        !            74:                sync_copper (hpos);
        !            75:                decide_line (hpos);
        !            76:                decide_fetch_ce (hpos);
        !            77:                if (bltstate != BLT_done)
        !            78:                        decide_blitter (hpos);
        !            79:                do_cycles (1 * CYCLE_UNIT);
        !            80:                cycles -= CYCLE_UNIT;
        !            81:        }
        !            82: */
        !            83:        extra_cycle = cycles;
        !            84: }
        !            85: 
        !            86: void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
        !            87: {
        !            88:        int hpos;
        !            89: 
        !            90: /*
        !            91:        hpos = dma_cycle ();
        !            92:        do_cycles_ce (CYCLE_UNIT);
        !            93: */
        !            94: #ifdef DEBUGGER
        !            95:        if (debug_dma) {
        !            96:                int reg = 0x1100;
        !            97:                if (mode < 0)
        !            98:                        reg |= 4;
        !            99:                else if (mode > 0)
        !           100:                        reg |= 2;
        !           101:                else
        !           102:                        reg |= 1;
        !           103:                record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
        !           104:                checknasty (hpos, vpos);
        !           105:        }
        !           106: #endif
        !           107: 
        !           108:        if (mode < 0)
        !           109:                put_long (addr, v);
        !           110:        else if (mode > 0)
        !           111:                put_word (addr, v);
        !           112:        else if (mode == 0)
        !           113:                put_byte (addr, v);
        !           114: 
        !           115:        regs.ce020memcycles -= CYCLE_UNIT;
        !           116: }
        !           117: 
        !           118: uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode)
        !           119: {
        !           120:        uae_u32 v = 0;
        !           121:        int hpos;
        !           122:        struct dma_rec *dr;
        !           123: 
        !           124: /*
        !           125:        hpos = dma_cycle ();
        !           126:        do_cycles_ce (CYCLE_UNIT);
        !           127: */
        !           128: 
        !           129: #ifdef DEBUGGER
        !           130:        if (debug_dma) {
        !           131:                int reg = 0x1000;
        !           132:                if (mode < 0)
        !           133:                        reg |= 4;
        !           134:                else if (mode > 0)
        !           135:                        reg |= 2;
        !           136:                else
        !           137:                        reg |= 1;
        !           138:                dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
        !           139:                checknasty (hpos, vpos);
        !           140:        }
        !           141: #endif
        !           142:        if (mode < 0)
        !           143:                v = get_long (addr);
        !           144:        else if (mode > 0)
        !           145:                v = get_word (addr);
        !           146:        else if (mode == 0)
        !           147:                v = get_byte (addr);
        !           148: 
        !           149: #ifdef DEBUGGER
        !           150:        if (debug_dma)
        !           151:                dr->dat = v;
        !           152: #endif
        !           153: 
        !           154:        regs.ce020memcycles -= CYCLE_UNIT;
        !           155:        return v;
        !           156: }
        !           157: 
        !           158: uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode)
        !           159: {
        !           160:        uae_u32 v = 0;
        !           161:        int hpos;
        !           162:        struct dma_rec *dr;
        !           163: 
        !           164: /*
        !           165:        hpos = dma_cycle ();
        !           166:        do_cycles_ce (CYCLE_UNIT);
        !           167: */
        !           168: 
        !           169: #ifdef DEBUGGER
        !           170:        if (debug_dma) {
        !           171:                int reg = 0x1000;
        !           172:                if (mode < 0)
        !           173:                        reg |= 4;
        !           174:                else if (mode > 0)
        !           175:                        reg |= 2;
        !           176:                else
        !           177:                        reg |= 1;
        !           178:                dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
        !           179:                checknasty (hpos, vpos);
        !           180:        }
        !           181: #endif
        !           182:        if (mode < 0)
        !           183:                v = get_long (addr);
        !           184:        else if (mode > 0)
        !           185:                v = get_word (addr);
        !           186:        else if (mode == 0)
        !           187:                v = get_byte (addr);
        !           188: 
        !           189: #ifdef DEBUGGER
        !           190:        if (debug_dma)
        !           191:                dr->dat = v;
        !           192: #endif
        !           193: 
        !           194:        do_cycles_ce (CYCLE_UNIT);
        !           195:        return v;
        !           196: }
        !           197: 
        !           198: void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
        !           199: {
        !           200:        int hpos;
        !           201: 
        !           202: /*
        !           203:        hpos = dma_cycle ();
        !           204:        do_cycles_ce (CYCLE_UNIT);
        !           205: */
        !           206: 
        !           207: #ifdef DEBUGGER
        !           208:        if (debug_dma) {
        !           209:                int reg = 0x1100;
        !           210:                if (mode < 0)
        !           211:                        reg |= 4;
        !           212:                else if (mode > 0)
        !           213:                        reg |= 2;
        !           214:                else
        !           215:                        reg |= 1;
        !           216:                record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
        !           217:                checknasty (hpos, vpos);
        !           218:        }
        !           219: #endif
        !           220: 
        !           221:        if (mode < 0)
        !           222:                put_long (addr, v);
        !           223:        else if (mode > 0)
        !           224:                put_word (addr, v);
        !           225:        else if (mode == 0)
        !           226:                put_byte (addr, v);
        !           227:        do_cycles_ce (CYCLE_UNIT);
        !           228: 
        !           229: }
        !           230: 
        !           231: int is_cycle_ce (void)
        !           232: {
        !           233:        int hpos = current_hpos ();
        !           234:        return cycle_line[hpos];
        !           235: }
        !           236: 
        !           237: void reset_frame_rate_hack (void)
        !           238: {
        !           239: /*     Laurent : should it be adapted or removed ?
        !           240:        if (currprefs.m68k_speed != -1)
        !           241:                return;
        !           242: 
        !           243:        if (! rpt_available) {
        !           244:                currprefs.m68k_speed = 0;
        !           245:                return;
        !           246:        }
        !           247: 
        !           248:        rpt_did_reset = 1;
        !           249:        is_lastline = 0;
        !           250:        vsyncmintime = read_processor_time () + vsynctime;
        !           251:        write_log ("Resetting frame rate hack\n");
        !           252: */
        !           253: }
        !           254: 
        !           255: /* Code taken from main.cpp */
        !           256: void fixup_cpu (struct uae_prefs *p)
        !           257: {
        !           258:        if (p->cpu_frequency == 1000000)
        !           259:                p->cpu_frequency = 0;
        !           260:        switch (p->cpu_model)
        !           261:        {
        !           262:        case 68000:
        !           263:                p->address_space_24 = 1;
        !           264:                if (p->cpu_compatible || p->cpu_cycle_exact)
        !           265:                        p->fpu_model = 0;
        !           266:                break;
        !           267:        case 68010:
        !           268:                p->address_space_24 = 1;
        !           269:                if (p->cpu_compatible || p->cpu_cycle_exact)
        !           270:                        p->fpu_model = 0;
        !           271:                break;
        !           272:        case 68020:
        !           273:                break;
        !           274:        case 68030:
        !           275:                p->address_space_24 = 0;
        !           276:                break;
        !           277:        case 68040:
        !           278:                p->address_space_24 = 0;
        !           279:                if (p->fpu_model)
        !           280:                        p->fpu_model = 68040;
        !           281:                break;
        !           282:        case 68060:
        !           283:                p->address_space_24 = 0;
        !           284:                if (p->fpu_model)
        !           285:                        p->fpu_model = 68060;
        !           286:                break;
        !           287:        }
        !           288:        if (p->cpu_model != 68040)
        !           289:                p->mmu_model = 0;
        !           290: }
        !           291: 
        !           292: /* Code taken from main.cpp*/
        !           293: void uae_reset (int hardreset)
        !           294: {
        !           295:        currprefs.quitstatefile[0] = changed_prefs.quitstatefile[0] = 0;
        !           296: 
        !           297:        if (quit_program == 0) {
        !           298:                quit_program = -2;
        !           299:                if (hardreset)
        !           300:                        quit_program = -3;
        !           301:        }
        !           302: 
        !           303: }
        !           304: 
        !           305: /* Code taken from debug.cpp*/
        !           306: void mmu_do_hit (void)
        !           307: {
        !           308:        int i;
        !           309:        uaecptr p;
        !           310:        uae_u32 pc;
        !           311: 
        !           312:        mmu_triggered = 0;
        !           313:        pc = m68k_getpc ();
        !           314:        p = mmu_regs + 18 * 4;
        !           315:        put_long (p, pc);
        !           316:        regs = mmu_backup_regs;
        !           317:        regs.intmask = 7;
        !           318:        regs.t0 = regs.t1 = 0;
        !           319:        if (!regs.s) {
        !           320:                regs.usp = m68k_areg (regs, 7);
        !           321:                if (currprefs.cpu_model >= 68020)
        !           322:                        m68k_areg (regs, 7) = regs.m ? regs.msp : regs.isp;
        !           323:                else
        !           324:                        m68k_areg (regs, 7) = regs.isp;
        !           325:                regs.s = 1;
        !           326:        }
        !           327:        MakeSR ();
        !           328:        m68k_setpc (mmu_callback);
        !           329:        fill_prefetch_slow ();
        !           330: 
        !           331:        if (currprefs.cpu_model > 68000) {
        !           332:                for (i = 0 ; i < 9; i++) {
        !           333:                        m68k_areg (regs, 7) -= 4;
        !           334:                        put_long (m68k_areg (regs, 7), 0);
        !           335:                }
        !           336:                m68k_areg (regs, 7) -= 4;
        !           337:                put_long (m68k_areg (regs, 7), mmu_fault_addr);
        !           338:                m68k_areg (regs, 7) -= 2;
        !           339:                put_word (m68k_areg (regs, 7), 0); /* WB1S */
        !           340:                m68k_areg (regs, 7) -= 2;
        !           341:                put_word (m68k_areg (regs, 7), 0); /* WB2S */
        !           342:                m68k_areg (regs, 7) -= 2;
        !           343:                put_word (m68k_areg (regs, 7), 0); /* WB3S */
        !           344:                m68k_areg (regs, 7) -= 2;
        !           345:                put_word (m68k_areg (regs, 7),
        !           346:                        (mmu_fault_rw ? 0 : 0x100) | (mmu_fault_size << 5)); /* SSW */
        !           347:                m68k_areg (regs, 7) -= 4;
        !           348:                put_long (m68k_areg (regs, 7), mmu_fault_bank_addr);
        !           349:                m68k_areg (regs, 7) -= 2;
        !           350:                put_word (m68k_areg (regs, 7), 0x7002);
        !           351:        }
        !           352:        m68k_areg (regs, 7) -= 4;
        !           353:        put_long (m68k_areg (regs, 7), get_long (p - 4));
        !           354:        m68k_areg (regs, 7) -= 2;
        !           355:        put_word (m68k_areg (regs, 7), mmur.sr);
        !           356: #ifdef JIT
        !           357:        set_special(SPCFLAG_END_COMPILE);
        !           358: #endif
        !           359: }
        !           360: 
        !           361: /* Code taken from win32.cpp*/
        !           362: void fpux_restore (int *v)
        !           363: {
        !           364: /*#ifndef _WIN64
        !           365:        if (v)
        !           366:                _controlfp (*v, _MCW_IC | _MCW_RC | _MCW_PC);
        !           367:        else
        !           368:                _controlfp (fpucontrol, _MCW_IC | _MCW_RC | _MCW_PC);
        !           369: #endif
        !           370: */
        !           371: }
        !           372: 
        !           373: /* Code taken from win32.cpp*/
        !           374: frame_time_t read_processor_time (void)
        !           375: {
        !           376: #if 0
        !           377:        static int cnt;
        !           378: 
        !           379:        cnt++;
        !           380:        if (cnt > 1000000) {
        !           381:                write_log(L"**************\n");
        !           382:                cnt = 0;
        !           383:        }
        !           384: #endif
        !           385:        if (userdtsc)
        !           386:                return read_processor_time_rdtsc ();
        !           387:        else
        !           388:                return read_processor_time_qpf ();
        !           389: }
        !           390: 
        !           391: /* Code taken from win32.cpp*/
        !           392: frame_time_t read_processor_time_qpf (void)
        !           393: {
        !           394: /* Laurent : may be coded later
        !           395:        LARGE_INTEGER counter;
        !           396:        QueryPerformanceCounter (&counter);
        !           397:        if (qpcdivisor == 0)
        !           398:                return (frame_time_t)(counter.LowPart);
        !           399:        return (frame_time_t)(counter.QuadPart >> qpcdivisor);
        !           400: */
        !           401: }
        !           402: 
        !           403: /* Code taken from win32.cpp*/
        !           404: frame_time_t read_processor_time_rdtsc (void)
        !           405: {
        !           406:        frame_time_t foo = 0;
        !           407: #if defined(X86_MSVC_ASSEMBLY)
        !           408:        frame_time_t bar;
        !           409:        __asm
        !           410:        {
        !           411:                rdtsc
        !           412:                        mov foo, eax
        !           413:                        mov bar, edx
        !           414:        }
        !           415:        /* very high speed CPU's RDTSC might overflow without this.. */
        !           416:        foo >>= 6;
        !           417:        foo |= bar << 26;
        !           418: #endif
        !           419:        return foo;
        !           420: }
        !           421: 
        !           422: /* Code taken from win32.cpp*/
        !           423: void sleep_millis (int ms)
        !           424: {
        !           425: /* Laurent : may be coded later (DSL-Delay ?)
        !           426:        unsigned int TimerEvent;
        !           427:        int start;
        !           428:        int cnt;
        !           429: 
        !           430:        start = read_processor_time ();
        !           431:        EnterCriticalSection (&cs_time);
        !           432:        cnt = timehandlecounter++;
        !           433:        if (timehandlecounter >= MAX_TIMEHANDLES)
        !           434:                timehandlecounter = 0;
        !           435:        LeaveCriticalSection (&cs_time);
        !           436:        TimerEvent = timeSetEvent (ms, 0, (LPTIMECALLBACK)timehandle[cnt], 0, TIME_ONESHOT | TIME_CALLBACK_EVENT_SET);
        !           437:        WaitForSingleObject (timehandle[cnt], ms);
        !           438:        ResetEvent (timehandle[cnt]);
        !           439:        timeKillEvent (TimerEvent);
        !           440:        idletime += read_processor_time () - start;
        !           441: */
        !           442: }
        !           443: 
        !           444: 
        !           445: /* Code just here to let newcpu.c link (original function is in inprec.cpp) */
        !           446: int inprec_open(char *fname, int record)
        !           447: {
        !           448:        return 0;
        !           449: }
        !           450: 
        !           451: int current_hpos (void)
        !           452: {
        !           453:     return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
        !           454: }

unix.superglobalmegacorp.com

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