|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.