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

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
1.1.1.5 ! root        8: * Copyright 2000-2014 Toni Wilen
1.1       root        9: */
                     10: 
                     11: #include "sysconfig.h"
                     12: #include "sysdeps.h"
                     13: #include "compat.h"
                     14: #include "hatari-glue.h"
                     15: #include "options_cpu.h"
1.1.1.5 ! root       16: #include "events.h"
1.1       root       17: #include "custom.h"
                     18: #include "newcpu.h"
                     19: #include "main.h"
                     20: #include "cpummu.h"
                     21: #include "m68000.h"
                     22: #include "debugui.h"
                     23: #include "debugcpu.h"
1.1.1.5 ! root       24: #ifdef WINUAE_FOR_HATARI
        !            25: #include "debug.h"
        !            26: #endif
1.1       root       27: 
                     28: #define WRITE_LOG_BUF_SIZE 4096
                     29: 
1.1.1.3   root       30: /* TODO: move custom.c stuff declarations to custom.h? */
                     31: 
1.1.1.5 ! root       32: #ifdef WINUAE_FOR_HATARI
        !            33: /* declared in newcpu.c */
1.1       root       34: extern struct regstruct mmu_backup_regs;
1.1.1.5 ! root       35: /* declared in events.h */
        !            36: unsigned long currcycle;
        !            37: /* declared in savestate.h */
        !            38: int savestate_state = 0;
        !            39: #endif
1.1.1.3   root       40: 
                     41: 
1.1.1.5 ! root       42: uae_u16 dmacon;
1.1       root       43: 
1.1.1.5 ! root       44: static int extra_cycle;
1.1       root       45: 
1.1.1.5 ! root       46: #if 0
1.1       root       47: typedef struct _LARGE_INTEGER
                     48: {
                     49:      union
                     50:      {
                     51:           struct
                     52:           {
                     53:                unsigned long LowPart;
                     54:                long HighPart;
                     55:           };
                     56:           int64_t QuadPart;
                     57:      };
                     58: } LARGE_INTEGER, *PLARGE_INTEGER;
1.1.1.5 ! root       59: #endif
1.1       root       60: 
                     61: 
1.1.1.5 ! root       62: #ifdef CPUEMU_13
1.1       root       63: 
1.1.1.5 ! root       64: uae_u8 cycle_line[256 + 1];
1.1.1.2   root       65: 
1.1.1.5 ! root       66: static void sync_ce020 (void)
        !            67: {
        !            68:        unsigned long c;
        !            69:        int extra;
1.1.1.2   root       70: 
1.1.1.5 ! root       71:        c = get_cycles ();
        !            72:        extra = c & (CYCLE_UNIT - 1);
        !            73:        if (extra) {
        !            74:                extra = CYCLE_UNIT - extra;
        !            75:                do_cycles (extra);
        !            76:        }
1.1       root       77: }
                     78: 
1.1.1.5 ! root       79: #ifndef WINUAE_FOR_HATARI
        !            80: #define SETIFCHIP \
        !            81:        if (addr < 0xd80000) \
        !            82:                last_custom_value1 = v;
        !            83: #endif         /* WINUAE_FOR_HATARI */
        !            84: 
        !            85: uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode)
