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

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 */
1.1.1.6 ! root      126: //     fprintf ( stderr , "mem read ce %x %d %lu %lu\n" , addr , mode ,currcycle / cpucycleunit , currcycle );
        !           127:        if ( ( ( CyclesGlobalClockCounter + currcycle*2/CYCLE_UNIT ) & 3 ) == 2 )
        !           128:        {
        !           129: //             fprintf ( stderr , "mem wait read %x %d %lu %lu\n" , addr , mode , currcycle / cpucycleunit , currcycle );
        !           130:                x_do_cycles (2*cpucycleunit);
        !           131: //             fprintf ( stderr , "mem wait read after %x %d %lu %lu\n" , addr , mode , currcycle / cpucycleunit , currcycle );
        !           132:        }
1.1       root      133: 
                    134:        if (mode < 0)
1.1.1.5   root      135:                v = get_long (addr);
1.1       root      136:        else if (mode > 0)
1.1.1.5   root      137:                v = get_word (addr);
1.1       root      138:        else if (mode == 0)
1.1.1.5   root      139:                v = get_byte (addr);
                    140: 
1.1.1.6 ! root      141:        x_do_cycles_post (2*CYCLE_UNIT, v);
1.1.1.5   root      142: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      143: 
1.1.1.5   root      144:        return v;
1.1       root      145: }
                    146: 
                    147: uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode)
                    148: {
                    149:        uae_u32 v = 0;
1.1.1.5   root      150: #ifndef WINUAE_FOR_HATARI
1.1       root      151:        int hpos;
                    152: 
1.1.1.5   root      153:        sync_ce020 ();
1.1       root      154:        hpos = dma_cycle ();
1.1.1.5   root      155:        x_do_cycles_pre (CYCLE_UNIT);
1.1       root      156: 
                    157: #ifdef DEBUGGER
1.1.1.5   root      158:        struct dma_rec *dr = NULL;
1.1       root      159:        if (debug_dma) {
                    160:                int reg = 0x1000;
                    161:                if (mode < 0)
                    162:                        reg |= 4;
                    163:                else if (mode > 0)
                    164:                        reg |= 2;
                    165:                else
                    166:                        reg |= 1;
                    167:                dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
                    168:                checknasty (hpos, vpos);
                    169:        }
                    170: #endif
                    171:        if (mode < 0)
                    172:                v = get_long (addr);
                    173:        else if (mode > 0)
                    174:                v = get_word (addr);
                    175:        else if (mode == 0)
                    176:                v = get_byte (addr);
                    177: 
                    178: #ifdef DEBUGGER
                    179:        if (debug_dma)
                    180:                dr->dat = v;
                    181: #endif
1.1.1.5   root      182:        if (currprefs.cpu_model == 68020)
                    183:                x_do_cycles_post (CYCLE_UNIT / 2, v);
                    184: 
                    185:        regs.chipset_latch_rw = regs.chipset_latch_read = v;
                    186:        SETIFCHIP
                    187: 
                    188: #else                                          /* WINUAE_FOR_HATARI */
                    189:        sync_ce020 ();
                    190:        x_do_cycles_pre (CYCLE_UNIT);
                    191: 
                    192:        if (mode < 0)
                    193:                v = get_long (addr);
                    194:        else if (mode > 0)
                    195:                v = get_word (addr);
                    196:        else if (mode == 0)
                    197:                v = get_byte (addr);
                    198: 
                    199:        if (currprefs.cpu_model == 68020)
                    200:                x_do_cycles_post (CYCLE_UNIT / 2, v);
                    201: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      202: 
                    203:        return v;
                    204: }
                    205: 
