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

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;
1.1.1.2 ! root       71: 
1.1       root       72:        while (cycles >= CYCLE_UNIT) {
1.1.1.2 ! root       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);
1.1       root       79:                do_cycles (1 * CYCLE_UNIT);
                     80:                cycles -= CYCLE_UNIT;
                     81:        }
1.1.1.2 ! root       82: 
1.1       root       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.