1.1       root       86: {
1.1.1.5 ! root       87:        uae_u32 v = 0;
        !            88: #ifndef WINUAE_FOR_HATARI
1.1       root       89:        int hpos;
                     90: 
                     91:        hpos = dma_cycle ();
1.1.1.5 ! root       92:        x_do_cycles_pre (CYCLE_UNIT);
        !            93: 
1.1       root       94: #ifdef DEBUGGER
1.1.1.5 ! root       95:        struct dma_rec *dr = NULL;
1.1       root       96:        if (debug_dma) {
1.1.1.5 ! root       97:                int reg = 0x1000;
1.1       root       98:                if (mode < 0)
                     99:                        reg |= 4;
                    100:                else if (mode > 0)
                    101:                        reg |= 2;
                    102:                else
                    103:                        reg |= 1;
1.1.1.5 ! root      104:                dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
1.1       root      105:                checknasty (hpos, vpos);
                    106:        }
                    107: #endif
1.1.1.5 ! root      108:        if (mode < 0)
        !           109:                v = get_long (addr);
        !           110:        else if (mode > 0)
        !           111:                v = get_word (addr);
        !           112:        else if (mode == 0)
        !           113:                v = get_byte (addr);
        !           114: 
        !           115: #ifdef DEBUGGER
        !           116:        if (debug_dma)
        !           117:                dr->dat = v;
        !           118: #endif
        !           119: 
        !           120:        x_do_cycles_post (CYCLE_UNIT, v);
        !           121: 
        !           122:        regs.chipset_latch_rw = regs.chipset_latch_read = v;
        !           123:        SETIFCHIP
        !           124: 
        !           125: #else                                          /* WINUAE_FOR_HATARI */
        !           126:        x_do_cycles_pre (CYCLE_UNIT);
1.1       root      127: 
                    128:        if (mode < 0)
1.1.1.5 ! root      129:                v = get_long (addr);
1.1       root      130:        else if (mode > 0)
1.1.1.5 ! root      131:                v = get_word (addr);
1.1       root      132:        else if (mode == 0)
1.1.1.5 ! root      133:                v = get_byte (addr);
        !           134: 
        !           135:        x_do_cycles_post (CYCLE_UNIT, v);
        !           136: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      137: 
1.1.1.5 ! root      138:        return v;
1.1       root      139: }
                    140: 
                    141: uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode)
                    142: {
                    143:        uae_u32 v = 0;
1.1.1.5 ! root      144: #ifndef WINUAE_FOR_HATARI
1.1       root      145:        int hpos;
                    146: 
1.1.1.5 ! root      147:        sync_ce020 ();
1.1       root      148:        hpos = dma_cycle ();
1.1.1.5 ! root      149:        x_do_cycles_pre (CYCLE_UNIT);
1.1       root      150: 
                    151: #ifdef DEBUGGER
1.1.1.5 ! root      152:        struct dma_rec *dr = NULL;
1.1       root      153:        if (debug_dma) {
                    154:                int reg = 0x1000;
                    155:                if (mode < 0)
                    156:                        reg |= 4;
                    157:                else if (mode > 0)
                    158:                        reg |= 2;
                    159:                else
                    160:                        reg |= 1;
                    161:                dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
                    162:                checknasty (hpos, vpos);
                    163:        }
                    164: #endif
                    165:        if (mode < 0)
                    166:                v = get_long (addr);
                    167:        else if (mode > 0)
                    168:                v = get_word (addr);
                    169:        else if (mode == 0)
                    170:                v = get_byte (addr);
                    171: 
                    172: #ifdef DEBUGGER
                    173:        if (debug_dma)
                    174:                dr->dat = v;
                    175: #endif
1.1.1.5 ! root      176:        if (currprefs.cpu_model == 68020)
        !           177:                x_do_cycles_post (CYCLE_UNIT / 2, v);
        !           178: 
        !           179:        regs.chipset_latch_rw = regs.chipset_latch_read = v;
        !           180:        SETIFCHIP
        !           181: 
        !           182: #else                                          /* WINUAE_FOR_HATARI */
        !           183:        sync_ce020 ();
        !           184:        x_do_cycles_pre (CYCLE_UNIT);
        !           185: 
        !           186:        if (mode < 0)
        !           187:                v = get_long (addr);
        !           188:        else if (mode > 0)
        !           189:                v = get_word (addr);
        !           190:        else if (mode == 0)
        !           191:                v = get_byte (addr);
        !           192: 
        !           193:        if (currprefs.cpu_model == 68020)
        !           194:                x_do_cycles_post (CYCLE_UNIT / 2, v);
        !           195: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      196: 
                    197:        return v;
                    198: }
                    199: 
1.1.1.5 ! root      200: void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
1.1       root      201: {
1.1.1.5 ! root      202: #ifndef WINUAE_FOR_HATARI
1.1       root      203:        int hpos;
                    204: 
                    205:        hpos = dma_cycle ();
1.1.1.5 ! root      206:        x_do_cycles_pre (CYCLE_UNIT);
1.1       root      207: 
                    208: #ifdef DEBUGGER
                    209:        if (debug_dma) {
1.1.1.5 ! root      210:                int reg = 0x1100;
1.1       root      211:                if (mode < 0)
                    212:                        reg |= 4;
                    213:                else if (mode > 0)
                    214:                        reg |= 2;
                    215:                else
                    216:                        reg |= 1;
1.1.1.5 ! root      217:                record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
1.1       root      218:                checknasty (hpos, vpos);
                    219:        }
                    220: #endif
1.1.1.5 ! root      221: 
1.1       root      222:        if (mode < 0)
1.1.1.5 ! root      223:                put_long (addr, v);
1.1       root      224:        else if (mode > 0)
1.1.1.5 ! root      225:                put_word (addr, v);
1.1       root      226:        else if (mode == 0)
1.1.1.5 ! root      227:                put_byte (addr, v);
1.1       root      228: 
1.1.1.5 ! root      229:        x_do_cycles_post (CYCLE_UNIT, v);
1.1       root      230: 
1.1.1.5 ! root      231:        regs.chipset_latch_rw = regs.chipset_latch_write = v;
        !           232:        SETIFCHIP
        !           233: 
        !           234: #else                                          /* WINUAE_FOR_HATARI */
        !           235:        x_do_cycles_pre (CYCLE_UNIT);
        !           236: 
        !           237:        if (mode < 0)
        !           238:                put_long (addr, v);
        !           239:        else if (mode > 0)
        !           240:                put_word (addr, v);
        !           241:        else if (mode == 0)
        !           242:                put_byte (addr, v);
        !           243: 
        !           244:        x_do_cycles_post (CYCLE_UNIT, v);
        !           245: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      246: }
                    247: 