1.1.1.5   root      206: void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
1.1       root      207: {
1.1.1.5   root      208: #ifndef WINUAE_FOR_HATARI
1.1       root      209:        int hpos;
                    210: 
                    211:        hpos = dma_cycle ();
1.1.1.5   root      212:        x_do_cycles_pre (CYCLE_UNIT);
1.1       root      213: 
                    214: #ifdef DEBUGGER
                    215:        if (debug_dma) {
1.1.1.5   root      216:                int reg = 0x1100;
1.1       root      217:                if (mode < 0)
                    218:                        reg |= 4;
                    219:                else if (mode > 0)
                    220:                        reg |= 2;
                    221:                else
                    222:                        reg |= 1;
1.1.1.5   root      223:                record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
1.1       root      224:                checknasty (hpos, vpos);
                    225:        }
                    226: #endif
1.1.1.5   root      227: 
1.1       root      228:        if (mode < 0)
1.1.1.5   root      229:                put_long (addr, v);
1.1       root      230:        else if (mode > 0)
1.1.1.5   root      231:                put_word (addr, v);
1.1       root      232:        else if (mode == 0)
1.1.1.5   root      233:                put_byte (addr, v);
1.1       root      234: 
1.1.1.5   root      235:        x_do_cycles_post (CYCLE_UNIT, v);
1.1       root      236: 
1.1.1.5   root      237:        regs.chipset_latch_rw = regs.chipset_latch_write = v;
                    238:        SETIFCHIP
                    239: 
                    240: #else                                          /* WINUAE_FOR_HATARI */
1.1.1.6 ! root      241: //     fprintf ( stderr , "mem write ce %x %d %lu %lu\n" , addr , mode ,currcycle / cpucycleunit , currcycle );
        !           242:        if ( ( ( CyclesGlobalClockCounter + currcycle*2/CYCLE_UNIT ) & 3 ) == 2 )
        !           243:        {
        !           244: //             fprintf ( stderr , "mem wait write %x %d %lu %lu\n" , addr , mode , currcycle / cpucycleunit , currcycle );
        !           245:                x_do_cycles (2*cpucycleunit);
        !           246: //             fprintf ( stderr , "mem wait write after %x %d %lu %lu\n" , addr , mode , currcycle / cpucycleunit , currcycle );
        !           247:        }
1.1.1.5   root      248: 
                    249:        if (mode < 0)
                    250:                put_long (addr, v);
                    251:        else if (mode > 0)
                    252:                put_word (addr, v);
                    253:        else if (mode == 0)
                    254:                put_byte (addr, v);
                    255: 
1.1.1.6 ! root      256:        x_do_cycles_post (2*CYCLE_UNIT, v);
1.1.1.5   root      257: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      258: }
                    259: 
1.1.1.5   root      260: void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
1.1       root      261: {
1.1.1.5   root      262: #ifndef WINUAE_FOR_HATARI
1.1       root      263:        int hpos;
                    264: 
1.1.1.5   root      265:        sync_ce020 ();
1.1       root      266:        hpos = dma_cycle ();
1.1.1.5   root      267:        x_do_cycles_pre (CYCLE_UNIT);
1.1       root      268: 
                    269: #ifdef DEBUGGER
                    270:        if (debug_dma) {
                    271:                int reg = 0x1100;
                    272:                if (mode < 0)
                    273:                        reg |= 4;
                    274:                else if (mode > 0)
                    275:                        reg |= 2;
                    276:                else
                    277:                        reg |= 1;
                    278:                record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
                    279:                checknasty (hpos, vpos);
                    280:        }
                    281: #endif
                    282: 
                    283:        if (mode < 0)
                    284:                put_long (addr, v);
                    285:        else if (mode > 0)
                    286:                put_word (addr, v);
                    287:        else if (mode == 0)
                    288:                put_byte (addr, v);
                    289: 
1.1.1.5   root      290:        if (currprefs.cpu_model == 68020)
                    291:                x_do_cycles_post (CYCLE_UNIT / 2, v);
                    292: 
                    293:        regs.chipset_latch_rw = regs.chipset_latch_write = v;
                    294:        SETIFCHIP
                    295: 
                    296: #else                                          /* WINUAE_FOR_HATARI */
                    297:        sync_ce020 ();
                    298:        x_do_cycles_pre (CYCLE_UNIT);
                    299: 
                    300:        if (mode < 0)
                    301:                put_long (addr, v);
                    302:        else if (mode > 0)
                    303:                put_word (addr, v);
                    304:        else if (mode == 0)
                    305:                put_byte (addr, v);
                    306: 
                    307:        if (currprefs.cpu_model == 68020)
                    308:                x_do_cycles_post (CYCLE_UNIT / 2, v);
                    309: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      310: }
                    311: 
1.1.1.5   root      312: void do_cycles_ce (unsigned long cycles)
1.1       root      313: {
1.1.1.5   root      314:        cycles += extra_cycle;
                    315:        while (cycles >= CYCLE_UNIT) {
                    316: #ifndef WINUAE_FOR_HATARI
                    317:                int hpos = current_hpos () + 1;
                    318:                decide_line (hpos);
                    319:                sync_copper (hpos);
                    320:                decide_fetch_ce (hpos);
                    321:                if (bltstate != BLT_done)
                    322:                        decide_blitter (hpos);
                    323: #endif                                         /* WINUAE_FOR_HATARI */
                    324:                do_cycles (1 * CYCLE_UNIT);
                    325:                cycles -= CYCLE_UNIT;
                    326:        }
                    327:        extra_cycle = cycles;
1.1       root      328: }
                    329: 