1.1.1.5 ! root      248: void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
1.1       root      249: {
1.1.1.5 ! root      250: #ifndef WINUAE_FOR_HATARI
1.1       root      251:        int hpos;
                    252: 
1.1.1.5 ! root      253:        sync_ce020 ();
1.1       root      254:        hpos = dma_cycle ();
1.1.1.5 ! root      255:        x_do_cycles_pre (CYCLE_UNIT);
1.1       root      256: 
                    257: #ifdef DEBUGGER
                    258:        if (debug_dma) {
                    259:                int reg = 0x1100;
                    260:                if (mode < 0)
                    261:                        reg |= 4;
                    262:                else if (mode > 0)
                    263:                        reg |= 2;
                    264:                else
                    265:                        reg |= 1;
                    266:                record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
                    267:                checknasty (hpos, vpos);
                    268:        }
                    269: #endif
                    270: 
                    271:        if (mode < 0)
                    272:                put_long (addr, v);
                    273:        else if (mode > 0)
                    274:                put_word (addr, v);
                    275:        else if (mode == 0)
                    276:                put_byte (addr, v);
                    277: 
1.1.1.5 ! root      278:        if (currprefs.cpu_model == 68020)
        !           279:                x_do_cycles_post (CYCLE_UNIT / 2, v);
        !           280: 
        !           281:        regs.chipset_latch_rw = regs.chipset_latch_write = v;
        !           282:        SETIFCHIP
        !           283: 
        !           284: #else                                          /* WINUAE_FOR_HATARI */
        !           285:        sync_ce020 ();
        !           286:        x_do_cycles_pre (CYCLE_UNIT);
        !           287: 
        !           288:        if (mode < 0)
        !           289:                put_long (addr, v);
        !           290:        else if (mode > 0)
        !           291:                put_word (addr, v);
        !           292:        else if (mode == 0)
        !           293:                put_byte (addr, v);
        !           294: 
        !           295:        if (currprefs.cpu_model == 68020)
        !           296:                x_do_cycles_post (CYCLE_UNIT / 2, v);
        !           297: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      298: }
                    299: 
1.1.1.5 ! root      300: void do_cycles_ce (unsigned long cycles)
1.1       root      301: {
1.1.1.5 ! root      302:        cycles += extra_cycle;
        !           303:        while (cycles >= CYCLE_UNIT) {
        !           304: #ifndef WINUAE_FOR_HATARI
        !           305:                int hpos = current_hpos () + 1;
        !           306:                decide_line (hpos);
        !           307:                sync_copper (hpos);
        !           308:                decide_fetch_ce (hpos);
        !           309:                if (bltstate != BLT_done)
        !           310:                        decide_blitter (hpos);
        !           311: #endif                                         /* WINUAE_FOR_HATARI */
        !           312:                do_cycles (1 * CYCLE_UNIT);
        !           313:                cycles -= CYCLE_UNIT;
        !           314:        }
        !           315:        extra_cycle = cycles;
1.1       root      316: }
                    317: 
1.1.1.5 ! root      318: 
        !           319: #ifndef WINUAE_FOR_HATARI
        !           320: void do_cycles_ce020 (unsigned long cycles)
        !           321: #else
        !           322: /* [NP] : confusing, because same function name as in cpu_prefetch.h with do_cycles_ce020( int ), */
        !           323: /* but here unsigned long parameter is already multiplied by cpucycleunit. */
        !           324: /* Requires C++, so we rename to do_cycles_ce020_long() to keep C compatibility */
        !           325: void do_cycles_ce020_long (unsigned long cycles)
        !           326: #endif
1.1       root      327: {
1.1.1.5 ! root      328:        unsigned long c;
        !           329: #ifndef WINUAE_FOR_HATARI
        !           330:        int extra;
        !           331: #else
        !           332:        unsigned long extra;                    /* remove warning "comparison between signed/unsigned" */
        !           333: #endif
1.1       root      334: 
1.1.1.5 ! root      335:        if (!cycles)
1.1       root      336:                return;
1.1.1.5 ! root      337:        c = get_cycles ();
        !           338:        extra = c & (CYCLE_UNIT - 1);
        !           339: //fprintf ( stderr , "do_cycles_ce020_long %d %d %d\n" , cycles , c , extra );
        !           340:        if (extra) {
        !           341:                extra = CYCLE_UNIT - extra;
        !           342:                if (extra >= cycles) {
        !           343:                        do_cycles (cycles);
        !           344:                        return;
        !           345:                }
        !           346:                do_cycles (extra);
        !           347:                cycles -= extra;
1.1       root      348:        }
1.1.1.5 ! root      349:        c = cycles;
        !           350:        while (c) {
        !           351: #ifndef WINUAE_FOR_HATARI
        !           352:                int hpos = current_hpos () + 1;
        !           353:                decide_line (hpos);
        !           354:                sync_copper (hpos);
        !           355:                decide_fetch_ce (hpos);
        !           356:                if (bltstate != BLT_done)
        !           357:                        decide_blitter (hpos);
        !           358: #endif                                         /* WINUAE_FOR_HATARI */
        !           359:                if (c < CYCLE_UNIT)
        !           360:                        break;
        !           361:                do_cycles (1 * CYCLE_UNIT);
        !           362:                c -= CYCLE_UNIT;
        !           363:        }
        !           364:        if (c > 0)
        !           365:                do_cycles (c);
        !           366: }
1.1       root      367: 
1.1.1.5 ! root      368: int is_cycle_ce (void)
        !           369: {
        !           370: #ifndef WINUAE_FOR_HATARI
        !           371:        int hpos = current_hpos ();
        !           372:        return cycle_line[hpos] & CYCLE_MASK;
        !           373: 
        !           374: #else                                          /* WINUAE_FOR_HATARI */
        !           375:        return 0;
        !           376: #endif                                         /* WINUAE_FOR_HATARI */
        !           377: }
        !           378: 
        !           379: #endif
        !           380: 
        !           381: 
        !           382: 
        !           383: void reset_frame_rate_hack (void)
        !           384: {
        !           385: #ifndef WINUAE_FOR_HATARI
        !           386:         jitcount = 0;
        !           387:         if (currprefs.m68k_speed >= 0)
        !           388:                 return;
        !           389: 
        !           390:         rpt_did_reset = 1;
        !           391:         is_syncline = 0;
        !           392:         vsyncmintime = read_processor_time () + vsynctimebase;
        !           393:         write_log (_T("Resetting frame rate hack\n"));
        !           394: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      395: }
                    396: 
                    397: /* Code taken from main.cpp */
                    398: void fixup_cpu (struct uae_prefs *p)
                    399: {
                    400:        if (p->cpu_frequency == 1000000)
                    401:                p->cpu_frequency = 0;
1.1.1.5 ! root      402: 
        !           403: #ifndef WINUAE_FOR_HATARI
        !           404:        if (p->cpu_model >= 68030 && p->address_space_24) {
        !           405:                error_log (_T("24-bit address space is not supported in 68030/040/060 configurations."));
        !           406:                p->address_space_24 = 0;
        !           407:        }
        !           408: #else
        !           409:         /* Hatari : don't force address_space_24=0 for 68030, as the Falcon has a 68030 EC with only 24 bits */
        !           410: #endif
        !           411:        if (p->cpu_model < 68020 && p->fpu_model && (p->cpu_compatible || p->cpu_cycle_exact)) {
        !           412:                error_log (_T("FPU is not supported in 68000/010 configurations."));
        !           413:                p->fpu_model = 0;
        !           414:        }
        !           415: 
1.1       root      416:        switch (p->cpu_model)
                    417:        {
                    418:        case 68000:
                    419:                p->address_space_24 = 1;
                    420:                break;
                    421:        case 68010:
                    422:                p->address_space_24 = 1;
                    423:                break;
                    424:        case 68020:
                    425:                break;
                    426:        case 68030:
                    427:                break;
                    428:        case 68040:
                    429:                if (p->fpu_model)
                    430:                        p->fpu_model = 68040;
                    431:                break;
                    432:        case 68060:
                    433:                if (p->fpu_model)
                    434:                        p->fpu_model = 68060;
                    435:                break;
                    436:        }
1.1.1.5 ! root      437: 
        !           438:        if (p->cpu_model < 68020 && p->cachesize) {
        !           439:                p->cachesize = 0;
        !           440:                error_log (_T("JIT requires 68020 or better CPU."));
        !           441:        }
        !           442: 
        !           443:        if (p->cpu_model >= 68040 && p->cachesize && p->cpu_compatible)
        !           444:                p->cpu_compatible = false;
        !           445: 
        !           446:        if (p->cpu_model >= 68040 && p->cpu_cycle_exact) {
        !           447:                p->cpu_cycle_exact = 0;
        !           448:                error_log (_T("68040/060 cycle-exact is not supported."));
        !           449:        }
        !           450: 
        !           451:        if ((p->cpu_model < 68030 || p->cachesize) && p->mmu_model) {
        !           452:                error_log (_T("MMU emulation requires 68030/040/060 and it is not JIT compatible."));
1.1       root      453:                p->mmu_model = 0;
1.1.1.5 ! root      454:        }
        !           455: 
        !           456:        if (p->cachesize && p->cpu_cycle_exact) {
        !           457:                error_log (_T("JIT and cycle-exact can't be enabled simultaneously."));
        !           458:                p->cachesize = 0;
        !           459:        }
        !           460:        if (p->cachesize && (p->fpu_no_unimplemented || p->int_no_unimplemented)) {
        !           461:                error_log (_T("JIT is not compatible with unimplemented CPU/FPU instruction emulation."));
        !           462:                p->fpu_no_unimplemented = p->int_no_unimplemented = false;
        !           463:        }
        !           464: 
        !           465: #ifndef WINUAE_FOR_HATARI
        !           466:        /* [NP] In Hatari, don't change m68k_speed in CE mode */
        !           467:        if (p->cpu_cycle_exact && p->m68k_speed < 0)
        !           468:                p->m68k_speed = 0;
        !           469: #endif
        !           470: 
        !           471: #ifndef WINUAE_FOR_HATARI
        !           472:        if (p->immediate_blits && p->blitter_cycle_exact) {
        !           473:                error_log (_T("Cycle-exact and immediate blitter can't be enabled simultaneously.\n"));
        !           474:                p->immediate_blits = false;
        !           475:        }
        !           476:        if (p->immediate_blits && p->waiting_blits) {
        !           477:                error_log (_T("Immediate blitter and waiting blits can't be enabled simultaneously.\n"));
        !           478:                p->waiting_blits = 0;
        !           479:        }
        !           480: #endif
        !           481:        if (p->cpu_cycle_exact)
        !           482:                p->cpu_compatible = true;
1.1       root      483: }
                    484: 