1.1.1.5   root      330: 
                    331: #ifndef WINUAE_FOR_HATARI
                    332: void do_cycles_ce020 (unsigned long cycles)
                    333: #else
                    334: /* [NP] : confusing, because same function name as in cpu_prefetch.h with do_cycles_ce020( int ), */
                    335: /* but here unsigned long parameter is already multiplied by cpucycleunit. */
                    336: /* Requires C++, so we rename to do_cycles_ce020_long() to keep C compatibility */
                    337: void do_cycles_ce020_long (unsigned long cycles)
                    338: #endif
1.1       root      339: {
1.1.1.5   root      340:        unsigned long c;
                    341: #ifndef WINUAE_FOR_HATARI
                    342:        int extra;
                    343: #else
                    344:        unsigned long extra;                    /* remove warning "comparison between signed/unsigned" */
                    345: #endif
1.1       root      346: 
1.1.1.5   root      347:        if (!cycles)
1.1       root      348:                return;
1.1.1.5   root      349:        c = get_cycles ();
                    350:        extra = c & (CYCLE_UNIT - 1);
                    351: //fprintf ( stderr , "do_cycles_ce020_long %d %d %d\n" , cycles , c , extra );
                    352:        if (extra) {
                    353:                extra = CYCLE_UNIT - extra;
                    354:                if (extra >= cycles) {
                    355:                        do_cycles (cycles);
                    356:                        return;
                    357:                }
                    358:                do_cycles (extra);
                    359:                cycles -= extra;
1.1       root      360:        }
1.1.1.5   root      361:        c = cycles;
                    362:        while (c) {
                    363: #ifndef WINUAE_FOR_HATARI
                    364:                int hpos = current_hpos () + 1;
                    365:                decide_line (hpos);
                    366:                sync_copper (hpos);
                    367:                decide_fetch_ce (hpos);
                    368:                if (bltstate != BLT_done)
                    369:                        decide_blitter (hpos);
                    370: #endif                                         /* WINUAE_FOR_HATARI */
                    371:                if (c < CYCLE_UNIT)
                    372:                        break;
                    373:                do_cycles (1 * CYCLE_UNIT);
                    374:                c -= CYCLE_UNIT;
                    375:        }
                    376:        if (c > 0)
                    377:                do_cycles (c);
                    378: }