1.1.1.5 ! root      485: 
        !           486: void custom_reset (bool hardreset, bool keyboardreset)
        !           487: {
        !           488: }
        !           489: 
        !           490: 
        !           491: // TODO NP remove ?
        !           492: #ifndef WINUAE_FOR_HATARI
1.1       root      493: /* Code taken from main.cpp*/
                    494: void uae_reset (int hardreset)
                    495: {
                    496:        currprefs.quitstatefile[0] = changed_prefs.quitstatefile[0] = 0;
                    497: 
                    498:        if (quit_program == 0) {
                    499:                quit_program = -2;
                    500:                if (hardreset)
                    501:                        quit_program = -3;
                    502:        }
                    503: 
                    504: }
                    505: #endif
1.1.1.5 ! root      506: 
1.1       root      507: 
                    508: /* Code taken from win32.cpp*/
                    509: void fpux_restore (int *v)
                    510: {
                    511: /*#ifndef _WIN64
                    512:        if (v)
                    513:                _controlfp (*v, _MCW_IC | _MCW_RC | _MCW_PC);
                    514:        else
                    515:                _controlfp (fpucontrol, _MCW_IC | _MCW_RC | _MCW_PC);
                    516: #endif
                    517: */
                    518: }
                    519: 
1.1.1.5 ! root      520: // TODO NP remove ?
1.1       root      521: /* Code taken from win32.cpp*/
                    522: void sleep_millis (int ms)
                    523: {
1.1.1.3   root      524: /* Laurent : may be coded later (DSL-Delay ?) */
1.1       root      525: }
                    526: 
                    527: 
                    528: /* Code just here to let newcpu.c link (original function is in inprec.cpp) */
                    529: int inprec_open(char *fname, int record)
                    530: {
                    531:        return 0;
                    532: }
                    533: 
1.1.1.5 ! root      534: // TODO NP remove ?
        !           535: #ifndef WINUAE_FOR_HATARI
1.1       root      536: int current_hpos (void)
                    537: {
                    538:     return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
                    539: }
1.1.1.5 ! root      540: #endif
        !           541: 
        !           542: 

unix.superglobalmegacorp.com

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