1.1       root      379: 
1.1.1.5   root      380: int is_cycle_ce (void)
                    381: {
                    382: #ifndef WINUAE_FOR_HATARI
                    383:        int hpos = current_hpos ();
                    384:        return cycle_line[hpos] & CYCLE_MASK;
                    385: 
                    386: #else                                          /* WINUAE_FOR_HATARI */
                    387:        return 0;
                    388: #endif                                         /* WINUAE_FOR_HATARI */
                    389: }
                    390: 
                    391: #endif
                    392: 
                    393: 
                    394: 
                    395: void reset_frame_rate_hack (void)
                    396: {
                    397: #ifndef WINUAE_FOR_HATARI
                    398:         jitcount = 0;
                    399:         if (currprefs.m68k_speed >= 0)
                    400:                 return;
                    401: 
                    402:         rpt_did_reset = 1;
                    403:         is_syncline = 0;
                    404:         vsyncmintime = read_processor_time () + vsynctimebase;
                    405:         write_log (_T("Resetting frame rate hack\n"));
                    406: #endif                                         /* WINUAE_FOR_HATARI */
1.1       root      407: }
                    408: 
                    409: /* Code taken from main.cpp */
                    410: void fixup_cpu (struct uae_prefs *p)
                    411: {
                    412:        if (p->cpu_frequency == 1000000)
                    413:                p->cpu_frequency = 0;
1.1.1.5   root      414: 
                    415: #ifndef WINUAE_FOR_HATARI
                    416:        if (p->cpu_model >= 68030 && p->address_space_24) {
                    417:                error_log (_T("24-bit address space is not supported in 68030/040/060 configurations."));
                    418:                p->address_space_24 = 0;
                    419:        }
                    420: #else
                    421:         /* Hatari : don't force address_space_24=0 for 68030, as the Falcon has a 68030 EC with only 24 bits */
                    422: #endif
                    423:        if (p->cpu_model < 68020 && p->fpu_model && (p->cpu_compatible || p->cpu_cycle_exact)) {
                    424:                error_log (_T("FPU is not supported in 68000/010 configurations."));
                    425:                p->fpu_model = 0;
                    426:        }
                    427: 
1.1       root      428:        switch (p->cpu_model)
                    429:        {
                    430:        case 68000:
                    431:                p->address_space_24 = 1;
                    432:                break;
                    433:        case 68010:
                    434:                p->address_space_24 = 1;
                    435:                break;
                    436:        case 68020:
                    437:                break;
                    438:        case 68030:
                    439:                break;
                    440:        case 68040:
                    441:                if (p->fpu_model)
                    442:                        p->fpu_model = 68040;
                    443:                break;
                    444:        case 68060:
                    445:                if (p->fpu_model)
                    446:                        p->fpu_model = 68060;
                    447:                break;
                    448:        }
1.1.1.5   root      449: 
                    450:        if (p->cpu_model < 68020 && p->cachesize) {
                    451:                p->cachesize = 0;
                    452:                error_log (_T("JIT requires 68020 or better CPU."));
                    453:        }
                    454: 
                    455:        if (p->cpu_model >= 68040 && p->cachesize && p->cpu_compatible)
                    456:                p->cpu_compatible = false;
                    457: 
                    458:        if ((p->cpu_model < 68030 || p->cachesize) && p->mmu_model) {
                    459:                error_log (_T("MMU emulation requires 68030/040/060 and it is not JIT compatible."));
1.1       root      460:                p->mmu_model = 0;
1.1.1.5   root      461:        }
                    462: 
                    463:        if (p->cachesize && p->cpu_cycle_exact) {
                    464:                error_log (_T("JIT and cycle-exact can't be enabled simultaneously."));
                    465:                p->cachesize = 0;
                    466:        }
                    467:        if (p->cachesize && (p->fpu_no_unimplemented || p->int_no_unimplemented)) {
                    468:                error_log (_T("JIT is not compatible with unimplemented CPU/FPU instruction emulation."));
                    469:                p->fpu_no_unimplemented = p->int_no_unimplemented = false;
                    470:        }
                    471: 
                    472: #ifndef WINUAE_FOR_HATARI
                    473:        /* [NP] In Hatari, don't change m68k_speed in CE mode */
                    474:        if (p->cpu_cycle_exact && p->m68k_speed < 0)
                    475:                p->m68k_speed = 0;
                    476: #endif
                    477: 
                    478: #ifndef WINUAE_FOR_HATARI
                    479:        if (p->immediate_blits && p->blitter_cycle_exact) {
                    480:                error_log (_T("Cycle-exact and immediate blitter can't be enabled simultaneously.\n"));
                    481:                p->immediate_blits = false;
                    482:        }
                    483:        if (p->immediate_blits && p->waiting_blits) {
                    484:                error_log (_T("Immediate blitter and waiting blits can't be enabled simultaneously.\n"));
                    485:                p->waiting_blits = 0;
                    486:        }
                    487: #endif
                    488:        if (p->cpu_cycle_exact)
                    489:                p->cpu_compatible = true;
1.1       root      490: }
                    491: 
1.1.1.5   root      492: 
                    493: void custom_reset (bool hardreset, bool keyboardreset)
                    494: {
                    495: }
                    496: 
                    497: 
                    498: // TODO NP remove ?
                    499: #ifndef WINUAE_FOR_HATARI
1.1       root      500: /* Code taken from main.cpp*/
                    501: void uae_reset (int hardreset)
                    502: {
                    503:        currprefs.quitstatefile[0] = changed_prefs.quitstatefile[0] = 0;
                    504: 
                    505:        if (quit_program == 0) {
                    506:                quit_program = -2;
                    507:                if (hardreset)
                    508:                        quit_program = -3;
                    509:        }
                    510: 
                    511: }
                    512: #endif
1.1.1.5   root      513: 
1.1       root      514: 
                    515: /* Code taken from win32.cpp*/
                    516: void fpux_restore (int *v)
                    517: {
                    518: /*#ifndef _WIN64
                    519:        if (v)
                    520:                _controlfp (*v, _MCW_IC | _MCW_RC | _MCW_PC);
                    521:        else
                    522:                _controlfp (fpucontrol, _MCW_IC | _MCW_RC | _MCW_PC);
                    523: #endif
                    524: */
                    525: }
                    526: 
1.1.1.5   root      527: // TODO NP remove ?
1.1       root      528: /* Code taken from win32.cpp*/
                    529: void sleep_millis (int ms)
                    530: {
1.1.1.3   root      531: /* Laurent : may be coded later (DSL-Delay ?) */
1.1       root      532: }
                    533: 
                    534: 
                    535: /* Code just here to let newcpu.c link (original function is in inprec.cpp) */
                    536: int inprec_open(char *fname, int record)
                    537: {
                    538:        return 0;
                    539: }
                    540: 
1.1.1.5   root      541: // TODO NP remove ?
                    542: #ifndef WINUAE_FOR_HATARI
1.1       root      543: int current_hpos (void)
                    544: {
                    545:     return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
                    546: }
1.1.1.5   root      547: #endif
                    548: 
                    549: 

unix.superglobalmegacorp.com

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